Primefaces input text inside select many menu - jsf

I need to make a selectManyMenu with spinner or input text inside, to be able to get the following result:
Here after my code:
<p:selectManyMenu id="opt-list" value="#{myBean.selectedOptionList}"
converter="optConverter" filter="true"
filterMatchMode="contains" showCheckbox="true"
var="selectedOpt">
<f:selectItems value="#{myBean.optionList}" var="opt" itemLabel="#{opt.name}" itemValue="#{opt}" />
<p:column>
<h:outputText value="#{selectedOpt.name}" />
</p:column>
<p:column>
<p:spinner value="#{selectedOpt.nb}" size="1" />
</p:column>
</p:selectManyMenu>
The idea is that the user should be able to select an option and specify a number.
but during execution, i get the following warning/error:
WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] .....\.....\my-page.xhtml #65,84 value="#{selectedOpt.nb}": JBWEB006016: Target Unreachable, identifier ''selectedOpt'' resolved to null: javax.el.PropertyNotFoundException: ....\......\my-page.xhtml #65,84 value="#{selectedOpt.nb}": JBWEB006016: Target Unreachable, identifier ''selectedOpt'' resolved to null

You can solve your "label" problems by replacing <f:selectItem>'s itemValue by #{selectedOpt} instead of #{opt}
<p:selectManyMenu id="opt-list" value="#{myBean.selectedOptionList}"
converter="optConverter" filter="true"
filterMatchMode="contains" showCheckbox="true"
var="selectedOpt">
<f:selectItems value="#{myBean.optionList}" var="opt" itemLabel="#{opt.name}" itemValue="#{selectedOpt}" />
<p:column>
<h:outputText value="#{selectedOpt.name}" />
</p:column>
<p:column>
<p:spinner value="#{selectedOpt.nb}" size="1" />
</p:column>
Keep in mind that will not solve your spinner problem. See : http://forum.primefaces.org/viewtopic.php?f=3&t=16964

Related

How to update a field using a converter and ajax in JSF

I basically have two input field I display if the value is currently empty or null. if it is not, I display an outputText. Those two values are currency values stored in a Long object and I use a converter to display the data properly (I can't use PrimeFaces' inputNumber since I am using PrimeFaces 5.3). My problem is the following :
<c:set var="edtVal1" value="#{bean.val1 ne null and bean.val1 ne 0}" scope="request" />
<c:set var="edtVal2" value="#{bean.val2 ne null and bean.val2 ne 0}" scope="request" />
<p:panelGrid>
<p:row>
<p:column colspan="2">
<p:messages id="mainMessages" globalOnly="false" autoUpdate="true" showDetail="true" />
</p:column>
</p:row>
<!-- [...] -->
<p:row>
<p:column styleClass="col-quarter col-label2">
<h:outputText value="value 1" />
</p:column>
<p:column styleClass="col-quarter col-value2" rendered="#{edtVal1}">
<h:outputText id="val1Output" value="#{bean.val1}" converter="myConverter" />
</p:column>
<p:column styleClass="col-quarter" rendered="#{not edtVal1}">
<p:inputText id="val1Input" value="#{bean.val1}" converter="myConverter">
<p:ajax update="mainMessages val1Input" event="change" />
</p:inputText>
</p:column>
</p:row>
<p:row>
<p:column styleClass="col-quarter col-label2">
<h:outputText value="value 2" />
</p:column>
<p:column styleClass="col-quarter col-value2" rendered="#{edtVal2}">
<h:outputText id="val1Output" value="#{bean.val2}" converter="myConverter" />
</p:column>
<p:column styleClass="col-quarter" rendered="#{not edtVal2}">
<p:inputText id="val1Input" value="#{bean.val2}" converter="myConverter">
<p:ajax update="mainMessages val1Input" event="change" />
</p:inputText>
</p:column>
</p:row>
</p:panelGrid>
when I put it like this, the messages thrown by the converter are displayed, but none of the fields are updated. However, if I use the same boolean variable for both input/output options (changed the variable used in rendered attribute of the 1rst data row to use edtVal2 in both) like so :
<p:row>
<p:column styleClass="col-quarter col-label2">
<h:outputText value="value 1" />
</p:column>
<p:column styleClass="col-quarter col-value2" rendered="#{edtVal1}">
<h:outputText id="val1Output" value="#{bean.val1}" converter="myConverter" />
</p:column>
<p:column styleClass="col-quarter" rendered="#{not edtVal1}">
<p:inputText id="val1Input" value="#{bean.val1}" converter="myConverter">
<p:ajax update="mainMessages val1Input" event="change" />
</p:inputText>
</p:column>
</p:row>
The first field updates successfully and the second once still does not work.
Using a converter to display a formated data is a workaround I already done and it works just as expected and I use the same converter than before. But this time, I don't understand why it's not working.
The converter is important to reproduce the issue, but any custom converter seems to do the job.
Any other solutions are still welcome on this post, but I managed to find a working solution :
when I changed the rendered attribute to a constant string, the issue was absent. So I think the problem comes from a misunderstanding of <c:set>.
My solution was to use a the bean as a controller. I changed the variables from the xhtml file to properties in the controller and now everything works fine. So I removed all <c:set> from my xhtml and use a proper MVC pattern on that page now.
Note :
For those who don't know what MVC is : it's a neat architectural pattern that divides clearly the user interface and manipulated data. Learn more on wikipedia.

