GWT: ‘A widget that has an existing parent widget may not be added to the detach list’

Problem

When wrapping an existing DOM element with a GWT widget (e.g. Button.wrap(…), HTML.wrap(…), etc), the GWT module will not load and report the exception like the following:

java.lang.AssertionError: A widget that has an existing parent widget may not be added to the detach list
at com.google.gwt.user.client.ui.RootPanel.detachOnWindowClose(RootPanel.java:136)
at com.google.gwt.user.client.ui.Label.wrap(Label.java:130)

Analysis

In GWT it does not seem to be possible, to wrap an element in the document’s DOM if any of its parents has been wrapped with a GWT widget before. For instance, see for the following HTML document …

<div style=”display: noneid=“outer_element”>

        <form class=“well”>

            <label><i class=“icon-exclamation-sign”></i> An error occurred while requesting your API key.</label>

            <div id=“inner_element”>No error message.</div>

        </form>

        </div>

… if we first wrap the element “outer_element” and then the element “inner_element” as in the following …

final HTML errorForm = HTML.wrap(DOM.getElementById(“outer_element”));

       final Label errorMessage = Label.wrap(DOM.getElementById(“inner_element”));

.. an exception will be thrown, since “outer_element” is the parent in the DOM of “inner_element“.

Solution

The exception can easily be prevented by wrapping DOM elements as GWT widgets from the inside out. So, the elements nested the deepest in the DOM will be wrapped first. Therefore, the example above will work smoothly, if the order in which the elements are wrapped is reversed, so that the inner element “inner_element” is wrapped before the outer element “outer_element“.

 // inner element must be wrapped BEFORE outer element

        final Label errorMessage = Label.wrap(DOM.getElementById(“inner_element”));

        final HTML errorForm = HTML.wrap(DOM.getElementById(“outer_element”));

References
gwt – How to add a custom widget to an element – Stack Overflow

How to wrap an existing div into an HTML widget ? – Google Web Toolkit | Google

java – How to mix html with gwt widgets? – Stack Overflow

2 thoughts on “GWT: ‘A widget that has an existing parent widget may not be added to the detach list’

  1. What if I have an inner element inside a widget defined in uibinder? In this case the outer element is already wrapped in a widget so I can’t wrap in reverse order. Is there a wa to wrap in this case? I show you an example:

    Go to the link

    I want to wrap the anchor mylink but it is inside a which is a widget. How can I do that?

    1. I don’t seem to be able to access your link. Can’t you insert the link as a widget? Or define the link somewhere else in the DOM, wrap it and then place in your widget?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s