A full js tab for wicket
By Vincent DEMAY, Monday 3 September 2007 :: Wicket :: #78 :: rss
Here is a code snippet to do a full js tab for wicket (tabs on the left) :
TabPanel
TabPanel.html
TabPanel.js
TabPanel.css
[java]
package com.theveniceproject.cow.editors.ui.widgets;
import java.util.List;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.behavior.HeaderContributor;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.Loop;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
public class TabPanel extends Panel {
private List tabs;
private IModel tabCount;
private static final ResourceReference DEFAULT_CSS = new ResourceReference(LeftTabPanel.class, "css/TabPanel.css");
public TabPanel(String id, List<AbstractTab> tabs) {
super(id, new Model());
setOutputMarkupId(true);
checkTabs(tabs);
add(HeaderContributor.forCss(getCss()));
add(HeaderContributor.forJavaScript(LeftTabPanel.class, "TabPanel.js"));
//create a model for the tabs size
this.tabs = tabs;
tabCount = new AbstractReadOnlyModel()
{
private static final long serialVersionUID = 1L;
public Object getObject()
{
return new Integer(LeftTabPanel.this.tabs.size());
}
};
createTabs();
createContents();
}
/**
* Return the css to use to layout tabs
* @return the css to use to layout tabs
*/
public ResourceReference getCss() {
return DEFAULT_CSS;
}
@Override
protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
// TODO Auto-generated method stub
super.onComponentTagBody(markupStream, openTag);
getResponse().write("<script type=\"text/javascript\">var " + getMarkupId() + "Tabs = new TabManager('" + getMarkupId() + "'); ");
}
/**
* Method to check if tabs is all rightd
* @param tabs tabs list
*/
private void checkTabs(List<AbstractTab> tabs){
if (tabs == null)
{
throw new IllegalArgumentException("argument [tabs] cannot be null");
}
if (tabs.size() < 1)
{
throw new IllegalArgumentException(
"argument [tabs] must contain a list of at least one tab");
}
}
/**
* Create tabs on the left of the component
* @param tabsContainer
*/
protected void createTabs(){
add(new Loop("tabs", tabCount)
{
private static final long serialVersionUID = 1L;
protected void populateItem(LoopItem item)
{
final int index = item.getIteration();
final ITab tab = ((ITab)LeftTabPanel.this.tabs.get(index));
final boolean selected = index == 0;
WebMarkupContainer tabContent = new WebMarkupContainer("tab"){
@Override
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
tag.put("class", "tabs");
//connect onClick event
tag.put("onClick", LeftTabPanel.this.getMarkupId() + "Tabs.selectTab(this)");
}
@Override
protected void onBeforeRender() {
super.onBeforeRender();
if (selected){
add(new AttributeAppender("class", new Model("selected"), " "));
}
}
};
tabContent.add(new Label("title", tab.getTitle()));
item.add(tabContent);
}
});
}
/**
* Create the tab content using {@link AbstractTab} Panel
*/
private void createContents(){
add(new Loop("contents", tabCount)
{
private static final long serialVersionUID = 1L;
protected void populateItem(LoopItem item)
{
final int index = item.getIteration();
final ITab tab = ((ITab)LeftTabPanel.this.tabs.get(index));
final boolean selected = index == 0;
item.add(tab.getPanel("innerPanel"));
if (!selected){
item.add(new AttributeAppender("style", true, new Model("display:none"), ";"));
}
}
});
}
}
TabPanel.html
<wicket:panel> <table width="100%" class="leftTab" cellpadding="0" cellspacing="0"> <tr valign="top"> <td width="120px"> <div wicket:id="tabs"> <div wicket:id="tab"> <span wicket:id="title"></span> </div> </div> </td> <td> <div class="content"> <div wicket:id="contents"> <div wicket:id="innerPanel"> content </div> </div> </div> </td> </tr> </table> </wicket:panel>
TabPanel.js
function TabManager(/**String*/ id){
this.id = id;
this.table = document.getElementById(id).getElementsByTagName("table")[0];
/**
* Select the given tab and show its content
*/
this.selectTab = function(/** div */ tab){
this._clearSelected();
addClass(tab, "selected");
this.setContentSelected(tab);
}
/**
* Return the list of domNode representing tabs
*/
this._getTabs /** Node[] */ = function(){
return this.table.rows.item(0).cells.item(0).childNodes;
}
/**
* return the list of domNode Representing Content
*/
this._getContents /** Node[] */ = function(){
return this.table.rows.item(0).cells.item(1).getElementsByTagName("div")[0].childNodes;
}
/**
* Clear Selection
*/
this._clearSelected = function(){
var tabs = this._getTabs();
for (var i=0; i<tabs.length; i++){
if (tabs[i].nodeName == "DIV"){
removeClass(tabs[i].getElementsByTagName('div')[0], "selected");
}
}
}
/**
* Select the right Content making it visible block
*/
this.setContentSelected = function(/** div */ tab){
var tabs = this._getTabs();
var pos = 0;
for (var i=0; i<tabs.length; i++){
if (tabs[i].nodeName == "DIV"){
if (tab == tabs[i].getElementsByTagName('div')[0]){
break;
}
pos ++;
}
}
var contents = this._getContents();
var contentPos = 0;
for (var i=0; i<contents.length; i++){
if (contents[i].nodeName == "DIV"){
if (contentPos == pos){
contents[i].style.display="block";
}else{
contents[i].style.display="none";
}
contentPos ++;
}
}
}
}
function addClass(/**DomNode*/ node, /** String */ cssclass){
if (!new RegExp('\\b'+cssclass+'\\b').test(node.className)){
node.className+=node.className?' '+cssclass:cssclass;
}
}
function removeClass(/**DomNode*/ node, /** String */ cssclass){
var rep=node.className.match(' '+cssclass)?' '+cssclass:cssclass;
node.className=node.className.replace(rep,'');
}
TabPanel.css
table.leftTab {
border-spacing: 0px;
}
table.leftTab * div.tabs{
padding:4px 15px 4px 6px;
color:white;
cursor:pointer;
font-size:12px;
font-weight:bold;
white-space:nowrap;
background-image: url('sidetabsDefault.gif');
background-repeat: no-repeat;
}
table.leftTab * div.selected{
color:blue;
cursor: default;
background-image: url('sidetabsSelected.gif');
}
table.leftTab * .content {
border:2px solid blue;
min-height: 300px;
padding: 10px 25px 10px 25px;
font-family:'Arial',sans-serif;
font-size:12px;
}
table.leftTab * .content * table{
font-family:'Arial',sans-serif;
font-size:12px;
}
table.leftTab * .content * label{
font-weight:bold;
margin-right:50px;
}
Power by
Comments
1. Le Tuesday 4 September 2007 , par Joël
2. Le Tuesday 25 September 2007 , par jbq
Add a comment