Dynamic Tab creation.

UI Components for JSF
jlferreira
Posts: 43
Joined: 16 Nov 2010, 17:52

16 Nov 2010, 18:23

Hi all.
I have a doubt.
How can I create a new tab with a specific name, when I click a button or in a menu option?
I'd looked many sites and I didn't had success.
I tried jquery, but it didn't work.
I don't know javascript, so, I don't know if i did the right configuration.
There is another way to do that?
I'm seeing that version 2.2 of PrimeFaces can create tabs dynamically. Am I correct?
Are there another options? Is jquery still the best choice?
Eclipse Helios.
JSF-2.0 (Mojarra 2.1.0-b11).
GlassFish 3.1.
PrimeFaces 2.2.1
EclipseLink 2.1.x - EclipseLink 2.1.x.
PostgreSQL 9.0

User avatar
tefron
Posts: 94
Joined: 15 Sep 2010, 23:54
Location: Canada
Contact:

16 Nov 2010, 20:00

You can try to you c:forEach i.e.:

Code: Select all

        <p:tabView >
            <c:forEach items="#{sessionBean1.tabs}" var="tab" varStatus="status" >
                <p:tab  title="#{tab.title}" >
                    <h:panelGrid>
                        <h:outputText value="Value: #{tab.content}" />
                    </h:panelGrid>
                </p:tab>
            </c:forEach>
        </p:tabView>
and add or remove objects to the tabs collection.

Let me know if it helps,

Cheers, Tamir
PrimeFaces: primefaces-8.0
Mojara2.3
Netbeans8.2
wildfly-17.0.1.Final

jlferreira
Posts: 43
Joined: 16 Nov 2010, 17:52

16 Nov 2010, 21:26

Tamir,
May you post the sessionBean1 that you used in this example?
Thanks.
Eclipse Helios.
JSF-2.0 (Mojarra 2.1.0-b11).
GlassFish 3.1.
PrimeFaces 2.2.1
EclipseLink 2.1.x - EclipseLink 2.1.x.
PostgreSQL 9.0

User avatar
tefron
Posts: 94
Joined: 15 Sep 2010, 23:54
Location: Canada
Contact:

16 Nov 2010, 23:59

Code: Select all

@ManagedBean
@SessionScoped
public class SessionBean1 implements Serializable {
    private List<Tab> tabs = new ArrayList();

    public List getTabs() {
        return tabs;
    }
    public void addTab(String label, String content) {
        //init last tabs

        this.tabs.add(new Tab(label, content));
     }

 }

public class Tab {
    private String label;
    private String content;

    public Tab(String label, String content) {
         this.label = label;
        this.content= content;
   }

    public String getLabel() {
        return label;
    }

....
}

}

PrimeFaces: primefaces-8.0
Mojara2.3
Netbeans8.2
wildfly-17.0.1.Final

jlferreira
Posts: 43
Joined: 16 Nov 2010, 17:52

17 Nov 2010, 14:40

Tamis,
May you explain me how could I reload the foreach after adding a tab.
I`m using a button to do the addTab(), but the tabs don`t reload automatically.
I have the followin need:
In the left side of the page I put a dynamic menu:
<p:menu style="width:90%" model="#{menuBean.model}"/>
menuBean creates the menu and menuItens.
How could I create tabs in the middle (content) of the page?

Thanks again for all help.
Eclipse Helios.
JSF-2.0 (Mojarra 2.1.0-b11).
GlassFish 3.1.
PrimeFaces 2.2.1
EclipseLink 2.1.x - EclipseLink 2.1.x.
PostgreSQL 9.0

User avatar
tefron
Posts: 94
Joined: 15 Sep 2010, 23:54
Location: Canada
Contact:

17 Nov 2010, 18:34

you need to tell your command button which components to process and update.
PrimeFaces: primefaces-8.0
Mojara2.3
Netbeans8.2
wildfly-17.0.1.Final

jlferreira
Posts: 43
Joined: 16 Nov 2010, 17:52

17 Nov 2010, 20:00

Guys,
I could not get the desired result yet.
I'll be very happy if someone can help me.
I want when I press the button, a tab is created on this page.


This is a sample of the code that I'm trying to implement:
page:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.prime.com.tr/ui"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:c="http://java.sun.com/jsp/jstl/core">
	<f:view>
		<h:head>
			<meta content='text/html; charset=iso-8859-1' http-equiv='Content-Type'/>
