0

Is there a way to handle sort of onAttach event in GWT Node? I suppose I could do like this:

Node myDiv = DOM.createDiv();
Magic.setOnAttachEventListener(myDiv, new EventListener() {
  @Override
  public void onEvent(Event event) {
    // ...
  }
}

The handler should be invoked when I do something like this,

parent.appendChild(myDiv);

given that the parent is attached itself, i.e., it is displayed in the current window.

Alexey Berezkin
  • 1,513
  • 1
  • 10
  • 18

4 Answers4

2

I post my second answer as now I know that you can't change the way how DIVs are added to the parent.

After some searching I found Mutation events. They allow you to listen to DOMNodeInserted event:

JS:

myDiv.addEventListener("DOMNodeInserted", function (ev) {
    alert('added');
}, false);

In GWT you need to use JSNI method:

private native void addListener(Element elem) /*-{
    elem.addEventListener("DOMNodeInserted", function (ev) {
        $wnd.alert('added');
    }, false);
}-*/;

It works, but... it's deprecated. You should use MutationObserver instead.

Unfortunately MutationObserver don't have NodeInserted event to be observed. I thought that subtree mutation observation would do the job but it didn't work for me. The solution is to observe childList mutation on the parent:

JS:

// create an observer instance
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        alert(mutation.type);
    });    
});

// configuration of the observer:
var config = {
    childList: true
};

// pass in the target node, as well as the observer options
observer.observe(elem, config);

And, again, for GWT you need to wrap it in JSNI method (you know how).

The mutation parameter in observer callback is a MutationRecord object.

So, if you can get the parent, use MutationObserver on it and observe childList mutation. If not, try to use the deprecated Mutation events.


I know that this is not pure GWT solution, but you can use GWT methods to handle event or mutation. You just need to call GWT method form JSNI like this:

[instance-expr.]@class-name::method-name(param-signature)(arguments)

You'll find all JSNI info in the GWT documentation.

Adam
  • 5,403
  • 6
  • 31
  • 38
1

All Widgets in GWT already implement HasAttachHandlers interface. If you need this functionality, you may be better off using a Widget instead of a Node.

Andrei Volgin
  • 40,755
  • 6
  • 49
  • 58
0

You can use SimplePanel or HTMLPanel as both use DIV for its contents.

On Panels you can call addAttachHandler method.

If you need an Element you can call getElement() method on the Panel.

This method works only if you attach myDiv as a Panel, so instead of

parent.appendChild(myDiv);

you should do this

HTMLPanel.wrap(parent).add(myDiv);

Here is an example code:

    Element parent = RootPanel.getBodyElement();
    SimplePanel myDiv = new SimplePanel();

    // use it as Panel
    myDiv.add(new Label("Hello!"));

    // or use it as an element
    myDiv.getElement().setInnerText("Hello 2!");

    myDiv.addAttachHandler(new Handler() {
        @Override
        public void onAttachOrDetach(AttachEvent event) {
            Window.alert("Attached");
        }
    });

//  parent.appendChild(myDiv.getElement());     // this will not fire the AttachEvent
    HTMLPanel.wrap(parent).add(myDiv);          // this will fire the AttachEvent
Adam
  • 5,403
  • 6
  • 31
  • 38
  • Unfortunately I can't change the way parent adds `myDiv`. If I could I would handle that "by hands" right after adding an element to a parent in whatever way. – Alexey Berezkin Jul 16 '16 at 08:28
0

There is also "polling" alternative which may be not very effective but easier, see https://stackoverflow.com/a/850995/938899.

Community
  • 1
  • 1
Alexey Berezkin
  • 1,513
  • 1
  • 10
  • 18