TabSet Tutorial

Table of Contents

TabSet Tutorial

The tabSet component manages a stack of contentPane's using tabControls. The attribute "currentId" determines which of the panes in the stack is currently visible. All other non-selected contentPane's are hidden from view. The individual contentPane will determine it's own caching and scalability optimization. This tutorial will cover the following:

  1. Static TabSet
  2. Dynamic TabSet using c:forEach

The full source code for both tutorials can be found here. Additional information regarding the tabSet component can be found here:


Static TabSet


We will define a tabSet with 3 pre-defined contentPanes. Let's start by adding the <mobi:tabSet> component to our page:


tabs.xhtml
<mobi:tabSet fixedPosition="false" currentId="#{tabBean.selectedTabPane}">
</mobi:tabSet>


The tabSet component requires that we use contentPane's to define the per tab content. For this tutorial we will add 3 contentPane's, each having a layout using a <fieldset> and <mobi:fieldSetGroup> layout. Paste the following within the <mobi:tabSet> tags:


tabs.xhtml
   
<mobi:contentPane id="panelt1" title="Tab 1" client="true">
	<mobi:fieldsetGroup>
	      <h3>Content Panel 1</h3>
	</mobi:fieldsetGroup>
   </mobi:contentPane>
   <mobi:contentPane id="panelt2" title="Tab 2" client="true">
	<mobi:fieldsetGroup>
	      <h3>Content Panel 2</h3>
	</mobi:fieldsetGroup>
   </mobi:contentPane>
   <mobi:contentPane id="panelt3" title="Tab 3" client="true">
	<mobi:fieldsetGroup>
	      <h3>Content Panel 3</h3>
	</mobi:fieldsetGroup>
   </mobi:contentPane>


Note:

The attribute client on each of the above contentPanes is set to true.  Remember that the individual contentPane's will determine their own caching and scalability optimization. The attributes do the following:

  • client - If client is set to true, all markup (even non-visible panes) will be rendered to the browser. This will help improve performance by limiting the size and frequency of DOM updates and ultimately reduce the amount of throughput over the wireless connection which is a goal for any mobile application.
  • facelet - If facelet to true, the children of that contentPane are not added to the component tree unless that particular contentPane is selected and being viewed which will help reduce server side memory consumption.

TabBean.java


The <mobi:tabSet> currentId attribute will be value bound to a String object server side. This attribute will determine the currently selected contentPane but is not required.


TabBean.java
@ManagedBean(name = "tabBean")
@ViewScoped
public class TabBean implements Serializable {

	private static final long serialVersionUID = 1L;

	private String selectedTabPane = "panelt1";

	public String getSelectedTabPane() {
		return selectedTabPane;
	}

	public void setSelectedTabPane(String selectedTabPane) {
		this.selectedTabPane = selectedTabPane;
	}
}



Dynamic TabSet using c:forEach


Instead of having a static tabSet implementation with 3 pre-defined contentPane's, we will now use the iterative tag <c:forEach>. This approach will also us to iterated over a single child contentPane in order to generate 3 unique tabs. Our <mobi:tabSet> markup remains the same:


tabs.xhtml
<mobi:tabSet fixedPosition="false" currentId="#{tabBean.selectedTabPane}">
</mobi:tabSet>


By definition, the <c:forEach> tag is a basic iteration tag, accepting many different collection types and supporting subsetting and other functionality (Oracle). In order to use this tag, we must ensure that we have the namespace defined within our top level tag like so:


tabs.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
........
xmlns:c="http://java.sun.com/jsp/jstl/core">
........


NOTE: We will need to include the jstl.jar in our project's WEB-INF/lib directory in order for the c:forEach to work correctly. You can download the JSTL library here. We will then add the following code as a child of <mobi:tabSet>:


tabs.xhtml
<c:forEach items="#{tabBean.eachContentPane}" var="currContentPane">
        <mobi:contentPane id="#{currContentPane.id}" title="#{currContentPane.title}" client="#
           {currContentPane.client}" facelet="#{currContentPane.facelet}">
              <mobi:fieldsetGroup>
                       <h3>#{currContentPane.content}</h3>
              </mobi:fieldsetGroup>
        </mobi:contentPane>
</c:forEach>


TabBean.java


The c:forEach items attribute is bound to a list of plain old java objects (POJOs) and will iterate over each and populating our contentPanes. Here is our basic class definition:


TabBean.java
@ManagedBean(name="tabBean")
@ViewScoped
public class TabBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private List<EachContentPane> eachContentPane = new ArrayList<EachContentPane>();
}


Our EachContentPane object will contain the following properties and can be added as an inner class of TabBean:


TabBean.java
public static class EachContentPane implements Serializable {

		private static final long serialVersionUID = 1L;

		private String id;
		private boolean client;
		private boolean facelet;
		private String title;
		private String content;

		public EachContentPane(String id, boolean client, boolean facelet,
				String title,String content) {
			this.id = id;
			this.client = client;
			this.facelet = facelet;
			this.title = title;
			this.content = content;
		}

                //TODO Generate Getters/Setters
}


The client and facelet properties do the following:

  • client - If client is set to true, all markup (even non-visible panes) will be rendered to the browser. This will help improve performance by limiting the size and frequency of DOM updates and ultimately reduce the amount of throughput over the wireless connection which is a goal for any mobile application.
  • facelet - If facelet to true, the children of that contentPane are not added to the component tree unless that particular contentPane is selected and being viewed which can help reduce server side memory consumption.


The final step is to add a TabBean constructor where we instantiate our 3 EachContentPane objects which populate our tabs.


TabBean.java
	public TabBean() {
		eachContentPane
				.add(new EachContentPane("panelt1", true, false, "panel1",
						"content for panel 1"));
		eachContentPane
				.add(new EachContentPane("panelt2", false, false, "panel2",
						"content for panel 2"));
		eachContentPane
				.add(new EachContentPane("panelt3", false, true, "panel3",
						"content for panel 3"));
	}


The end result for both Usage 1 and Usage 2 will look like the following:



Source

1. tabset-static-tutorial.zip
2. tabset-dynamic-tutorial.zip
3. jstl.jar

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

© Copyright 2016 ICEsoft Technologies Canada Corp.