<!-- 		<link type="text/css" rel="stylesheet" href="#{request.contextPath}/resources/themes/cupertino/skin.css" /> -->
			<link type="text/css" href="resources/css/cupertino/jquery-ui-1.8.6.custom.css" rel="stylesheet" />
			<style type="text/css">
                 .ui-widget {
                         font-size: 75%;
                 }
                 .themeMenu {
                         overflow: auto;
                         height:300px;
                         width:200px;
                 }
			</style>
		</h:head>
		<h:body>
			<h:form id="form1">
				<p:tabView id="tvteste">
				    <c:forEach items="#{montaTela.tabs}" var="tab" varStatus="status" >
				        <p:tab  title="#{tab.label}" >
				            <h:panelGrid>
				                <h:outputText value="Value: #{tab.content}" />
				            </h:panelGrid>
				        </p:tab>
				    </c:forEach>
				</p:tabView>
				<p:accordionPanel autoHeight="false">
					<p:tab title="Cadastros" >
						<p:commandButton value="Países" action="#{montaTela.addTab}" update="form1:tvteste" style="width:99%;" />
					</p:tab>
				</p:accordionPanel>
			</h:form>
		</h:body>

	</f:view>
</html>
And this is the MontaTela.class:

Code: Select all

package br.com.sitic.sitic.sistema.backing;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;


public class MontaTela implements Serializable {
	    private List<Tab> tabs = new ArrayList();

	    public List getTabs() {
	        return tabs;
	    }
	    public void addTab(String label, String content) {
	        //init last tabs

	        this.tabs.add(new Tab(label, content));
	        
	     }
	    public void addTab() {
	        //init last tabs

	        this.tabs.add(new Tab("Tab1", "Conteudo-1"));
	     }

	    public class Tab {
	        private String label;
	        private String content;

	        public Tab(String label, String content) {
	             this.label = label;
	            this.content= content;
	        }

	        public String getLabel() {
	            return label;
	        }
	        
	        public void setLabel(String label){
	        	this.label = label;
	        }
	        
	        public String getContent(){
	        	return content;
	        }
	        public void setContent(String content){
	        	this.content = content;
	        }
	    }

}

the faces-config.xml:

Code: Select all

	<managed-bean>
		<managed-bean-name>montaTela</managed-bean-name>
		<managed-bean-class>br.com.sitic.sitic.sistema.backing.MontaTela</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
	</managed-bean>
thanks for all help.
Eclipse Helios.
JSF-2.0 (Mojarra 2.1.0-b11).
GlassFish 3.1.
PrimeFaces 2.2.1
EclipseLink 2.1.x - EclipseLink 2.1.x.
PostgreSQL 9.0

User avatar
tefron
Posts: 94
Joined: 15 Sep 2010, 23:54
Location: Canada
Contact:

18 Nov 2010, 00:50

I was able to make your example work however its takes pressing the button twice before the tabs are starting to show because of the phase that the c:forEach is called. I guess that it wasn't designed to be fully dynamic :cry:
I had to disable ajax for the button and to use a session bean.
hear is my code:
XHTML:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<!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:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
    <f:view>
        <h:head>
                    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

            <!--meta content='text/html; charset=iso-8859-1' http-equiv='Content-Type'/-->
   <!--       <link type="text/css" rel="stylesheet" href="#{request.contextPath}/resources/themes/cupertino/skin.css" /> -->
            <link type="text/css" href="resources/css/cupertino/jquery-ui-1.8.6.custom.css" rel="stylesheet" />
            <style type="text/css">
                .ui-widget {
                    font-size: 75%;
                }
                .themeMenu {
                    overflow: auto;
                    height:300px;
                    width:200px;
                }
            </style>
        </h:head>
        <h:body>
            <h:form id="form1">
                <p:tabView id="tvteste">
                    <c:forEach items="#{montaTela.tabs}" var="tab" varStatus="status" >
                        <p:tab  title="#{tab.label}" >
                            <h:panelGrid>
                                <h:outputText value="Value: #{tab.content}" />
                            </h:panelGrid>
                        </p:tab>
                    </c:forEach>
                </p:tabView>
                <p:accordionPanel autoHeight="false">
                    <p:tab title="Cadastros" >
                        <p:commandButton value="Países" action="#{montaTela.addTab}" ajax="false" style="width:99%;" />
                    </p:tab>
                </p:accordionPanel>
            </h:form>
        </h:body>
    </f:view>
