Use this when several components belong together on a page and you want to treat them as one: hide them all, disable them all, set a CSS class on the element around them, or repaint them in one Ajax response. A WebMarkupContainer is a component for an ordinary HTML element that has no Java behavior of its own. Unlike a panel, it needs no class and no markup file: its markup is the element in the page.
Wrap the components in a container
Give the surrounding element a wicket:id and nest the components inside it, in the markup and in Java.
InboxPage.html
<div wicket:id="newMail" class="notice">
You have <span wicket:id="count"></span> new messages.
<a wicket:id="open">Read them</a>
</div>
InboxPage.java
WebMarkupContainer newMail = new WebMarkupContainer("newMail");
newMail.add(new Label("count", () -> mailbox.countUnread()));
newMail.add(new BookmarkablePageLink<Void>("open", UnreadPage.class));
add(newMail);
Hide or disable the group
Visibility and the enabled state of a container apply to all of its children. Decide them in onConfigure so they follow the current state:
WebMarkupContainer newMail = new WebMarkupContainer("newMail") {
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(mailbox.countUnread() > 0);
}
};
See Show, hide or disable a component.
Style the group
The container is a component, so behaviors work on it like on any other:
newMail.add(AttributeModifier.append("class", () -> mailbox.hasUrgent() ? "urgent" : null));
Repaint the group with Ajax
Turn on the markup id and add the container to the Ajax response. Everything inside it is rendered again.
newMail.setOutputMarkupPlaceholderTag(true);
add(new AjaxLink<Void>("refresh") {
@Override
public void onClick(AjaxRequestTarget target) {
target.add(newMail);
}
});
setOutputMarkupPlaceholderTag(true) also writes the id, and keeps a placeholder in the page while the container is hidden so it can reappear. See Update components with Ajax.
Group components without an HTML element
When an extra <div> would be invalid HTML or break your CSS, attach the container to a <wicket:container> tag. It works the same in Java, but in deployment mode it leaves no element in the output.
<table>
<wicket:container wicket:id="details">
<tr><th>Weight</th><td wicket:id="weight"></td></tr>
<tr><th>Size</th><td wicket:id="size"></td></tr>
</wicket:container>
</table>
A container without an element cannot be repainted with Ajax or carry attributes; use a real element for that.
Change a tag without regrouping its children
Sometimes you only want to control one element, such as setting a class on <body> in a base page, without making everything inside it a child of a new container. A TransparentWebMarkupContainer does that: components inside its tag in the markup can stay children of its parent in Java.
public class BasePage extends WebPage {
public BasePage() {
add(new TransparentWebMarkupContainer("body")
.add(AttributeModifier.append("class", this::getBodyClass)));
}
protected String getBodyClass() {
return null;
}
}
<body wicket:id="body">
<wicket:child/>
</body>
Subclasses keep adding their components to the page itself.