Dynamically populate options in a selectOneMenu by <ui:repeat> - user-interface

I'm trying to populate some dropdown menus in primefaces with content depending on some choices from other selections in the GUI. This is a simplified example of what I'm trying to do:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core" >
<h:head>
<title>Test</title>
</h:head>
<h:body>
<h:form>
<c:set var="options" value="#{['1','2','3']}" />
<c:set var="currentValue" value="#{3}" />
<h:outputText value="${options}" />
<ui:repeat var="r" value="#{options}">
<h:outputText value="#{r}" />
</ui:repeat>
<c:set var="currentValue" value="#{currentValue}" />
<p:selectOneMenu id="selectValue"
value="${currentValue}"
class="pFieldSet_Template_Input200 r10">
<p:ajax event="change" />
<ui:repeat var="r" value="#{options}">
<f:selectItem itemLabel="Choice #{r} (20180101)" itemValue="#{r}" />
</ui:repeat>
</p:selectOneMenu>
</h:form>
</h:body>
</html>
When I visit the page it shows [1, 2, 3]123 and an empty selectOneMenu. I would have expected the selectOneMenu to contain the choices as well. The iteration obivously works in the above case so I don't know why it doesn't show the options in the menu. What am I doing wrong?

The <ui:repeat> is an UI component while <f:selectItem> is a taghandler (like JSTL). Taghandlers runs during view build time before UI components which runs during view render time. So at the moment the <ui:repeat> runs, there is no means of a <f:selectItem>.
A <c:forEach>, which is also a tag handler, would work:
<p:selectOneMenu id="selectValue"
value="${currentValue}"
class="pFieldSet_Template_Input200 r10">
<p:ajax event="change" />
<c:forEach items="#{options}" var="r">
<f:selectItem itemLabel="Choice #{r} (20180101)" itemValue="#{r}" />
</c:forEach>
</p:selectOneMenu>

Related

Primefaces 4.0: p:ajax partialSubmit inside compositeComponent

I'm trying to create a simple composite component based on JSF h:panelGroup:
filter.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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<composite:interface>
</composite:interface>
<composite:implementation>
<span>Расширенный фильтр</span>
<h:panelGroup id="#{cc.clientId}" class="filter"
style="background:white">
<composite:insertChildren></composite:insertChildren>
</h:panelGroup>
</composite:implementation>
and place a component that has to be partially submitted inside it.
<h:form id="issueFilterForm" prependId="false">
<c3:filter>
<h:panelGrid columns="2">
<h:outputText value="Продукт:" />
<p:selectOneMenu value="#{issueFilterBean.selectedProd}"
filter="true" filterMatchMode="contains">
<f:selectItem itemLabel="Выберите продукт" itemValue="-1" />
<f:selectItems value="#{issueFilterBean.products}" var="proj"
itemLabel="#{proj.name}" itemValue="#{proj.id}" />
<p:ajax event="change" process="#this" update="#form"
partialSubmit="true" />
</p:selectOneMenu>
</h:panelGrid>
</c3:filter>
</h:form>
The p:ajax call is fired, but no partial submission takes place. If i remove enclosing c3:filter, the submission works well.
How can I make this not skipping partial submission?

JSF PrimeFaces rowSelect for one datatable being called from another datatable