</html>
JAVA:

Code: Select all

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package test;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

/**
 *
 * @author tefron
 */
@ManagedBean
@SessionScoped
public class MontaTela implements Serializable {

    private List<Tab> tabs = new ArrayList();

    public MontaTela() {
        this.tabs.add(new Tab("Static Tab1", "Static Tab1 Content"));
        this.tabs.add(new Tab("Static Tab2", "Static Tab2 Content"));
    }

    public List getTabs() {
        return tabs;
    }

    public void addTab(String label, String content) {
        //init last tabs

        this.tabs.add(new Tab(label, content));

    }
    private int dynamicTabCounter = 1;

    public void addTab() {
        //init last tabs

        this.tabs.add(new Tab("Dynamic Tab" + dynamicTabCounter, "Dynamic Tab" + dynamicTabCounter + " Conteudo"));
        dynamicTabCounter++;
    }

    public class Tab {

        private String label;
        private String content;

        public Tab(String label, String content) {
            this.label = label;
            this.content = content;
        }

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
}



You can submit a request to make tabs creation more dynamic or maybe use javascript as you said.

Cheers Tamir
PrimeFaces: primefaces-8.0
Mojara2.3
Netbeans8.2
wildfly-17.0.1.Final

jlferreira
Posts: 43
Joined: 16 Nov 2010, 17:52

18 Nov 2010, 01:45

Tamir,
I'm very grateful with your help in this post.
Talking about javascript, I used jQuery to create tabs, but without fully success.
When I click the button (or menu item), the tabs is generated, but primefaces objects only works in the first tab.
In the tab creation command, I call a page to be loaded. this page is included (request i think) inside the tab. The called page has a <p:calendar/> object. The calendar is displayed correctly only in the first created tab. In others tabs, the field is displayed, but the calendar is not showed when I click in it.
This is the codes that I used to create with javascript:
MenuBean.java

Code: Select all

import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.model.DefaultMenuModel;
import org.primefaces.model.MenuModel;

public class MenuBean {

	
	private MenuModel model;

	public MenuBean() {
		model = new DefaultMenuModel();
		
		//First submenu
		Submenu submenu = new Submenu();
		submenu.setLabel("Dynamic Submenu 1");

		
		MenuItem item = new MenuItem();
		item.setValue("Dynamic Menuitem 1.1");
		item.setUrl("#");
		item.setOnclick("createTab('teste2.xhtml','Tab XX')");
		submenu.getChildren().add(item);
		
		model.addSubmenu(submenu);
	}
	
	public MenuModel getModel() {
		return model;
	}	
}
faces-config.xml:

Code: Select all

	<managed-bean>
		<managed-bean-name>menuBean</managed-bean-name>
		<managed-bean-class>br.com.sitic.sitic.sistema.backing.MenuBean</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
	</managed-bean>
template-teste.xhtml:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.prime.com.tr/ui"
	xmlns:ui="http://java.sun.com/jsf/facelets">
	<f:view>
		<h:head>
			<title>
				<ui:insert name="title">SITIC SISTEMAS - Transformando Informações em Conhecimento</ui:insert>
			</title>
			<meta content='text/html; charset=iso-8859-1' http-equiv='Content-Type'/>
<!-- 		<link type="text/css" rel="stylesheet" href="#{request.contextPath}/resources/themes/cupertino/skin.css" /> -->
			<link type="text/css" href="resources/css/cupertino/jquery-ui-1.8.6.custom.css" rel="stylesheet" />
			<style type="text/css">
                 .ui-widget {
                         font-size: 75%;
                 }
                 .themeMenu {
                         overflow: auto;
                         height:300px;
                         width:200px;
                 }
			</style>
			<script type="text/javascript" src="resources/js/jquery-1.4.2.min.js"></script>
			<script type="text/javascript" src="resources/js/jquery-ui-1.8.6.custom.min.js"></script>
			<script type="text/javascript" src="resources/js/ui.tabs.closable.min.js"></script>
			<script type="text/javascript">
				function init() {
					var promptTab=" ";
					var linkTab=" ";
				   $("#mytabs").tabs({
				            		    closable: true, 
				            		    cache:true, 
				            		    add: function(e, ui){
				                            $('#mytabs').tabs('select', '#' + ui.panel.id);
				            		    }});
				   // wipe all the tabs so we can programatically show the ones we want
				   removeAllTabs();
				   // if {condition}, then show relevant tab. this is just for example purposes
				   if (true) {
				      $("#tabs-1-tab").css("display","list-item");
				   }
				   // now show the tabs area
				   $("#mytabs").css("display","block");
				}
				
