TabView binding with ui:include for dynamic tabs

UI Components for JSF
Post Reply
nalmeida
Posts: 5
Joined: 13 Nov 2017, 12:03

13 Nov 2017, 12:45

Hi to everyone,

I'm new in Primefaces but I really enjoying it. As newbie I'm facing some troubles but this one I'm posting about wasted too many hours and finally my patience :cry: .

I have a menu with links that open a new tab in a tabview component. New tab content is a xhtml file. I have a selector that allows me to choose a item and only one tab, so I'm using the xhtml as "template" (only a tab for each selector item).

For example:
Selected: Item1; tabs: Tab1, Tab2
Selected: Item2; tabs: Tab1, Tab3, Tab4
Having a tabview:
|Tab1|Tab2|Tab1|Tab3|Tab4|

This is xhtml code:

Code: Select all

 <h:form id="tabViewForm">
				<p:growl id="tabViewGrowl" showDetail="true" />
				<p:tabView id="tabView" dynamic="true" cache="false"
					rendered="true" binding="#{testbinding.tabView}" >
					<p:ajax event="tabChange" listener="#{testbinding.onTabChange}" />
					<p:ajax event="tabClose" listener="#{testbinding.onTabClose}" />			
					<c:forEach var="tab" items="#{testbinding.tabs}" varStatus="loop">
						<p:tab title="Tab - #{tab.tabName}" closable="true"
							disabled="#{tab.tabDisabled}">
							<p:fragment id="tabContentWrapper">
								<ui:include src="#{tab.tabURL}"></ui:include>
							</p:fragment>
						</p:tab>
					</c:forEach>
				</p:tabView>
			</h:form>
And my managed bean (principal parts):

Code: Select all

private TabView tabView;

	private List<Tab> tabs;

	@PostConstruct
	private void init() {
		tabView = new TabView();
		tabs = new LinkedList<Tab>();
         }

Getter and setter for tabs and tabView
...

	public void addTab1() {
		tabs.add(new Tab("TAB_1", "Pestaña 1", "/content/tabs/tab1.xhtml", false));
		PrimeFaces.current().ajax().update(tabView.getClientId()); <--- when I have the binding of the tabView
		// PrimeFaces.current().ajax().update("tabViewForm:tabView"); <--- when I not have the binding

		log.info("TABVIEW: getChildren(): " + tabView.getChildren() + " size: " + tabView.getChildCount()
				+ " clientId: " + tabView.getClientId());
		log.info("TABS: " + tabs + " size: " + tabs.size());
	}

Rest of the tabs methods...
The problem:

When using the binding I have console messages telling that the components already exists

Code: Select all

java.lang.IllegalStateException: El ID del componente tabViewForm:tabView:j_idt70 ya se ha encontrado en la vista.
translated: java.lang.IllegalStateException: The ID of the tabViewForm component: tabView: j_idt70 has already been found in the view.
	at com.sun.faces.util.Util.checkIdUniqueness(Util.java:1026)
	at com.sun.faces.util.Util.checkIdUniqueness(Util.java:1010)
	at com.sun.faces.util.Util.checkIdUniqueness(Util.java:1010)
	at com.sun.faces.util.Util.checkIdUniqueness(Util.java:1010)
	at com.sun.faces.util.Util.checkIdUniqueness(Util.java:1010)
	at com.sun.faces.application.view.FaceletPartialStateManagementStrategy.saveView(FaceletPartialStateManagementStrategy.java:460)
	at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:89)
	at com.sun.faces.application.view.WriteBehindStateWriter.getState(WriteBehindStateWriter.java:327)
	at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:221)
	at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:475)
	at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:134)
	at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
	at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
	....
But if I not use the binding all is working right...

What I want is to control the TabView object from the code (to select active tab when I create dynamically one new, for example)

Why when I do the bind this kind of problem appears and how can I solve it?

I'm using latest 6.2 snapshot but I also had the problem with 6.1 version. It's running on a JBOSS 7.0.0 EAP server.

Thanks you very much in advance.

Nestor Almeida.

Jan Eckert
Posts: 84
Joined: 11 Sep 2014, 10:13
Location: Brussels, Belgium

15 Nov 2017, 16:35

Code: Select all

					
<c:forEach var="tab" items="#{testbinding.tabs}" varStatus="loop">
	<p:tab title="Tab - #{tab.tabName}" closable="true" disabled="#{tab.tabDisabled}">
		<p:fragment id="tabContentWrapper">
			<ui:include src="#{tab.tabURL}"></ui:include>
		</p:fragment>
	</p:tab>
</c:forEach>
This part of your code looks very dangerous, since you create multiple tabs (which is no NamingContainer) with a fragment each that all have the same ID="tabContentWrapper". So in case of more than one tab, you will end up with at least dublicate IDs.

My first guess without actually trying to get it run. So I propose to replace the code above with

Code: Select all

					
<c:forEach var="tab" items="#{testbinding.tabs}" varStatus="loop">
	<p:tab title="Tab - #{tab.tabName}" closable="true" disabled="#{tab.tabDisabled}">
		<p:fragment id="tabContentWrapper_#{loop.index}">
			<ui:include src="#{tab.tabURL}"></ui:include>
		</p:fragment>
	</p:tab>
</c:forEach>
Take care


Naive question: You mention a binding of the component ... which scope has it?

*edited b/c of typo
Primefaces 6.1+
Wildfly 11

nalmeida
Posts: 5
Joined: 13 Nov 2017, 12:03

27 Nov 2017, 13:43

Hi Jan,

I'm using @SessionScoped in the tabbedview bean.

Problem is that I'm using a xhtml file as template so I need to duplicate these tabs with different data, same xhtml 'static' content.

It's working if I don't use the binding, but I need to use it to access to the tabview component functions.

Thanks for your help anyway,

Nestor.

Epifanov
Posts: 1
Joined: 06 Sep 2018, 19:44

07 Sep 2018, 19:49

Hello, I also had such problems. This is my solution.

Code: Select all

		<p:tabView id="tabView" style="height:63vh;" dynamic="false" cache="false">
			<p:ajax event="tabChange" listener="#{flatdoc.onTabChange}" update="tabView"/>
			<p:tab binding="#{flatdoc.dynamicTabs[0]}" rendered="#{flatdoc.dynamicTabs.length > 0}"/>
			<p:tab binding="#{flatdoc.dynamicTabs[1]}" rendered="#{flatdoc.dynamicTabs.length > 1}"/>
			<p:tab binding="#{flatdoc.dynamicTabs[2]}" rendered="#{flatdoc.dynamicTabs.length > 2}"/>
			<p:tab binding="#{flatdoc.dynamicTabs[3]}" rendered="#{flatdoc.dynamicTabs.length > 3}"/>
			<p:tab binding="#{flatdoc.dynamicTabs[4]}" rendered="#{flatdoc.dynamicTabs.length > 4}"/>
			<p:tab title="Attached files" rendered="#{flatdoc.documentMetadata.showFilesTab}">
			....
and Java code:

Code: Select all

		Tab tab = new Tab();
		tab.setId("params");
		tab.setTitle("Additional parameters");
		tab.setRendered(true);
                fillDocumentPropertiesTab(tab);
		dynamicTabs.add(tab);

		int tabId = 1;
		while (dynamicTabs.size() < 10) {
			Tab tab = new Tab();
			tab.setId("childsTab-" + tabId++);
			tab.setRendered(false);
			dynamicTabs.add(tab);
		}

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 31 guests