0

I have the following ui situation:

<g:DisclosurePanel width="100%" ui:field="disclosurePanel">
       <g:customHeader>
         <g:HorizontalPanel width="100%" ui:field="tableRow">
           <g:cell width="16px" horizontalAlignment="ALIGN_CENTER">
             <g:Image url="images/plus-icon.gif" ui:field="icon"></g:Image>
           </g:cell>
           <g:cell width="20%">
             <g:Label ui:field="productName"></g:Label>
           </g:cell>
           <g:cell>
             <g:Anchor ui:field="info"><ui:msg>More info...</ui:msg></g:Anchor>
           </g:cell>
         </g:HorizontalPanel>
       </g:customHeader>
       <g:VerticalPanel width="100%" ui:field="details">
         <!-- details panel here -->
       </g:VerticalPanel>
     </g:DisclosurePanel>

And I would like to bind an event handler method to the Anchor info. However every widget I have in the header opens and closes the disclosurepanel, even if I hook something on the info by:

@UiHandler("info")
public void onInfoClicked(ClickEvent event)
{
   // do something custom, but do not open/close the disclosurepanel
}

I hope that this can be achieved without making a custom composite or stuff. Can you help me?

jabal
  • 11,987
  • 12
  • 51
  • 99

2 Answers2

1

Well it works as it is designed. Each element you put inside the DisclosurePanel has a click handler which opens/ closes it. So inside your header there should be only images and or text, basically onyl elements with no atteched logic. I would consider arranging your html elements different, so the link isn't inside the header...

If you really, really have to put it inside the header, you can add this to your Anchor click event:

disclosurePanel.setOpen(!disclosurePanel.isOpen());

This will restore the previous state of the DisclosurePanel. The good part is, that it is so fast, that you don't even see the DisclosurePanel opening/closing, the bad part is, that this is really bad design....

Addition: the DisclosurePanel uses Anchors to be displayed. An anchor allowes per definition only block elements, so you shouldn't use it like this at all! (See Is putting a div inside a anchor ever correct?)

Community
  • 1
  • 1
Stefan
  • 14,826
  • 17
  • 80
  • 143
  • My problem is that I cannot add any event handler to the widgets inside the header. So I cannot add even the line you told. I considered your suggestion and restructured my ui so that the widgets that were previously inside the header are out now controlling the disclosurepanel and the header is hidden. – jabal Apr 12 '12 at 09:19
1

DisclosurePanel's header is private inner class ClickableHeader:

private final class ClickableHeader extends SimplePanel {

private ClickableHeader() {
  // Anchor is used to allow keyboard access.
  super(DOM.createAnchor());
  Element elem = getElement();
  DOM.setElementProperty(elem, "href", "javascript:void(0);");
  // Avoids layout problems from having blocks in inlines.
  DOM.setStyleAttribute(elem, "display", "block");
  sinkEvents(Event.ONCLICK);
  setStyleName(STYLENAME_HEADER);
}

@Override
public void onBrowserEvent(Event event) {
  // no need to call super.
  switch (DOM.eventGetType(event)) {
    case Event.ONCLICK:
      // Prevent link default action.
      DOM.eventPreventDefault(event);
      setOpen(!isOpen);
  }
}
}

assuming your code:

@UiField
DisclosurePanel p;

//call this somewhere once on widget creation to 
//prevent header's default click handler
private void myInit()
{
    p.getHeader().unsinkEvents(Event.ONCLICK);
}

@UiHandler("info")
public void onInfoClicked(ClickEvent event)
{
   //trigger "standard" click handler if you want
   if(someCondition) {
       //convert GwtEvent descendant to NativeEvent descendant;
       p.getHeader().onBrowserEvent(event.getNativeEvent().<Event> cast());
   }

   // do something custom, but do not open/close the disclosurepanel
}
Tomasz Gawel
  • 8,379
  • 4
  • 36
  • 61
  • To anyone else thinking of trying this solution - it doesn't work. Even after calling unsinkEvents the disclosure panel still reacts to click events as usual. The only solution to this is described at http://www.summa-tech.com/blog/2010/04/19/gwt-disclosurepanel-openclose-without-header. – Ben Oct 15 '14 at 11:10
  • @Ben, on which GWT version it does not work? I tested it when I wrote this post - and it worked properly on the version which was then up-to-date. (It was however december 2012, maybe current GWT version has different implementation.) – Tomasz Gawel Oct 15 '14 at 11:57
  • It should also work on 2.6 version - checked it just now. So please tell what version of GWT caused any problems to You! – Tomasz Gawel Oct 15 '14 at 12:04