Reputation: 1476
I have a bro problem which I don't know how to solve. I have this Primefaces p:tabMenu
which is used to call tabs with lazy loading.
<p:tabMenu id="tabs" activeIndex="0" >
<p:menuitem value="tab1" url="/tab1.jsf" />
<p:menuitem value="tab2" url="/tab2.jsf" />
</p:tabMenu>
I want to use the JSF tag ui:insert
in order to call the tab's code. How I can combine the ui:insert
tag into the above code?
Upvotes: 3
Views: 15353
Reputation: 4044
I see 2 approaches here:
1) Use one page for each tab. use the p:tabMenu component (available in primefaces 3.4). In this case, if user is viewing one tab and clicks on the second tab to display it, he will be redirected to another page.
pros: if you want to navigate from another page to the second tab, it's easy since it's a different page (see cons in 2nd approach). also, each tab page is load fast because it only contains code for one tab. you'll have a better separation of code.
cons: if users goes to another tab, all data entered in current tab will be lost. also, changing from one tab to another is not so fast because there is navigation involved.
this is the page for one tab (tab1.xhtml):
<h:body>
<p:tabMenu activeIndex="0">
<p:menuitem value="Tab 1" url="/tab1.jsf" />
<p:menuitem value="Tab 2" url="/tab2.jsf" />
</p:tabMenu>
<!-- content of tab1 goes here -->
</h:body>
this is the code for the other tab (tab2.xhtml):
<h:body>
<p:tabMenu activeIndex="1">
<p:menuitem value="Tab 1" url="/tab1.jsf" />
<p:menuitem value="Tab 2" url="/tab2.jsf" />
</p:tabMenu>
<!-- content of tab2 goes here -->
</h:body>
2) The other approach is to have one page with p:tabView. in this case, all the tab contents go in the same page. you can use dynamic="true" attribute on p:tabView to render the tab contents on demand and accelerate page load.
pros: smoother transition from tab to tab (always stays on same page).
cons: if you want to navigate directly to the 2nd tab for example, it's not so easy. so will have to use activeIndex attribute of tabView pointing to an attribute in the managed bean that handles the first tab, and still you'll be constructing the bean of the first tab when you actually don't need it.
this is the code for the main page that contains the tab:
<h:body>
<p:tabView dynamic="true">
<p:tab id="tab1" title="Tab 1" >
<ui:include src="tab2.xhtml" />
</p:tabView>
<p:tab id="tab2" title="Tab 2" >
<ui:include src="tab2.xhtml" />
</p:tab>
</p:tabView>
</h:body>
and you'll need the pages for each tab (that is inserted into main page): tab1.xhtml:
tab2.xhtml:
Upvotes: 8
Reputation: 2435
I assume you want to share code between tabs?
I think you are staring yourself blind on the tabMenu component. You do not need it's assistance to properly use templates here.
Just:
Those pages could then be tabs or whatever you want.
a proper structure could perhaps be to define tabs.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions"
xmlns:o="http://omnifaces.org/ui">
<h:head>
<h:outputStylesheet name="style.css" library="css" />
<div id="header">
<ui:insert name="header">
<title><ui:insert name="title">title</ui:insert></title>
</ui:insert>
</div>
</h:head>
<h:body>
<div id="content">
<ui:insert name="content">
content here
</ui:insert>
</div>
</h:body>
</html>
Then for each tab you have:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions"
xmlns:pe="http://primefaces.org/ui/extensions"
template="/WEB-INF/templates/template.xhtml">
<ui:define name="header">
a specific tab header here
</ui:define>
<ui:define name="content">
specific content here
</ui:define>
</ui:composition>
Note that this is just standard templating with JSF 2. Good luck
Upvotes: 2