				function openTab(tabNum,closeOthers) {
				   if (closeOthers != false) {
				      removeAllTabs();
				   }
				   $("#tabs-"+tabNum+"-tab").css("display","list-item");
				   $("#mytabs").tabs("select",tabNum-1);
				}

				function removeAllTabs() {
				   $("#tablist").children().css("display","none");
				}

				function createTab5() {
				   // this will add a tab via the standard method
				   $("#mytabs").tabs("add","tab5.html","Fifth Tab");
				}

				function removeTab5() {
				   // this will add a tab via the standard method. part of the problem here is I don't know the index...just assuming its on the end
				   $("#mytabs").tabs("remove",$("#mytabs").tabs("length")-1);
				   // reselect the 2nd tab or it will show tab 3
				   $("#mytabs").tabs("select",1);
				}
				
				function createTab(linkTab,promptTab) {
				   $("#mytabs").tabs("add",linkTab,promptTab);
				}
				
				
				$(document).ready(init);
			</script>
		</h:head>
		<h:body>
			<p:layout fullPage="true">
				<p:layoutUnit id="top" position="top" resizable="true" height="80" minHeight="70" maxHeight="150">
					<ui:insert name="cabecalho">
					</ui:insert>
				</p:layoutUnit>			       
			    <p:layoutUnit id="bottom" position="bottom" height="60" minHeight="50" maxHeight="150" resizable="true">  
					<ui:insert name="rodape">
					</ui:insert>
			    </p:layoutUnit>
			       
			    <p:layoutUnit position="left" width="220" minWidth="100" maxWidth="400" header="Opções" resizable="true" collapsible="true"  scrollable="true">  
					<ui:insert name="esquerda">
					</ui:insert>
			<!--         <p:themeSwitcher initialText="Change Skin" buttonPreText="Skin: "/> -->
			    </p:layoutUnit>  
			       
			    <p:layoutUnit position="right" width="220" minWidth="100" maxWidth="400" header="Galeria" resizable="true" closable="true" collapsible="true">
					<ui:insert name="direita">
					</ui:insert>
			    </p:layoutUnit>  
			       
			    <p:layoutUnit position="center" scrollable="true">  
					<ui:insert name="conteudo">
					</ui:insert>
			    </p:layoutUnit>  
			</p:layout>
		</h:body>
	</f:view>
</html>
teste2.xhtml:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.prime.com.tr/ui"
	xmlns:ui="http://java.sun.com/jsf/facelets">
	<f:view>
		<h:head></h:head>
		<h:body>
				<p:calendar></p:calendar>
		</h:body>
	</f:view>
</html>
teste.xhtml - the page that I execute:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:p="http://primefaces.prime.com.tr/ui"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:c="http://java.sun.com/jsp/jstl/core">
	<f:view>
		<ui:composition template="/resources/templates/template-teste.xhtml">
			<ui:define name="conteudo">
				<body>
					<div id="mytabs" style="display:none;"> 
					   <ul id="tablist">
					   </ul>
					</div>
				</body>
			</ui:define>
			<ui:define name="esquerda">
				<h3>Dynamic Menu</h3>  
				<p:menu style="width:90%" model="#{menuBean.model}"/>
			</ui:define>
		</ui:composition>
	</f:view>
</html>
Thanks again.
Eclipse Helios.
JSF-2.0 (Mojarra 2.1.0-b11).
GlassFish 3.1.
PrimeFaces 2.2.1
EclipseLink 2.1.x - EclipseLink 2.1.x.
PostgreSQL 9.0

jlferreira
Posts: 43
Joined: 16 Nov 2010, 17:52

18 Nov 2010, 21:46

Anyone know the solution?
I tried to create dynamic tabs using jquery, but I can't do it using xhtml pages.
Examples in internet shows javascript codes that refers to '<p>' character, that do not work with xhtml.

Thanks for help.
Eclipse Helios.
JSF-2.0 (Mojarra 2.1.0-b11).
GlassFish 3.1.
PrimeFaces 2.2.1
EclipseLink 2.1.x - EclipseLink 2.1.x.
PostgreSQL 9.0

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 68 guests