I have a Purchase datatable in a tab that lists all purchases. When you select a row, it is supposed to open a dialog that shows a list of the purchases for a particular customer. Also in the code there is a dialog for adding a new purchase in which a Customer can be selected from a list of previous customers in a datatable.
My problem is that when I select a row in the purchase table it is calling the rowSelect ajax event in the customer datatable (from inside the "New Purchase" dialog) instead of triggering it's own rowSelect event that opens the Purchase dialog.
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:o="http://omnifaces.org/ui"
xmlns:of="http://omnifaces.org/functions">
<h:head>
</h:head>
<h:body>
<p:growl id="messages" showDetail="true" />
<h:form id="newPurchaseCommandForm" enctype="multipart/form-data">
<p:commandButton value="New Purchase" process="#this"
onclick="PF('newPurchase').show()" id="btnNewPurchase">
<f:actionListener binding="#{purchasesDAO.init()}" />
</p:commandButton>
</h:form>
<p:tabView id="tabView" dynamic="true" cache="true" scrollable="true"
style="font-size:12px;">
<p:tab id="tba1" title="Purchase List">
<h:form id="purchaseTableForm" enctype="multipart/form-data">
<p:dataTable id="PurchaseTable" var="purchaseVar"
rowKey="#{purchaseVar.id}"
selection="#{purchasesDAO.selectedPurchaseRow}"
widgetVar="purchasesTableSearch"
filteredValue="#{purchasesDAO.filteredPurchaseRow}"
selectionMode="single" value="#{purchasesDAO.purchaseList}"
style="font-size:10px;">
<!-- Opens dialog -->
<p:ajax event="rowSelect" listener="#{purchasesDAO.onRowSelect}"
update=":messages" oncomplete="PF('showPurchase').show()" />
...
</p:dataTable>
</h:form>
</p:tab>
</p:tabView>
<p:dialog header="Purchase Details" widgetVar="showPurchase"
id="dialog" resizable="true" modal="false" hideEffect="explode"
height="500" width="990">
...
</p:dialog>
<p:dialog header="Add New Purchase" widgetVar="newPurchase"
id="dialogNewPurchase" resizable="true" modal="true" hideEffect="explode"
closeOnEscape="true" height="600" width="900">
<h:form id="form-newcasedialog" enctype="multipart/form-data">
<p:dataTable id="CustomerTable" var="customer"
rowKey="#{customer.id}"
selection="#{purchasesDAO.selectedCustomerRow}"
widgetVar="purchasesTableSearch"
filteredValue="#{purchasesDAO.filteredCustomerRow}"
selectionMode="single" value="#{purchasesDAO.customerList}"
style="font-size:10px;">
<!-- Opens dialog -->
<p:ajax event="rowSelect" listener="#{purchasesDAO.onRowSelect3}"
process="#this" />
...
</p:dataTable>
</h:form>
</p:dialog>
</h:body>
</html>
The solution for this took me ages to find but it turned out to be a simple one-line typo.
The widgetVar for both the Customer table and the Purchases table were the same:
<p:dataTable id="CustomerTable" var="customer"
rowKey="#{customer.id}"
selection="#{purchasesDAO.selectedCustomerRow}"
widgetVar="purchasesTableSearch"
filteredValue="#{purchasesDAO.filteredCustomerRow}"
selectionMode="single" value="#{purchasesDAO.customerList}"
style="font-size:10px;">
Should be:
<p:dataTable id="CustomerTable" var="customer"
rowKey="#{customer.id}"
selection="#{purchasesDAO.selectedCustomerRow}"
widgetVar="customerTableSearch"
filteredValue="#{purchasesDAO.filteredCustomerRow}"
selectionMode="single" value="#{purchasesDAO.customerList}"
style="font-size:10px;">
This was caused by copy/pasting code during development and missing the widgetVar line when updating the code. Changing the widgetVar in the customer datatable to be different to the purchase table solved the problem.

Action of command button not invoked if I use ajax

I have the following problem:
I have a button that should invoke a method, but the page should't get refreshed (I display a dialog based on bootstrap modal after clicking on the button and it vanishes otherwise). Therefore I use ajax to say that nothing should get rendered after clicking on the button.
I already used applied it before and it worked. But in the recent version of my code the method isn't invoked anymore as long as I use ajax. If I remove the ajax part the method is invoked as it should be, but the page gets refreshed and I don't want that.
My code:
<h:form>
<ui:fragment rendered="#{bean.condition1}">
<ui:include src="facelet1.xhtml" />
</ui:fragment>
<ui:fragment rendered="#{bean.condition2}">
<ui:include src="facelet2.xhtml" />
</ui:fragment>
<h:commandButton value="Save" action="bean.method">
<f:ajax execute="#form" render="#none"/>
</h:commandButton>
<h:form>
Before I had it like this and it worked:
<h:form>
<ui:include src="bean.faceletPath" />
<h:commandButton value="Save" action="bean.method">
<f:ajax execute="#form" render="#none"/>
</h:commandButton>
<h:form>
Thanks all,
/metalhamster
Edit:
facelet1.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<ui:composition>
<h:panelGrid columns="2">
<h:outputText value="Name:">
<h:inputText value="bean.name">
<h:outputText value="Value:">
<h:inputText value="bean.value">
</h:panelGrid>
</ui:composition>
</h:body>
</html>
facelet2.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<ui:composition>
<h:panelGrid columns="2">
<h:outputText value="Name:">
<h:inputText value="bean.name">
<h:outputText value="Text:">
<h:inputText value="bean.text">
</h:panelGrid>
</ui:composition>
</h:body>
</html>

