Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wicket container that is hidden when all its child components are hidden

Tags:

java

wicket

I have a block level element, a container, that should be hidden when all its child Wicket elements (buttons) are hidden. In other words, if any child button is visible, the container should be visible.

Earlier one of the buttons was always visible if any buttons were, so I used that button to control the visibility of a <wicket:enclosure>, handling all of this purely on HTML side.

Now, the specs have changed so that the buttons can be hidden/visible independently, so a simple enclosure won't work anymore (I think).

I got it working with something like this:

HTML:

<wicket:container wicket:id="downloadButtons">
     <wicket:message key="download.foo.bar"/>:
     <input type="button" wicket:id="excelDownloadButton" wicket:message="value:download.excel"/>
     <input type="button" wicket:id="textDownloadButton" wicket:message="value:download.text"/>
     <!-- etc ... -->
</wicket:container>

Java:

WebMarkupContainer container = new WebMarkupContainer("downloadButtons");

// ... add buttons to container ...

boolean showContainer = false;
Iterator<? extends Component> it = container.iterator();
while (it.hasNext()) {
    if (it.next().isVisible()) {
        showContainer = true;
        break;
    }
}
addOrReplace(container.setVisible(showContainer));

But the Java side is now kind of verbose and ugly, and I was thinking there's probably be a cleaner way to do the same thing. Is there? Can you somehow "automatically" hide a container (with all its additional markup) when none of its child components are visible?

(Wicket 1.4, if it matters.)

like image 440
Jonik Avatar asked Aug 01 '12 07:08

Jonik


1 Answers

If you want this to be reusable, you can define it as a IComponentConfigurationBehavior (for wicket version > 1.4.16) that you attach to any containers and then set the container visibility in the onConfigure() method of the behavior:

class AutoHidingBehavior extends AbstractBehavior {

    @Override
    public void bind(Component component) {
        if (! (component instanceof MarkupContainer) ) {
            throw new IllegalArgumentException("This behavior can only be used with markup containers");
        }
    }

    @Override
    public void onConfigure(Component component) {
        MarkupContainer container = (MarkupContainer) component;
        boolean hasVisibleChildren = false;
        for (Iterator<? extends Component> iter = container.iterator(); iter.hasNext(); ) {
            if ( iter.next().isVisible() ) {
                hasVisibleChildren = true;
                break;
            }
        }
        container.setVisible(hasVisibleChildren);
    }

}
like image 99
Costi Ciudatu Avatar answered Sep 21 '22 23:09

Costi Ciudatu