c:forEach inside p:tab does not work - jsf

I am using primefaces 6, JSf2.0, jstl 1.2 on Weblogic server.
I have an xhtml page where i want to display panels dynamically inside a Tab. The panels should behave like a Dashboard, so i have put the panels inside a dashboard tag.
My problem is that c:forEach is not able to get values from the items I want to iterate. It is confirmed that my "items="${cg.charts}" is of List type and does have objects, but the panels dont appear in UI, as well as there are not exception raised. Any leads ?
<p:tabView id="tabViewId"
value="#{userdashboard.chartGroupsList}" var="cg" onTabShow="reflowChart()" >
<p:tab title="#{cg.groupName}" >
<p:dashboard model="#{userdashboard.model}" >
<p:ajax event="reorder" listener="#{userdashboard.handleReorder}" />
<c:forEach var="c" items="${cg.charts}">
<p:panel id="pnlDivId#{c.id}" header="#{c.name}">hello</p:panel>
</c:forEach>
</p:dashboard>
</p:tab>
</p:tabView>

Related

c:forEach not iterating through list in a TabView

I have been trying to iterate through a list of tabs (my own custom tab object) by using c:forEach tag. But when I run the code, the tabs are not getting displayed. The page has no tabs.
When I debugged the code, I found that the getter method for the list object in the c:forEach items is not getting called. Please refer the below xhtml code:
<p:tabView id="tabView" dynamic="true" cache="false">
<p:ajax event="tabChange" listener="#{tabsController.onTabChange}" />
<c:forEach items="#{menusController.tabs}" var="customTab" varStatus="loop">
<p:tab title="#{customTab.title}" >
<f:subview id="tab_#{loop.index}">
<ui:include src="#{customTab.pageName}" />
</f:subview>
</p:tab>
</c:forEach>
</p:tabView>
I tried to follow the solution in this post JSF dynamically include src in "ui:include src="#{bean.pagePath}" but still it didn't work.
You should not mixing JSP and JSF tags, c:forEach is executing before JSF parser, instead use ui:repeat.

PrimeFaces p:accordionPanel inside ui:repeat or c:forEach