Composite Component Binding is resolves to null

I am trying to bind a composite component to an ajax listener but the bind variable resolves to null. If I use the bind variable as part of the body, eg. #{bind} it does resolve properly. I assume it is a bug, but would like a second opinion before I report it. Thanks
page:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:composite="http://xmlns.jcp.org/jsf/composite"
xmlns:jstl="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:jfunc="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:jid1="http://mydomain.com/facelets">
<h:head></h:head>
<h:body>
<h:form id="commentBoxForm">
<jid1:confirmModal title="t" cssID="a" binding="#{bind}">
</jid1:confirmModal>
<h:commandLink value="click">
<f:ajax execute="#this" render="#form"
listener="#{bind.getFamily()}" />
</h:commandLink>
</h:form>
</h:body>
</html>
component:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:composite="http://xmlns.jcp.org/jsf/composite"
xmlns:jstl="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:jfunc="http://xmlns.jcp.org/jsp/jstl/functions"
xmlns:jid1="http://mydomain.com/facelets">
<composite:interface>
<composite:attribute name="cssID" required="true" />
<composite:attribute name="title" required="true" />
</composite:interface>
<composite:implementation>
<h:panelGroup >
......
</h:panelGroup>
</composite:implementation>
</ui:composition>
This is a bug. See here for details.
A composite component binding attribute will not work properly for Ajax calls.

<f:ajax> contains an unknown id when switching from PrimeFaces to jsf/html

this is my 1st question here :)
My code is as follows:
<?xml version="1.0"?>
<f:view 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"
>
<h:head />
<h:body>
<h:form id="filterForm">
<h:outputStylesheet library="css" name="main.css" />
<div id="filterPane">
<h:panelGroup rendered="#{not empty filters.categories}">
<div class="filter">
<div class="filterCategories" style="width: 100%;">
<h4>Kategorien</h4>
<p />
<h:selectManyCheckbox layout="pageDirection"
value="#{filters.selectedCategories}"
valueChangeListener="#{filters.categoryValueChanged}">
<f:selectItems value="#{filters.categories}" var="category"
itemLabel="#{category.displayName} (#{category.count})"
itemValue="#{category.name}" />
<f:ajax render="#form" />
</h:selectManyCheckbox>
</div>
</div>
</h:panelGroup>
</div>
</h:form>
</h:body>
</f:view>
I get the same error as some others before me here #stackoverflow - but none of the suggested solutions worked for me.:
<f:ajax> contains an unknown id 'A5539:filterForm:j_idt9' - cannot locate it in the context of the component j_idt9
Before my switch from <p:selectManyCheckbox to <h:selectManyCheckbox the code was working fine.
We need to change to <h:selectedManyCheckbox, because the PrimeFaces variant is not selectable for a non-JavaScript user. I need the form <h:form id="filterForm"> to be re-rendered as a consequence of my AJaX request via the <f:ajax> element.
Beside the initial <f:ajax render="#form" /> I unsuccessfully tried to reference the <h:form id="filterForm"> element with the following variants:
<f:ajax render=":filterForm" />
<f:ajax render=":#{component.parent.parent}" />
I also tried some more stupid ones.
Any hint, anybody!? :)

Resources