PDA

View Full Version : Widgets (FormFields) in TreeTable


flow
06-23-2008, 01:03 PM
- GXT RC1b
- Hosted Mode
- GWT 1.5 RC
AFAIK, this issues has only been adressed to Tables, but not to the TreeTable yet (if I am wrong, sorry...)

As the cells in a Table and a TreeTable are not yet editable I tried a workaround by setting widgets into the TableItems or TreeTableItems respectively. Using GWT widgets works fine inside the TreeTable, because their toString return the html-code. This method is called inside the TreeTable#getRenderedValue, if no CellRenderer is set.

protected String getRenderedValue(TreeTableItem item, int column, Object value) {
TreeTableColumn col = (TreeTableColumn) cm.getColumn(column);
if (col.getRenderer() != null) {
return col.getRenderer().render(item, col.getId(), value);
} else {
if (value != null) {
return value.toString();
}
return null;
}
}
But now I'd like to make use of the handy GXT-form-widgets. Of course, their toString-method does not return the html-tags. Neither can I make use of a custom CellRenderer, because I don't know, how to retrieve the rendered GXT-widgets as its string-representation.

To make things less complicated, I tried a simple example:

public void onModuleLoad() {
final Viewport viewport = new Viewport();
viewport.setLayout(new FillLayout());
final List<TreeTableColumn> columns = new ArrayList<TreeTableColumn>();
TreeTableColumn column = new TreeTableColumn("id", "id", 40f);
columns.add(column);

column = new TreeTableColumn("ComboBox", 150f);
columns.add(column);

final TreeTableColumnModel cm = new TreeTableColumnModel(columns);
final TreeTable treeTable = new TreeTable(cm);
final Object[] values = new Object[2];
values[0] = "23";
final ComboBox<BaseModelData> combobox = new ComboBox<BaseModelData>();
combobox.setDisplayField("display");
final ListStore<BaseModelData> store = new ListStore<BaseModelData>();
for (int i = 0; i < 3; i++) {
final BaseModelData dummy = new BaseModelData();
dummy.set("display", "Number " + i);
store.add(dummy);
}
combobox.setStore(store);
values[1] = combobox;
final TreeTableItem item = new TreeTableItem(values);
treeTable.getRootItem().add(item);
viewport.add(treeTable);
RootPanel.get().add(viewport);
}
But due to the issues mentioned above (toString, rendering), this won't show the expected ComboBox.

Any ideas, how I can apply GXT-widgets inside a TreeTable?

flow
06-27-2008, 10:52 AM
I tried this with GWT#s ListBox and this one is rendered. But herein the ChangeListener is not notified (I guess, the BrowserEvent is handled by the TreeTable and not further propagated).

jtmille3
07-01-2008, 03:42 PM
This is a bit hacky, but here's what I did.

TableColumn tc = new TableColumn("id", "Button", 60);
tc.setRenderer(new CellRenderer() {
public String render(Component item, String property, final Object value) {
DeferredCommand.addCommand(new Command() {
public void execute() {
Element placeHolder = DOM.getElementById("button-" + value);
final Button button = new Button("My Button");
button.render(button.getElement());
placeHolder.appendChild(button.el().dom);
}
});
return "<div id='button-" + value + "'/>";
}
});
columns.add(tc);

The cell renderer prints raw html. This is great because now I can place a div tag with an id as a place holder. I defer the creation of the button until after the rendering. But I also have to make sure the GXT button is rendered so I force it to render

button.render(button.getElement());

Regular GWT widgets don't have this problem because they don't lazy load.

flow
07-02-2008, 01:22 AM
Thanks for this hint. But in my case, I want to add the widget dynamically, dependant on some constraint. So the TableColumn won't always show a specific widget. Sure, I could include the check into the ColumnRenderer. But I prefer clean code ;-).

Any other ideas or maybe improvements in the next Releases (1.1)??

Igor Nikolaev
12-04-2008, 09:48 AM
Based on jtmille3 code I've written WidgetCellRenderer:

public class WidgetCellRenderer implements CellRenderer<TreeTableItem>
{
public String render(final TreeTableItem item, final String property, final Object value)
{
TreeModel model = (TreeModel) item.getModel();

if (value == null || !(value instanceof Component))
return null;

final Component component = (Component) value;
component.render(component.getElement());
ComponentHelper.doAttach(component);

DeferredCommand.addCommand(new Command()
{
public void execute()
{
Element element = DOM.getElementById("combobox-" + property + "-" + item.getId());
element.appendChild(component.getElement());
}
});

return "<div id=\"combobox-" + property + "-" + item.getId() + "\"></div>";
}
}



So now just set renderer for the column and set value for the TreeTableItem:


TreeTableItem item = new TreeTableItem(new Object[2]);
item.setText("Tree Item"));
ComboBox<DataPoolModel> comboBox = new ComboBox<DataPoolModel>();
comboBox.setStore(...);
comboBox.addSelectionChangedListener(selectionChangedListener);
comboBox.setDisplayField("name");
item.setValue(1, comboBox);