Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PaperDropdownMenu fails after initial import #145

Open
cpboyd opened this issue Jan 7, 2017 · 5 comments
Open

PaperDropdownMenu fails after initial import #145

cpboyd opened this issue Jan 7, 2017 · 5 comments

Comments

@cpboyd
Copy link

cpboyd commented Jan 7, 2017

The demo app works fine, since all dropdowns are limited to the same page...

However, if you have two pages with dropdowns, you'll notice something like the following error when opening the second page (whichever page is the second one you load):

Uncaught Error: com.google.gwt.event.shared.UmbrellaException: Exception caught: Cannot find element with id "gwt-uid-72". Perhaps it is not attached to the document body.
    at E2c_g$.ljb_g$ [as createError_0_g$] (Throwable.java:121)
    at E2c_g$.vjb_g$ [as initializeBackingError_0_g$] (Throwable.java:113)
    at E2c_g$.fjb_g$ (Throwable.java:74)
    at E2c_g$.Ljb_g$ (Exception.java:33)
    at E2c_g$.Tjb_g$ (RuntimeException.java:33)
    at E2c_g$.x2c_g$ (UmbrellaException.java:65)
    at E2c_g$ (UmbrellaException.java:26)
    at y1c_g$.B1c_g$ [as fireEvent_0_g$] (HandlerManager.java:129)
    at Q$e_g$._b_g$ [as fireEvent_0_g$] (Widget.java:129)
    at wi_g$ (DomEvent.java:125)
    at Q$e_g$.hc_g$ [as onBrowserEvent_0_g$] (Widget.java:177)
    at $be_g$ (DOM.java:1481)
    at Zbe_g$ (DOM.java:1420)
    at HTMLElement.Dhe_g$ (DOMImplStandard.java:317)
    at $sb_g$ (Impl.java:239)
    at btb_g$ (Impl.java:298)
    at HTMLElement.<anonymous> (Impl.java:77)

This also occurs on the initial page load if you have statically linked the paper-dropdown-menu.html.

This issue may be what was truly behind #85

@cpboyd
Copy link
Author

cpboyd commented Jan 9, 2017

Creating a Widget using the individual Elements (rather than trying to use the generated Polymer Widgets) seems to work fine:

        <paper-dropdown-menu-light no-label-float="" class="custom">
            <paper-listbox ui:field="menu" class="dropdown-content" selected="0">
                <paper-item>25</paper-item>
                <paper-item>50</paper-item>
                <paper-item>100</paper-item>
            </paper-listbox>
        </paper-dropdown-menu-light>

@ghost
Copy link

ghost commented Jan 11, 2017

It has to do with how the UiBinder is building the DOM tree.

Using Elements inside the Dropdown like:

<p:PaperDropdownMenu>
     <paper-menu class="dropdown-content">
          <paper-item>One</paper-item>
          <paper-item>Two</paper-item>
     </paper-menu>
 </p:PaperDropdownMenu>

will be generated to:

private PaperDropdownMenu build_f_PaperDropdownMenu2() {
      // Creation section.
      final PaperDropdownMenu f_PaperDropdownMenu2 = new PaperDropdownMenu(template_html1().asString());
      // Setup section.

      return f_PaperDropdownMenu2;
}

with template_html1() like
@Template("<paper-menu class='dropdown-content'> <paper-item>One</paper-item> <paper-item>Two</paper-item> </paper-menu>")

Using a Widget inside the Dropdown like:

<p:PaperDropdownMenu>
     <p:PaperMenu class="dropdown-content">
          <paper-item>One</paper-item>
          <paper-item>Two</paper-item>
     </p:PaperMenu>
 </p:PaperDropdownMenu>

will be generated to:

private PaperDropdownMenu build_f_PaperDropdownMenu2() {
  // Creation section.
  final PaperDropdownMenu f_PaperDropdownMenu2 = new PaperDropdownMenu(template_html2().asString());
  // Setup section.
  {
	// Attach section.
	UiBinderUtil.TempAttachment __attachRecord__ = UiBinderUtil.attachToDom(f_PaperDropdownMenu2.getElement());

	get_domId1Element().get();

	// Detach section.
	__attachRecord__.detach();
  }
  f_PaperDropdownMenu2.addAndReplaceElement(get_f_PaperMenu3(), get_domId1Element().get());

  return f_PaperDropdownMenu2;
}

In this case the template_html2() is just a SPAN holding an Id:
@Template("<span id='{0}'></span>")
It seems it is like a placeholder for the PaperMenu which will be replaced by the PaperMenu-Element after attaching to the DOM.

The error happens because get_domId1Element() returns a LazyDomElement and when calling the get()-method there is no element with this id.

The strange thing about this all is that this does not happen in general. It happens just for some Widgets like PaperDrawerPanel or PaperDropdownMenu and only if these Components are already registered (Polymer.isRegisteredElement returns true)

@ghost
Copy link

ghost commented Jan 11, 2017

Ok, things become clearer.
The core part of the Dropdown from the iron-dropdown is

<div id="contentWrapper">
    <content id="content" select=".dropdown-content"></content>
</div>

Since the DomId-Holder from the UiBinder is just a SPAN-element without the class dropdown-content the element will be dropped while attaching to the DOM and then the LazyDomElement can't find this element anymore.

Simple Test:

<p:PaperDropdownMenu>
     <span id="test-id" class="dropdown-content"></span>
</p:PaperDropdownMenu>

Without the class the span is missing after rendering in the browser.

Since the Vaadin PolymerWidget saves and restores the element properties when the webcomponent has to be downloaded first the effect may occur only on already registered components.

Conclusion: Using elements inside a webcomponent seems to be the way to go.

@cpboyd
Copy link
Author

cpboyd commented Jan 11, 2017

I wonder if it'd be possible to specify for certain widgets (like PaperDrawerPanel and PaperDropdownMenu) to always perform the save/restore regardless of whether or not the element has already been downloaded.

In my case, I don't really care about PaperDropdownMenuLight (using it more as a wrapper) but would rather have access to PaperListbox as a widget.

@ghost
Copy link

ghost commented Jan 11, 2017

Sorry, my assumption seems wrong. It has nothing to do with this properties save /restore but more with the fact that when the webcomponent is not loaded yet it is just a HTMLUnknownElement (without any content selector) and therefore the widget placeholder (SPAN element) is still alive.

It has more to do with the webcomponent lifecycle (point of registration)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant