I needed an Ajax Tabbed Panel with tabs that load only when clicked and and a wait indicator (a.k.a. hourglass or wait cursor) when the tab is being loaded. This example just shows how to use existing Wicket 1.3 components for those who haven't used these components before.
First, an example of how to use it:
MyTabPage.java
public class MyTabPage extends WebPage
{
private static final long serialVersionUID = 1L;
public MyTabPage()
{
add(HeaderContributor.forCss(MyTabPage.class, "MyTabPage.css"));
final Listtabs = new ArrayList ();
tabs.add(new MyTab("Tab One")
{
private static final long serialVersionUID = 1L;
@Override
public Panel createPanel()
{
return new TabOnePanel();
}
});
tabs.add(new MyTab("Tab Two")
{
private static final long serialVersionUID = 1L;
@Override
public Panel createPanel()
{
return new TabTwoPanel();
}
});
final MyTabbedPanel tabpanel = new MyTabbedPanel("tabpanel", tabs);
add(tabpanel);
}
}
MyTabPage.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.sourceforge.net/" xml:lang="en"
lang="en">
<body>
<div wicket:id="tabpanel">[tabbed panel will be here]</div>
</body>
</html>
The CSS for the project:
MyTabPage.css
div.mytabpanel div.tab-row{
float:left;
width: 100%;
border-bottom: 1px solid #3e6581;
background-color: #e6e6e6;
}
div.mytabpanel div.tab-row ul {
margin:0;
list-style:none;
}
div.mytabpanel div.tab-row li {
float:left;
width: 10%;
}
div.mytabpanel div.tab-row a {
display:block;
text-decoration:none;
font-weight:bold;
color:#949494;
}
div.mytabpanel div.tab-row li.selected a {
color:#333;
}
div.mytab {
padding: 5em;
}
The tabbed panel class:
MyTabbedPanel.java
public class MyTabbedPanel extends Panel
{
private static final long serialVersionUID = 1L;
private final TabbedPanel tabbedPanel;
public MyTabbedPanel(String id, Listtabs)
{
super(id);
tabbedPanel = new AjaxTabbedPanel("mytabpanel", tabs)
{
private static final long serialVersionUID = 1L;
// Override newLink to supply an IndicatingAjaxLink (wait cursor)
@Override
protected WebMarkupContainer newLink(String linkId, final int index)
{
final WebMarkupContainer c = new IndicatingAjaxLink(linkId)
{
private static final long serialVersionUID = 1L;
public void onClick(AjaxRequestTarget target)
{
setSelectedTab(index);
if (target != null)
{
target.addComponent(MyTabbedPanel.this);
}
onAjaxUpdate(target);
}
};
return c;
}
};
tabbedPanel.setOutputMarkupId(true);
MyTabbedPanel.this.setOutputMarkupId(true);
add(tabbedPanel);
}
public static class MyTab extends AbstractTab
{
private static final long serialVersionUID = 1L;
private Panel p;
public MyTab(String label)
{
super(new Model(label));
}
@Override
public Panel getPanel(String panelId)
{
if (p == null)
{
// Lazily create the panel
p = createPanel();
if (!TabbedPanel.TAB_PANEL_ID.equals(p.getId()))
{
throw new IllegalArgumentException(
"Panel id must be TabbedPanel.TAB_PANEL_ID");
}
p.setOutputMarkupId(true);
}
return p;
}
protected Panel createPanel()
{
throw new IllegalArgumentException("Must provide a panel");
}
}
}
MyTabbedPanel.html
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.sourceforge.net/" xml:lang="en" lang="en">
<body>
<wicket:panel>
<div wicket:id="mytabpanel" class="mytabpanel"></div>
</wicket:panel>
</body>
</html>
Finally, a simple panel displayed by a tab:
TabOnePanel.java
public class TabOnePanel extends Panel
{
private static final long serialVersionUID = 1L;
public TabOnePanel()
{
super(TabbedPanel.TAB_PANEL_ID);
add(new Label("mylabel", "Tab One Contents"));
}
}
TabOnePanel.html
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<wicket:panel>
<div wicket:id="mylabel" class="mytab"></div>
</wicket:panel>
</body>
</html>
4 comments:
Thanks,
this post was really useful for me.
Brilliant. This is how examples should be presented. I have not used AjaxTabbedPanel before but once I have worked through your example I was geared for production implementation.
Great article, but I have a question....how can I move the busy indicator so that it will show in another place?
ex. I want my busy indicator to appear not on the right side of every tab, but always on the right side of the last tab
Instead of overriding newLink to create an IndicatingAjaxLink, you could probably create an AjaxLink and instead attach a WicketAjaxIndicatorAppender to the tabbed panel itself. I've used WicketAjaxIndicatorAppender but not in this particular use case, so you'll have to try it and see.
Post a Comment