Group radio buttons inside a datatable - Primefaces

I want to create webpage having table with radio buttons in primefaces using datatable component like below.
I found one solution to implement custom component as mentioned in http://www.javaworld.com/article/2077687/enterprise-java/group-radio-buttons-inside-a-jsf-datatable-component.html for JSF.
But it is time taking and a lot of code.
Primefaces provides the custom layout for selectOneRadio. I implemented the table using the custom layout example of selectOneRadio as below. In this first column has width zero which contains the radio button.
<p:dataTable id ="employeeTable" rowIndexVar="rowId" var ="emp" value ="#{employeeList.employeeData}" widgetvar ="employeeTable" resizableColumns="true">
<p:column headerText="" style="width:0px;">
<p:selectOneRadio id="action" value="#{emp.status}" layout ="custom">
<f:selectItem itemLabel="Yes" itemValue="Yes" />
<f:selectItem itemLabel="No" itemValue="No" />
<f:selectItem itemLabel="Amendment" itemValue="Amendment" />
<f:selectItem itemLabel="KIV" itemValue="KIV" />
</p:selectOneRadio>
</p:column>
<p:column headerText="Personnel No">
<h:outputText value="#{emp.perNum}" />
</p:column>
<p:column headerText="Empl Name">
<h:outputText value="#{emp.name}" />
</p:column>
<p:column headerText="Yes">
<p:radioButton for="action" itemIndex="0" />
</p:column>
<p:column headerText="No">
<p:radioButton for="action" itemIndex="1" />
</p:column>
<p:column headerText="Amendment">
<p:radioButton for="action" itemIndex="2" />
</p:column>
<p:column headerText="KIV">
<p:radioButton for="action" itemIndex="3" />
</p:column>
</datatable>
Use p:selectOneRadio outside of your dataTable with layout attribute set to "custom". Fill this radio with f:selectItems same as data provided to dataTable via "value" parameter.
<p:selectOneRadio id="customRadio"
value="#{beanMB.selectedItem}"
layout="custom">
<f:selectItems value="#{beanMB.tableItems}"
var="item"
itemValue="#{item.radioValue}"
itemLabel="#{item.radioLabel}"/>
</p:selectOneRadio>
In dataTable column use p:radioButton with itemIndex matching current rowIndex.
<p:dataTable var="item"
rowIndexVar="rowIndex"
value="#{beanMB.tableItems}">
<p:column headerText="Choice">
<p:radioButton for="#form:customRadio"
itemIndex="#{rowIndex}"
rendered="#{item.radioRendered}"/>
</p:column>
</p:dataTable>

List is empty after submit

if i want to show the selected elements in the datalist when i click on 'übernehmen' commandbutton, the List from the ManagedBean is empty, but i dont know why. My Converter works fine. No error from my console is show. All elements are in the same form.
Thanks
<p:selectManyMenu id="standard"
value="#{hauptBean.standardSelektion}" converter="konverter"
var="t" filter="true" filterMatchMode="contains"
showCheckbox="true">
<f:selectItems value="#{hauptBean.vorbelegt}" var="risk" itemLabel="#{risk.risikobereich}" itemValue="#{risk}" />
<p:column>
<h:outputText value="#{t.risikobereich}" />
</p:column>
</p:selectManyMenu>
<p:commandButton value="übernehmen" update="ge" icon="ui-icon-check"/>
<h:outputText value="gewählt" styleClass="fetterText" />
<h:panelGroup />
<h:panelGroup id="ge">
<p:dataList value="#{hauptBean.standardSelektion}" var="t">
<h:outputText value="#{t}" />
</p:dataList>
</h:panelGroup>
By default, when you click the commandButton, the p:selectManyMenu will not be processed and update its selected value to the ManagedBean. To change this behaviour you can add attribute process="standard" to your p:commandButton

Clear input validation error from backing bean