I'm trying to create multiple accordionPanels.
I tried to include this tag inside repeat elements (e.g. c:forEach).
The accordionPanel is well rendered, but I'm unable to switch from one tab to another.
These are some codes I tried:
<ui:repeat value="#{myBackingBean.myList}" var="o">
<p:accordionPanel dynamic="true" cache="true" multiple="true" widgetVar="accordion">
<p:tab title="Title 1">
#{o.data_one}
</p:tab>
<p:tab title="Title 2">
#{o.data_two}
</p:tab>
</p:accordionPanel>
</ui:repeat>
And also
<c:forEach items"${myBackingBean.myList}" var="o">
<p:accordionPanel dynamic="true" cache="true" multiple="true" widgetVar="accordion">
<p:tab title="Title 1">
#{o.data_one}
</p:tab>
<p:tab title="Title 2">
#{o.data_two}
</p:tab>
</p:accordionPanel>
</ui:repeat>
Both of these codes produces a list of accordionPanels, each with two tabs.
But I'm unable to switch from one tab to another: If I click one tab it does not open nor close (except for the last accordionPanel).
Noteworthy, if I put two or more accordionPanels by hand (without JSF loops) they works.
Also, I've checked the requests the browser sends when I try to open/close a tab. The requests I intercept are like:
<?xml version="1.0" encoding="utf-8"?><partial-response><changes><update id="mainForm:tabView"><![CDATA[
// something that always use the id of the HTML tag of the _last_ accordionPanel
</update></changes></partial-response>
How can I put an <accordionPanel> inside an <ui:repeat> or <c:forEach> so that I can still switch the accordionPanel's tab?
Its the problem with the widgetVar when you put p:accordion in ui:repeat, it will generate Accordion Panel components with different/dynamic Ids but not with different/dynamic widgetVar when you explicitly specify widgetVar like you're doing in your code.
Which is basically name to Javascript Object to access the Client side Api functions of p:accordion.
So If you are not using that widgetVar of p:accordions anywhere, Remove widgetVar attribute, then the widgetVar will be generated dynamically.
If you still want to use widgetVar, give dynamic name yourself, for example:
widgetVar="accordion_#{o.data_one}"
Note: I tried the above strategy with only on ui:repeat.
Using:Primefaces 3.5 and JSF 2.1.13 and its working for me.

Primefaces blockUI to block a DataTable doesn't work when the DataTable is updated via AJAX [duplicate]

I am trying to create a datatable that displays a blockUI whenever it is busy, and I have been mostly successful. It now grays out and shows "Loading..." whenever I click either of two commandButtons, sort the datatable by clicking on a header, or page through the datatable. You can see the code for it below.
The problem is that after I have used one of the commandButtons (which runs an ajax update on the blocked element), subsequent actions do not trigger the blockUI (until I refresh the page). For example:
Load page
Click a datatable header - blockUI appears until table is finished sorting
Click one of the datatable page navigation buttons - blockUI appears until the page is loaded
Click one of the commandButtons - blockUI appears until the button's actionListener has finished
Click a datatable header - table sorts, but blockUI does not appear.
Click one of the datatable page navigation buttons - page loads, but blockUI does not appear
Click one of the commandButtons - actionListener runs and table updates, but blockUI does not appear
Reload the page - everything works properly again
Changing the commandButtons' update="" attribute to ajax="false" causes the sorting/paging to always display the blockUI, but the commandButtons to never display the blockUI.
Any ideas?
<div class="buttonDiv">
<p:commandButton ... update="resultsPanel" id="submitButton" ... />
...
<p:commandButton ... update="resultsPanel" id="resetScenarioButton" ... />
</div>
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
</p:panel>
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
The trigger attribute binds jQuery listeners on the specified elements. However if you update an element the binding gets lost. I don't know if it works, but you could try moving the <p:blockUI inside the resultsPanel. I suspect that when you update the panel the blockUI gets updated too and thus re-binding the listener to the data table.
<p:panel header="Results Grid" id="resultsPanel">
...
<p:dataTable ... id="VAResults" ... >
...
</p:dataTable>
....
<p:blockUI block="resultsPanel" trigger="submitButton, resetScenarioButton, VAResults">
Loading...
</p:blockUI>
</p:panel>
I've had the same problem and kind of simillar scenario:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons">
<!-- content to be blocked -->
</p:outputPanel>
<p:blockUI block="buttons" widgetVar="blockMessageButtons"/>
The problem was that panel buttons was both updated by ajax, and blocked by blockUI. I had to divide it in two:
<p:dataTable>
....
<p:ajax event="rowSelect" update="buttons-content" global="false" onstart="blockMessageButtons.show();" oncomplete="blockMessageButtons.hide();"/>
</p:dataTable>
<p:outputPanel layout="block" id="buttons-container">
<p:outputPanel layout="block" id="buttons-content">
<!-- content to be blocked -->
</p:outputPanel>
</p:outputPanel>
<p:blockUI block="buttons-container" widgetVar="blockMessageButtons"/>
#siebz0r already provided the explanation why blockUI stops working when a component is updated.
I am using a one blockUI element in the template for all other pages and thus don't want to include more blockUI elements.
If the blockUI element is updated as well one does not need to move the blockUI inside the component that will be updated.
Here is an example:
<p:panel id="surroundingPanel">
...
<p:commandButton value="ButtonName" styleClass="blockUi"
action="actionToBeExecuted" update=":surroundingPanel :blockUiBinding" />
</p:panel>
<p:outputPanel id="blockUiBinding">
<p:blockUI block=":elementToBeBlocked" trigger="#(.blockUi)">
Loading ...
</p:blockUI>
</p:outputPanel>
The element blockUiBinding can be located anywhere, as long as it can be updated. It is wrapping the blockUI element, because blockUI generates at least two different divs. So when the wrapping element is updated also the blockUI will be updated.

Dynamic Primefaces:tabView doesn't update

I'm using Primefaces 3.4 (also tried 3.3) and Mojarra 2.1.7. But I have a problem updating my dynamical tabs within a p:tabView.
I have 2 buttons which should add an additional tab. The first button is outside the p:tabView. When clicking this button, the backing bean is called, the p:tabView is updated, and the new tab is shown. But when I click the second button, which is inside a tab of that tabView, the backing bean is called, but the tabView is NOT updated.
This lack of updating occures only in dynamic tabs. When I modify the given example to have only one tab, and displaying a value which changes when clicking the buttons, the tabView is updated by both buttons, and the new Value is shown. So it is an problem only occuring in dynamic tabs.
Here is my code.
<f:view contentType="text/html">
<h:form>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update=":ApplicationTab"/>
</h:form>
<p:tabView id="ApplicationTab" cache="false" dynamic="false" var="tab" value="#{idTestBean.tabList}">
<p:tab title="tab" closable="false" >
<p:panel>
<h:form>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update=":ApplicationTab"/>
</h:form>
#{idTestBean.count}
</p:panel>
</p:tab>
</p:tabView>
</f:view>
The different tabs contains separate forms that needed to be submitted separate. therefore I had the approach of more than one form.
Well this must do the trick:
<f:view contentType="text/html">
<h:form>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update="#form"/>
<p:tabView id="ApplicationTab" cache="false" dynamic="false" var="tab" value="#{idTestBean.tabList}">
<p:tab title="tab" closable="false" >
<p:panel>
<p:commandButton value="press me" action="#{idTestBean.addTab}" update="#form"/>
#{idTestBean.count}
</p:panel>
</p:tab>
</p:tabView>
</h:form>
</f:view>
Today i did the same problem too, I had a dynamic tabview, and inside tabs, there're some panels that needed to be updated when tab changes, so what i did was, i added the p:ajax on event TabChange, and in the update attribute, i added the form id and tabviewId like this:
:formID:tabViewID
and it worked at last.
Just so you know.

ui:repeat inside composition not printing values

I am new to jsf. I have the bellow code. When I place ui:repeat inside rich:toolbar it prints the data. But when I place it after the toolbargroup inside composition tag it doesn't print anything. I have a toolbar and I want to show ui:repeat data bellow that toolbar. If I place it in toolbar it shows the data but inside the toolbar not bellow it. How can I place it bellow the toolbar?
Thanks.
Update: I found out the problem. The ui:repeat tag is showing up bellow the toolbar. So how can I add position to ui:repeat?
enter code here<h:body>
<ui:composition> <h:panelGroup layout="block">
<a4j:region>
<rich:toolbar id="header-toolbar" height="30px" itemSeparator="line">
<rich:toolbarGroup location="right" rendered="#{not empty searchType}">
<rich:menuItem
label="search"
mode="ajax"
execute="#this"
oncomplete="#{rich:component(searchFormModalPanel)}.show();"
status="status"/>
</rich:toolbarGroup> </rich:toolbarGroup>
</rich:toolbar>
</a4j:region> //Bellow doesn't show up! <ui:repeat value="#{breadCrumbMB.crumbs}" var="crumb" varStatus="crumStatus">
#{breadCrumbMB.incIndex()}
<h:outputLink value="#{crumb}">
<h:outputText value="#{breadCrumbMB.title(crumb.toString())}" rendered="${breadCrumbMB.lastLink()=='false'}"/></h:outputLink> >
<h:outputText value="#{breadCrumbMB.title(crumb.toString())}" rendered="${breadCrumbMB.lastLink()=='true'}"/>
</ui:repeat> </ui:composition>
</h:body>
Try to include ui:repeat inside a4j:region, if it doesn't work then use a4j:repeat

Resources