Execute some code when a value from a p:selectOneMenu is selected - ajax

I am doing a password editor. The password can be entered in two ways: manually entering the values for password and confirmation or by selecting some already generated password.
To use the generated password, a new value from the select box must be chosen. The change triggers the filling of the password/confirmation fields(psw1 and psw2) with the value from the selected value.
<p:selectOneMenu value="#{password.selectedPassword}" >
<f:selectItems value="#{password.passwords}" var="val"
itemLabel="#{val}" itemValue="#{val}" />
<p:ajax update="psw1, psw2" listener="#{password.passwordChanged}"/>
</p:selectOneMenu>
I need to implement the filling of password fields also when the the same value is selected. How can I implement this? One way is to add an extra value, a default empty value.

You can't trigger a change event if the value has not changed. Indeed, one way is to supply a default value as in "Please select" with a #{null} value or even with noSelectionOption="true" in flavor of an additional <f:selectItem>. This forces the enduser to actually change the value to a valid value.
E.g.
<p:selectOneMenu value="#{password.selectedPassword}" >
<f:selectItem itemValue="#{null}" itemLabel="--select--" />
<f:selectItems value="#{password.passwords}" var="val"
itemLabel="#{val}" itemValue="#{val}" />
<p:ajax update="psw1, psw2" listener="#{password.passwordChanged}"/>
</p:selectOneMenu>
Another way is to use <p:selectOneListbox> instead, which is maybe better if you don't have many items.
<p:selectOneListbox value="#{password.selectedPassword}" >
<f:selectItems value="#{password.passwords}" var="val"
itemLabel="#{val}" itemValue="#{val}" />
<p:ajax update="psw1, psw2" listener="#{password.passwordChanged}"/>
</p:selectOneListbox>

Related

Performing data binding during ajax-request

I have the following markup:
<rich:panel id="selectorPanel">
<h:inputText value="#{myBean.field1}" />
<h:inputText value="#{myBean.field2}" />
<h:inputText value="#{myBean.field3}" />
<!-- and so forth -->
<h:selectOneMenu id="selector" value="#{myBean.selected}">
<a4j:ajax event="change" listener="#{myBean.doUpdateValues()}" render="selectorPanel" />
<f:selectItem itemLabel="#{msgs['bundle.addFilter']}" itemValue="#{null}" value="#{null}"/>
<f:selectItems value="#{myBean.filters}" />
</h:selectOneMenu>
</rich:panel>
The problem: when I change the value of the selectOneMenu the selectorPanel is being rerendered, therefore the values of the inputTexts are being refreshed and set to the myBean's properties value.
But I need to set values entered by user on the web-page to the corresponding bean's properties before rerendering.
Is it possible? How?
Why to do need to execute all? the #form should be enough or even list of inputs ids.
I've found the solution just now and we can actually use execute attribute as follows:
execute="#all"
It works for me.

Passing selected value in h:selectOneMenu to h:link

I want to pass the selected value of a h:selectOneMenu to h:link as a view param. The selected value is always empty.
Here's my code:
<h:selectOneMenu value="#{countryLclController.selectedCountry}">
<f:selectItem itemLabel="#{text['select_country']}" itemValue=""/>
<f:selectItems value="#{countryLclController.getCountries(request.locale.language)}" var="country" itemLabel="#{country.countryName}" itemValue="#{country.countryName}"/>
<f:ajax render="visa"/>
</h:selectOneMenu>
<h:link id="visa" outcome="Visa_Guide" includeViewParams="true" value="#{text['visa_guide']}">
<f:param name="country" value="#{countryLclController.selectedCountry}"/>
</h:link>
the term country is added to outcome since I have the f:viewParam in Visa_Guide.xhtml but country is empty; so the outcome becomes: Visa_Guide?country=
country is a String field with getter and setter methods in countryLclController managed bean.
I had forgotten to put my <h:selectonemenu> inside <h:form>.

Make components required depending on selectOneRadio value

JSF2, PrimeFaces 4.0
There is a form with multiple inputFields and a selectOneRadio (and some action button at the end):
<p:outputLabel for="R1" value="R1" />
<p:selectOneRadio id="R1" value="#{bean.r1Value}" required="#{bean.r1Condition}" converter="SomeConverter" >
<f:selectItems value="#{bean.r1PossibleValues}" var="r1Var" itemValue="#{r1Var}" itemLabel="#{r1Var}" />
<p:ajax process="#form" update="#form" />
</p:selectOneRadio>
<p:outputLabel for="F1" value="F1" />
<p:inputText id="F1" value="#{bean.value1}" required="#{bean.condition1}" />
<p:outputLabel for="F2" value="F2" />
<p:inputText id="F2" value="#{bean.value2}" required="#{bean.condition2}" />
If user selects first value of selectOneRadio - field F1 should be required, if second - field F2.
Methods bean.conditionX check the value of radio (and one more condition) and return true/false.
If I select first radio value, field F1 changes to required. Then, if I change my mind select second radio value - I get validation error (that field F1 is required).
If I change:
<p:ajax process="#form" update="#form" />
to:
<p:ajax update="#form" />
and then:
- enter some values into F1 and F2,
- select a value in radio
-> the values entered into fields F1, F2 disappear.
How can I change set of required fields on selectOneRadio change without losing data and without premature validation errors?
Remove the process attribute to <p:ajax> in order to make selectOneRadio trigger a partial Ajax request, that only submits the selectOneRadio itself. Fill the update attribute with a space-separated list of the components you need to update, excluding the inputText components, because you want to preserve their values, and their required status will be evaluated only when submitting the entire form. Finally, use the listener property of <p:ajax> for invoking a server method that updates the conditions that make the inputText components required:
<p:selectOneRadio id="R1" value="#{bean.r1Value}" required="#{bean.r1Condition}" converter="SomeConverter" >
<f:selectItems value="#{bean.r1PossibleValues}" var="r1Var" itemValue="#{r1Var}" itemLabel="#{r1Var}" />
<p:ajax listener="#{bean.myListener()}" update="label1 label2" />
</p:selectOneRadio>
<p:outputLabel id="label1" for="F1" value="#{myBean.condition1 ? '*' : ''}" />
<p:inputText id="F1" value="#{bean.value1}" required="#{bean.condition1}" />
<p:outputLabel id="label2" for="F2" value="#{myBean.condition2 ? '*' : ''}" />
Where
public void myListener() {
// changes the values of the required conditions based on selected value
condition1 = true;
condition2 = false;
}