I have a dataTable with cell editor. And I want to only have some (selected) rows editable. And when the user uses the cell editor, I want to perform input validation immediately after the value is set.
So I use cellEdit event in the data table and from the event handler I trigger validation failure.
<p:ajax event="cellEdit" listener="#{bean.onEditCell}" update=":formId:propertySelect" />
This works like a charm. If the user enters an invalid value, the editor doesn't close and the error message is displayed.
What doesn't work is the user inputting a valid value afterwards. The cellEdit event does not trigger again since the form is in "input validation failure state".
I have lost a day trying to resolve that:
I want to reset input validation when a user sets a new value - resetInput only works from buttons. I couldn't get it working on value change.
I didn't find how to reset the field from JavaScript directly.
if I combine "onchange" event and "remoteCommand" a handler is called in the backing bean, but then I cannot find the UIInput to call resetValue() on it.
<p:dataTable id="propertySelect" value="#{bean.propertyValues}" var="prop"
editable="true" editMode="cell" scrollable="true"
scrollHeight="200" widgetVar="propSelectTable"
filteredValue="#{bean.filteredPVs}">
<p:ajax event="cellEdit" listener="#{bean.onEditCell}" update=":#{formId}:propertySelect" />
<p:ajax event="filter" oncomplete="updateToggle()" />
<p:column id="rowSelection">
<f:facet name="header">
<p:selectBooleanCheckbox id="toggleAll" value="#{bean.selectAllRows}">
<p:ajax listener="#{bean.handleToggleAll}" update=":#{formId}:propertySelect" />
</p:selectBooleanCheckbox>
</f:facet>
<p:selectBooleanCheckbox value="#{prop.selected}">
<p:ajax update=":#{formId}:propertySelect" oncomplete="updateToggle()" listener="#{bean.rowSelectListener(prop)}"/>
</p:selectBooleanCheckbox>
</p:column>
<p:column headerText="Property">
<h:outputText value="#{prop.name}" />
</p:column>
<p:column headerText="Description">
<h:outputText value="#{prop.description}" />
</p:column>
<p:column headerText="Value">
<p:cellEditor rendered="#{prop.selected}">
<f:facet name="output">
<h:outputText value="#{bean.displayPV(prop)}" />
</f:facet>
<f:facet name="input">
<p:inputText id="pvSimple" value="#{prop.uiValue}" rendered="#{prop.propertyValueUIElement eq 'INPUT'}" />
<p:inputTextarea id="pvArea" rows="7" value="#{prop.uiValue}"
rendered="#{prop.propertyValueUIElement eq 'TEXT_AREA'}" />
<p:selectOneMenu id="pvEnum" value="#{prop.uiValue}"
rendered="#{prop.propertyValueUIElement eq 'SELECT_ONE_MENU'}">
<f:selectItem itemLabel="<Select value>" itemValue="" />
<f:selectItems value="#{prop.enumOptions}" var="enum" itemLabel="#{enum}" itemValue="#{enum}" />
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
<h:outputText value="-" rendered="#{!prop.selected}" />
</p:column>
I am looking for a way to clear input validation errors on the input fields with the ids "pvSimple", "pvArea" or "pvEnum".

Multiple error messages for one input field

I am creating a form using facelets. One input field looks like this:
<p:inputText id="initials" value="#{dilution.initials}" />
dilution is a entity bean and the initials field has two validation constraints set on it. One size constraint and one regex pattern constraint. My problem is getting error messages for both constraints to display next to the input field. Using the <h:message> only display one of the messages and using <h:messages> displays all input fields error messages or nothing (when I tried setting <h:messages for="initials" autoUpdate="true" />).
Is there any simple way to do this?
The full form:
<h:form id="addDilForm">
<p:panel>
<p:messages autoUpdate="true" showDetail="TRUE" />
<p:panelGrid>
<f:facet name="header" >
<p:row><p:column colspan="3">Ny spädningsfaktor</p:column></p:row>
</f:facet>
<p:row>
<p:column colspan="1">
<p:outputLabel for="sampT">Provtyp</p:outputLabel>
</p:column>
<p:column>
<p:selectOneMenu id="sampT" required="true" value="#{dilution.dilution.sampleType.ID}" >
<f:selectItem itemLabel="-" itemValue="" />
<f:selectItems value="#{SampleTypeController.samples}" var="samp" itemLabel="#{samp.name}" itemValue="#{samp.ID}" />
</p:selectOneMenu>
</p:column>
<p:column>
<p:message for="sampT" />
</p:column>
</p:row>
<p:row>
<p:column>
<p:outputLabel for="initials">Initialer</p:outputLabel>
</p:column>
<p:column >
<p:inputText id="initials" value="#{dilution.initials}" />
</p:column>
<p:column>
<p:message for="initials" />
</p:column>
</p:row>
<f:facet name="footer">
<p:row>
<p:column colspan="3">
<p:commandButton value="Save" action="#{dilution.save()}" update="addDilForm" icon="ui-icon-check" />
</p:column>
</p:row>
</f:facet>
</p:panelGrid>
</p:panel>
</h:form>
Using the <h:message> only display one of the messages
Just use <h:messages> with the plural "s" instead of <h:message> while keeping the for attribute.
<h:messages for="initials" />
The <p:messages> works the same way, only with a different UI.

Resources