i'm currently using a GXT3 grid to display data from a custom object EntityDAO.
This class contains 3 attributes: an id and two references to complex type objects
Let's call them
Long id;
UserInfo userInfo;
OutputInfo outputInfo;
I created an interface to explicit the desired display of these info:
interface EntityDAOProperties extends PropertyAccess<EntityDAO> {
ModelKeyProvider<EntityDAO> id();
#Path("userInfo.name")
ValueProvider<EntityDAO, String> step();
#Path("outputInfo.name")
ValueProvider<EntityDAO, String> outputInfo();
}
The display is perfectly fine. The matter is that i want to be able to add/edit rows to my grid.
To do so, I have a
GridRowEditing<EntityDAO> editing = createGridEditing(grid);
comprising a
SimpleComboBox<String> comboUser = new SimpleComboBox<String>(new LabelProvider<String>() {
#Override
public String getLabel(String item) {
return item;
}
});
for(...){
comboUser.add("entry " + i); // For instance
logger.info("entry : " +i); // For instance
i++;
}
comboUser.setEditable(false);
comboUser.setTriggerAction(TriggerAction.ALL);
When i double click on my line and make the GridRowEditing appear, the combo doesn't seem to have more than 1 row and the click on the expand arrow doesn't change anything to the matter.
I think you miss the part where you set the property editor for the combobox, here is the example code:
SimpleComboBox<Light> combo = new SimpleComboBox<Light>(new StringLabelProvider<Light>());
combo.setClearValueOnParseError(false);
combo.setPropertyEditor(new PropertyEditor<Light>() {
#Override
public Light parse(CharSequence text) throws ParseException {
return Light.parseString(text.toString());
}
#Override
public String render(Light object) {
return object == null ? Light.SUNNY.toString() : object.toString();
}
});
combo.setTriggerAction(TriggerAction.ALL);
combo.add(Light.SUNNY);
combo.add(Light.MOSTLYSUNNY);
combo.add(Light.SUNORSHADE);
combo.add(Light.MOSTLYSHADY);
combo.add(Light.SHADE);
// combo.setForceSelection(true);
editing.addEditor(cc2, new Converter<String, Light>() {
#Override
public String convertFieldValue(Light object) {
return object == null ? "" : object.toString();
}
#Override
public Light convertModelValue(String object) {
try {
return Light.parseString(object);
} catch (ParseException e) {
return null;
}
}
}, combo);
Hope this could help you.
I have DataGrid where one on of the columns contains images. I used this code to generate the column.
Column<Job, String> expandHideColumn = new Column<Job, String>(
imageCell) {
#Override
public String getValue(Job object) {
return null;
}
#Override
public void render(Context context, Job Object, SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<img src='images/expand.jpeg' style='cursor: pointer' />");
}
}
What I want is on clicking the image it has to change. For this I added a click handler on the ImageCell like this
ImageCell imageCell = new ImageCell() {
#Override
public Set<String> getConsumedEvents() {
Set<String> events = new HashSet<String>();
events.add("click");
return events;
}
};
In the onBrowserEvent method I wrote this
#Override
public void onBrowserEvent(Context context, Element element,
Job job, NativeEvent event) {
if (element.getFirstChildElement().isOrHasChild(
Element.as(event.getEventTarget()))) {
if (element.getFirstChildElement().getPropertyString("src")
.matches("(.*)expand.jpeg")) {
element.getFirstChildElement().setPropertyString("src",
"images/collapse.jpeg");
} else {
element.getFirstChildElement().setPropertyString("src",
"images/expand.jpeg");
}
}
}
I don't think this is a good approach to change images on click event. Is there a better solution?
You can use a column value for know the state of the column :
Column<Job, Boolean> expandHideColumn = new Column<Job, Boolean>(new ImageExpandCollapseCell()) {
#Override
public Boolean getValue(Job object) {
return object.isExpand(); //The object know the expand state ?
}
}
expandHideColumn.setValueUpdater(new FieldUpdater<Job, Boolean>() {
void update(int index, Job object, Boolean value) {
object.setExpand(value);
}
});
The ImageExpandCollapseCell look like this :
public class ImageExpandCollapseCell extends AbstractCell<Boolean> {
final String EXPAND = "images/expand.jpeg";
final String COLLAPSE = "images/collapse.jpeg";
interface Template extends SafeHtmlTemplates {
#Template("<div style=\"float:right\"><img src=\"" + url + "\"></div>")
SafeHtml img(String url);
}
private static Template template;
/**
* Construct a new ImageCell.
*/
public ImageCell() {
super("click"); //Replace your getConsumedEvents()
if (template == null) {
template = GWT.create(Template.class);
}
}
#Override
public void render(Context context, Boolean value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(template.img(UriUtils.fromSafeConstant(value ? EXPAND : COLLAPSE)));
}
}
#Override
public void onBrowserEvent(Context context, Element element,
Boolean value, NativeEvent event, ValueUpdater<Boolean> valueUpdater) {
valueUpdate.update(!value);
}
}
I improve the proposed version of user905374
It's not a good idea to instantiate new value in the render method.
The column render method call the Cell render method, you musn't replace it !
With the FieldUpdater, you can change the state of the image : expand or collapse and update the cell display (it will be rendered again).
I have this buttoncell
It's returning a string, but can i return an actual button instead of this string "ReList", to which I can add ClickHandler, which i can disable, hide etc.
(as i want to disable/hide this cell)
ButtonCell reListCell = new ButtonCell();
reListColumn = new Column<EmployerJobs, String>(reListCell) {
#Override
public String getValue(EmployerJobs object) {
return "ReList";
}
};
You have to add a FieldUpdater to the Column. See here for details.
ButtonCell reListCell = new ButtonCell();
reListColumn = new Column<EmployerJobs, String>(reListCell) {
#Override
public String getValue(EmployerJobs object) {
return "ReList";
}
};
reListColumn.setFieldUpdater(new FieldUpdater<EmployerJobs,String>() {
#Override
public void update(int index, EmployerJobs object, String value) {
Window.alert("You clicked " + object.someField());
}
});
I have a cell table in GWT with textcells and buttoncell ,Now i want to add a hyperlinkCell in my celltable , is this possible ?
TextCell jobStatusCell = new TextCell();
jobStatusColumn = new Column<EmployerJobs, String>(jobStatusCell) {
#Override
public String getValue(EmployerJobs object) {
// int status = object.getJobStatusId();
/*
* if(status ==1) { return ""; } else
*/
// return "post job";
return "view";
}
};
I want some thing like this
HyperlinkCell jobStatusCell = new HyperLinkCell();
Thanks
do you mean this HyperlinkCell?
If not, you can write a normal hyperlink (linkCell )and put it as the content of a cell.
Try using the following Cell implementation
Be sure that you provide cell's value as an array of 2 String objects like:
String[] value = new String[2];
value[HyperTextCell.LINK_INDEX] = "http://www.google.com";
value[HyperTextCell.TEXT_INDEX] = "Search on google";
public class HyperTextCell extends AbstractCell<String[]> {
interface Template extends SafeHtmlTemplates {
#Template("<a target=\"_blank\" href=\"{0}\">{1}</a>")
SafeHtml hyperText(SafeUri link, String text);
}
private static Template template;
public static final int LINK_INDEX = 0, URL_INDEX = 1;
/**
* Construct a new ImageCell.
*/
public HyperTextCell() {
if (template == null) {
template = GWT.create(Template.class);
}
}
#Override
public void render(Context context, String[] value, SafeHtmlBuilder sb) {
if (value != null) {
// The template will sanitize the URI.
sb.append(template.hyperText(UriUtils.fromString(value[LINK_INDEX]), value[URL_INDEX]));
}
}
}
I have tried this but didn't work
Column<ContactInfo, String> imageColumn = new Column<ContactInfo, String>(new ImageCell()) {
#Override
public String getValue(ContactInfo object) {
return "contact.jpg";
}
};
imageColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
#Override
public void update(int index, ContactInfo object, String value) {
Window.alert("You clicked " + object.firstName);
}
});
cellTable.addColumn(imageColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));
public class ButtonImageCell extends ButtonCell{
#Override
public void render(com.google.gwt.cell.client.Cell.Context context,
String value, SafeHtmlBuilder sb) {
SafeHtml html = SafeHtmlUtils.fromTrustedString(new Image(value).toString());
sb.append(html);
}
}
in use:
final Column<ReportDTOProxy, String> buttonImageCellTest = new Column<ProxyObject, String>(new ButtonImageCell()) {
#Override
public String getValue(ProxyObject row) {
//url to image
return row.getImageUrl();
}
};
You can extend ImageCell class and override 2 it's methods - getConsumedEvents and onBrowserEvent. Example:
private class MyImageCell extends ImageCell{
#Override
public Set<String> getConsumedEvents() {
Set<String> consumedEvents = new HashSet<String>();
consumedEvents.add("dblclick");
return consumedEvents;
}
#Override
public void onBrowserEvent(Context context, Element parent,
String value, NativeEvent event,
ValueUpdater<String> valueUpdater) {
switch (DOM.eventGetType((Event)event)) {
case Event.ONDBLCLICK:
// TODO
break;
default:
break;
}
}
}
I did something similar mixing a Button cell with the renderer from an ImageCell....
ButtonCell bc = new ButtonCell() {
#Override
public void render(Context context, SafeHtml data, SafeHtmlBuilder sb) {
if (data != null) {
ImageResource icon = Icons.BUNDLE.pieChart();
SafeHtml html = SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(icon).getHTML());
sb.append(html);
}
}
};
You get the idea. The only problem is that it does not display the "hand" icon when you hover over it.... likely it can be fixed by setting the CSS.
You can try this rather than using ButtonCell or ImageCell. This will work for sure. As I have implemented for my requirement. Let me know how does it goes..
ClickableTextCell imageCell = new ClickableTextCell() {
#Override
public void render(Context context, SafeHtml data, SafeHtmlBuilder sb) {
if (data != null) {
String imagePath = "icon.png";
sb.append(imagePath);
}
}
};
Column<ContactInfo, String> imageColumn = new Column<ContactInfo, String>(imageCell) {
#Override
public String getValue(ContactInfo object) {
return "";
}
};
imageColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {
#Override
public void update(int index, ContactInfo object, String value) {
Window.alert("You clicked " + object.firstName);
}
});
cellTable.addColumn(imageColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));
A good solution for this issue, if you use ActionCell that is able to handle clicking. The use of it is a bit complicatied, but for me it worked pretty well.
First you need to initialize ActionCell with a delegate, in the constructor, write new ActionCell.Delegate<your class>. In this override the method execute and in that write your code that handle the clicking event.
The other thing you need to do is building up a html from the image. The SafeHtmlUtils class gives you a very easy way to do that. It's fromTrustedString method helps you building up the html:
SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create ("Your image from a resource class").getHTML());
This way the SafeHtml field can be initalized and if you give the ActionCell's contructor the SafeHtml and the Delegate, that it will do the work for you.
In this example a button will be initialized with the image from the bundle file in it. You can make it without the button if you override the render method of the ActionCell and append the SafeHtmlBuilder in the method with the same SafeHtml variable as above.
My code looks like the following:
IdentityColumn<Type> imageCell = new IdentityColumn<Type>(new ActionCell<Type>("AnyString",
new ActionCell.Delegate<Type>() {
#Override
public void execute(final Type item) {
"your code"
}
}) {
#Override
public void render(Context context, Type value, SafeHtmlBuilder sb) {
if (value != null) {
SafeHtml html = SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(resource.image).getHTML());
sb.append(html);
}
}
});
You'd rather override the method in an another class but I didn't want to split them for this post. It worked for me very well, I hope it will help other's too.
I got all the above and added them in my app. Thanks to all. stackoverflow rocks!
ButtonCell bc = new ButtonCell() {
#Override
public void render(Context context, SafeHtml data, SafeHtmlBuilder sb) {
if (data != null) {
ImageResource icon = Connector.imageResources.minus();
Image image = new Image(icon);
//fix the mouse pointer
image.getElement().getStyle().setCursor(Cursor.POINTER);
//Do something with the DATA
image.setTitle("Delete " + data.asString());
SafeHtml html = SafeHtmlUtils.fromTrustedString(image.toString());
sb.append(html);
}
}
};
Column<InstanceProperty, String> imageColumn = new Column<InstanceProperty, String>(bc) {
#Override
public String getValue(InstanceProperty object) {
//return the DATA
return object.getKey();
}
};
imageColumn.setFieldUpdater(new FieldUpdater<InstanceProperty, String>() {
#Override
public void update(int index, InstanceProperty property,
String value) {
//you can also use the DATA to do something
InstancePropertiesTable.this.dataProvider.getList().remove(index);
}
});
addColumn(imageColumn, "");
This worked for me:
public class ButtonImageCell extends ButtonCell{
#Override
public void render(com.google.gwt.cell.client.Cell.Context context,
String renderedHtmlStr, SafeHtmlBuilder sb) {
sb.appendHtmlConstant(renderedHtmlStr);
}
}
In a class containing CellTable table:
TableResources resources = GWT.create(TableResources.class);
ImageResourceRenderer imageRenderer = new ImageResourceRenderer();
...
Column<MyRecord, String> buttonCol = new Column<MyRecord, String>(new ButtonImageCell()) {
#Override
public String getValue(MyRecord record) {
if(record.isOn())
return imageRenderer.render(resources.getOnImg()).asString();
else
return imageRenderer.render(resources.getOffImg()).asString();
}
};
buttonCol.setFieldUpdater(new FieldUpdater<MyRecord, String>() {
public void update(int index, MyRecordobject, String value) {
if (Window.confirm("Do stuff?")) {
//todo: stuff
}
}
});
...
table.addColumn(buttonCol, "");
Where the ImageResource comes from (resources):
public interface TableResources extends CellTable.Resources {
interface TableStyle extends CellTable.Style {
}
#Source("/images/on.png")
ImageResource getOnImg();
#Source("/images/off.png")
ImageResource getOffImg();
}
You need to sinkEvents() with appropriate bits.
Refer to answer of Question Adding ClickHandler to div which contains many other widget.