editable selectOneMemu appears blank instead of first default string value

I have this editable selectOneMenu which correctly resets/repopulates on its previous selectOneMenu change. but it always show blank instead of the first value - 'Please select/Enter statement'
<p:selectOneMenu id="statement" style="width:300px;" value="#{mgBean.statement}"
editable="true" panelStyle="width:200px;">
>
<f:selectItem itemLabel="Please select/Enter statement" itemValue="" />
<f:selectItems value="#{mgBean.statementList}" var="stmt" itemLabel="#{stmt.defaultStatement}" itemValue="#{stmt.defaultStatementValue}" />
</p:selectOneMenu>
You should use the noSelectionOption attribute
Like this
<f:selectItem itemLabel="Please select/Enter statement" noSelectionOption="true"/>
Try setting the attribute label="Please select/Enter statement" for the p:selectOneMenu tag.

How to let validation depend on the pressed button?

I have created form and I want to show previous existing items on a table while a new one is creating. I'd like to show matching items as form is filling up. But when I try to filter the list without having the form completed, the validation messages appear and the table doesn't get updated.
Don't know if it's possible, but what I want to do something like this:
<h:form id="form">
<h:outputText value="Name: "/>
<p:inputText value="#{itemsBean.name}" id="name" required="true"/>
<br/>
<h:outputText value="Description: "/>
<p:inputText value="#{itemsBean.description}" id="description" required="true"/>
<p:commandButton value="Save" update="form" actionListener="#{itemsBean.save}"/> //validate and save
<p:commandButton value="Filter" update="form" actionListener="#{itemsBean.updateItemsList}"/> //don't validate, and update the table.
<p:dataTable id="list" value="#{itemsBean.itemsList}" var="item">
<p:column>
<h:outputText value="#{item.name}"/>
</p:column>
<p:column>
<h:outputText value="#{item.description}"/>
</p:column>
</p:dataTable>
</h:form>
I'm very new to JSF.
I understand that you want to filter based on the name input field. The <p:commandButton> sends by default an ajax request and has a process attribute wherein you can specify which components you'd like to process during the submit. In your particular case, you should then process only the name input field and the current button (so that its action will be invoked).
<p:commandButton process="#this name" ... />
The process attribute can take a space separated collection of (relative) client IDs of the components, wherein #this refers to the current component. It defaults in case of <p:commandButton> to #form (which covers all input fields of the current form and the pressed button), that's why they were all been validated in your initial attempt. In the above example, all other input fields won't be processed (and thus also not validated).
If you however intend to skip the required validation for all fields whenever the button in question is been pressed, so that you can eventually process multiple fields which doesn't necessarily need to be all filled in, then you need to make the required="true" a conditional instead which checks if the button is been pressed or not. For example, let it evaluate true only when the save button has been pressed:
<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:inputText ... required="#{not empty param[save.clientId]}" />
...
<p:commandButton binding="#{save}" value="Save" ... />
This way it won't be validated as required="true" when a different button is pressed. The trick in the above example is that the name of the pressed button (which is essentially the client ID) is been sent as request parameter and that you could just check its presence in the request parameter map.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
I Have tested this with non-ajax submits:
<p:inputText ... required="#{not empty param.includeInSave1}" />
...
<p:inputText ... required="true" />
...
<p:commandButton value="Save1" ajax="false">
<f:param name="includeInSave1" value="true" />
</p:commandButton>
<p:commandButton value="Save2" ajax="false" />
The first input is required validated only on Save1 button submit.
Additionally to the BalusC answer (very useful and complete) I want to add that when you use a <h:commandButton /> it will validate (required, custom validations) all the fields in the <h:form /> where the command button is located, therefore when you need to use more than one command button you could consider that it is a good practice to use different <h:form /> to different responsibilities to avoid unexpected behavior in submit actions of the command buttons.
It is well explained in a BalusC answer: Multiple h:form in a JSF Page
If your form has validations and you do not update the <h:form /> or you do not show messages, you could get a headache thinking that the <h:commandButton /> is not firing your action, but likely is a validation problem that has not been shown.
Change your filter commandbutton like this to ignore validation:
<p:commandButton value="Filter" update="list" actionListener="#{itemsBean.updateItemsList}" process="#this"/>
EDIT:
The related post on SO, I think this will solve your issue too
JSF 2.0: How to skip JSR-303 bean validation?

Resources