Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GWT: On adding custom widget to celltable losing events of the custom widgets

Tags:

gwt

Our requirement is to make an editable grid using the CellTable containing custom widgets in its cell. The custom widget is having text box and search button associated with the text box. To add the custom widget as a cell created a subclass of AbstractEditableCell class (provided by GWT) and had override render() and onBrowserEvent() methods.

The render(Context context, String value, SafeHtmlBuilder sb) method of the custom widget cell creates a Safe html for the widget and render this safe html in to the cell. But the problem i am facing is, the custom widget is rendered correctly but it loses its associates events. The render method in given below :

if (viewData.isEditing()) {
    textBoxSelector.setText(text);
    OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml safeHtmlObj = new OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml(textBoxSelector.toString());
    sb.append(safeHtmlObj);
} else {
  // The user pressed enter, but view data still exists.
  sb.append(html);
}

If I try to add the widget in the render() method using the following code, it does not add the widget.

    int left = parent.getAbsoluteLeft();
    int top = parent.getAbsoluteTop();
    String elementId = "ID" + left + top;
    try {
        parent.setId(elementId);
        // parent.removeFromParent();
        RootPanel.get(elementId).add(textBoxSelector);
    } catch (AssertionError error) {
        RootPanel.get(elementId).add(textBoxSelector);
    }

I'd really appreciate if anyone can guide me in achieving addition of widget in the CellTable without it losing associated events.

like image 381
Anurag Avatar asked Aug 03 '11 08:08

Anurag


1 Answers

GWT's Cells are non-compatible with GWT Widgets. This means that you could not have a GWT widget placed inside of a cell and have it still function. Cells do have an alternative event handling mechanism though (covered below)

The reason for this is that Cells are closer to stateless renderers. Given a data object the Cell will spit out HTML. A single Cell will be reused over and over - spitting out HTML for various elements on the page - and never maintaining references to any of the DOM elements it creates.

In your above example, you call "someWidget.toString()". Doing this will only return the HTML representation of your widget and is what is loses your event handling.

Handling Events in Cells

GWT Dev Guide for Custom Cells (has some additional details)

To handle events in cells, you'll need to override a separate method called onBrowserEvent. You'll also need to configure your cell to be notified of particular events by calling super('click', 'keydown') in your constructor with the list of events you are interested in listening to.

Since Cells are stateless renderers, the onBrowserEvent will be passed a context of the rendered element that was clicked on along with the original data object that your cell rendered. You can then apply changes or manipulate the DOM as needed.

Here is an example taken from the linked dev guide above:

@Override
public void onBrowserEvent(
    Context context,
    Element parent,
    String value,
    NativeEvent event,
    ValueUpdater<String> valueUpdater) {

  // Let AbstractCell handle the keydown event.
  super.onBrowserEvent(context, parent, value, event, valueUpdater);

  // Handle the click event.
  if ("click".equals(event.getType())) {
    // Ignore clicks that occur outside of the outermost element.
    EventTarget eventTarget = event.getEventTarget();
    if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) {
      doAction(value, valueUpdater);
    }
  }
}
like image 186
Scott Bailey Avatar answered Oct 23 '22 04:10

Scott Bailey