primefaces binding , required attribute for multiSelectListbox not triggred - jsf

I want to create a JSF application. In the application the user will have two drop downs.
If a user selects the country Mexico / value 3 from the first drop down then he is required to choose the option Cancun / value 6 from the multiselect
I have added the binding , required attribute for multiSelectListbox but they are not triggered when the drop down is selected
<h:form>
<p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" />
<p:panel header="Tranfer Destination" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px" required="true" binding="#{country}">
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:multiSelectListbox id="city" value="#{dropdownView.city}" style="width:150px" required="#{not empty param[country.6]}">
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItem itemLabel="New York" itemValue="1"> </f:selectItem>
<f:selectItem itemLabel="Chicago" itemValue="2"> </f:selectItem>
<f:selectItem itemLabel="Seattle" itemValue="3"> </f:selectItem>
<f:selectItem itemLabel="Toronto" itemValue="4"> </f:selectItem>
<f:selectItem itemLabel="Ontario" itemValue="5"> </f:selectItem>
<f:selectItem itemLabel="Cancun" itemValue="6"> </f:selectItem>
<f:selectItem itemLabel="Tijuana" itemValue="7"> </f:selectItem>
</p:multiSelectListbox>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit" update="msgs" action="#{dropdownView.displayLocation}" icon="pi pi-check" />
</p:panel>
</h:form>
The option Cancun / value 6 is required from the second drop down only If the user selects the country Mexico / value 3 from the first drop down

After selecting first drop-down, you need to update <p:multiSelectListbox id="city"/>.
<p:selectOneMenu id="country"
value="#{dropdownView.country}"
style="width:150px"
required="true"
binding="#{country}">
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
<p:ajax update="city"/>
</p:selectOneMenu>

Related

Make a multiSelect drop downvalue required based in the input of previous p:selectOneMenu value

I want to create a JSF application. In the application the user will have two drop downs.
If a user selects the country Mexico / value 3 from the first drop down then he is required to choose the option Cancun / value 6 from the multiselect
How this can be implemented?
<h:form>
<p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" />
<p:panel header="Tranfer Destination" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px">
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:multiSelectListbox id="city" value="#{dropdownView.city}" style="width:150px">
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItem itemLabel="New York" itemValue="1"> </f:selectItem>
<f:selectItem itemLabel="Chicago" itemValue="2"> </f:selectItem>
<f:selectItem itemLabel="Seattle" itemValue="3"> </f:selectItem>
<f:selectItem itemLabel="Toronto" itemValue="4"> </f:selectItem>
<f:selectItem itemLabel="Ontario" itemValue="5"> </f:selectItem>
<f:selectItem itemLabel="Cancun" itemValue="6"> </f:selectItem>
<f:selectItem itemLabel="Tijuana" itemValue="7"> </f:selectItem>
</p:multiSelectListbox>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit" update="msgs" action="#{dropdownView.displayLocation}" icon="pi pi-check" />
</p:panel>
</h:form>
List of Countries are populated from the database
ID NAME
USA-C
Canada-N
Mexico-C
List of cities
New york (optional)
Chicago (optional)
Seattle (optional)
Toronto (optional)
Ontario (optional)
Cancun [required]
Tijuana (optional)
Here in the second drop down we are making sure that the option is selected/required item for selection
Update
I have made necessary changes as suggested but it does not work.
<h:form>
<p:growl id="msgs" showDetail="true" skipDetailIfEqualsSummary="true" />
<p:panel header="Tranfer Destination" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px" required="true" binding="#{country}">
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:multiSelectListbox id="city" value="#{dropdownView.city}" style="width:150px" required="#{not empty param[country.6]}">
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItem itemLabel="New York" itemValue="1"> </f:selectItem>
<f:selectItem itemLabel="Chicago" itemValue="2"> </f:selectItem>
<f:selectItem itemLabel="Seattle" itemValue="3">
</f:selectItem>
<f:selectItem itemLabel="Toronto" itemValue="4"> </f:selectItem>
<f:selectItem itemLabel="Ontario" itemValue="5"> </f:selectItem>
<f:selectItem itemLabel="Cancun" itemValue="6"> </f:selectItem>
<f:selectItem itemLabel="Tijuana" itemValue="7"> </f:selectItem>
</p:multiSelectListbox>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit" update="msgs" action="#{dropdownView.displayLocation}" icon="pi pi-check" />
</p:panel>
</h:form>
The the option Cancun / value 6 is required from the second drop down only If the user selects the country Mexico / value 3 from the first drop down

The listener for p:selectOneMenu working only partially

I have a simple JSF form which has three dropdowns,
here is the code:
<h:form>
<p:panel header="Select country" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{phaseOneController.country}" style="width:150px">
<p:ajax listener="#{phaseOneController.onCountryChange}" update="province" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.countries}" />
</p:selectOneMenu>
<p:outputLabel for="province" value="Province: " />
<p:selectOneMenu id="province" value="#{phaseOneController.province}" style="width:150px">
<p:ajax listener="#{phaseOneController.onProvinceChange}" update="city" />
<f:selectItem itemLabel="Select Province" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.provinces}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:selectOneMenu id="city" value="#{phaseOneController.city}" style="width:150px">
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.cities}" />
</p:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Select" actionListener="#{phaseOneController.submit}" icon="ui-icon-check">
</p:commandButton>
</p:panel>
</h:form>
Now when I select a country, the onCountryChange gets called but when I update the province, the onProvinceChange doesn't get called at all!! It is surprising how one would work and other wouldn't
Here is the piece of code from the controller:
public void onCountryChange() {
System.out.println("On country change called");
}
public void onProvinceChange() {
System.out.println("On province change called");
}
For shortening the question I have replaced the code in the listener methods.
Answer: For anyone who faces this issue, using HashMap to populate the dropdown solved the issue. I am not sure why list is giving so much trouble.
Try to add event="change"...
<p:selectOneMenu id="country" value="#{phaseOneController.country}" style="width:150px">
<p:ajax event="change" listener="#{phaseOneController.onCountryChange}" update="subCategory" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.countries}" />
</p:selectOneMenu>
<p:selectOneMenu id="province" value="#{phaseOneController.province}" style="width:150px">
<p:ajax event="change" listener="#{phaseOneController.onProvinceChange}" update="city" />
<f:selectItem itemLabel="Select Province" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{phaseOneController.provinces}" />
</p:selectOneMenu>
Placing the bean in the view scope by #ViewScoped and Custom Converters to each f:selectItems should solve this problem.
Please See:
Cascading p:selectOneMenu model value not set

Display/hide h:panelGrid on the base of value selected in h:selectOneMenu

I want to display and hide a <h:panelGrid> on the basis of the value selected in <h:selectOneMenu>.
The code is:
<p:dialog id="logClassDlg" header="Log Class Teached" widgetVar="logClass" modal="true" >
<h:form>
<p:growl id="growl" showDetail="true" />
<h:panelGrid id="logClassPanelGrd1" columns="2">
<h:outputLabel for="class" value="Class: " />
<h:selectOneMenu id="class" value="#{logClassBean.classLog.classTitle}">
<f:selectItem itemValue="Reading" itemLabel="Reading" />
<f:selectItem itemValue="Memorization" itemLabel="Memorization" />
<f:selectItem itemValue="Translation" itemLabel="Translation" />
<f:selectItem itemValue="Language" itemLabel="Language" />
<f:selectItem itemValue="Grammer" itemLabel="Grammer" />
<f:ajax render="logClassPanelGrdBook" />
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid id="logClassPanelGrdBook" columns="2" rendered="#{(logClassBean.classLog.classTitle ne 'Language') and (logClassBean.classLog.classTitle ne 'Grammar')}">
<p:outputLabel value="Book" />
<h:selectOneMenu id="book" value="#{logClassBean.classLog.classStatus}">
<f:selectItem itemValue="first" itemLabel="first" />
<f:selectItem itemValue="second" itemLabel="second" />
<f:selectItem itemValue="third" itemLabel="third" />
<f:selectItem itemValue="fourth" itemLabel="fourth" />
<f:selectItem itemValue="fifth" itemLabel="fifth" />
</h:selectOneMenu>
</h:panelGrid>
As you can see I want to display the panel grid logClassPanelGrdBook only on when the selected values are not Language and Grammar i.e
rendered="#{(logClassBean.classLog.classTitle ne 'Language') and (logClassBean.classLog.classTitle ne 'Grammar')}"
But the panel grid is displayed irrespective of the values selected, it should hide when the other values (Reading, Memorization and Translation) are selected.
Any help/pointers would be appreciated. Thank you.
The part <f:ajax render="logClassPanelGrdBook" /> won't update and recheck the rendered function of the panelGrid this way. You will need to update its parent element instead.
For example, you can wrap it with <h:panelGroup>:
<h:panelGrid id="logClassPanelGrd1" columns="2">
<h:outputLabel for="class" value="Class: " />
<h:selectOneMenu id="class" value="#{logClassBean.classLog.classTitle}">
<f:selectItem itemValue="Reading" itemLabel="Reading" />
<f:selectItem itemValue="Memorization" itemLabel="Memorization" />
<f:selectItem itemValue="Translation" itemLabel="Translation" />
<f:selectItem itemValue="Language" itemLabel="Language" />
<f:selectItem itemValue="Grammar" itemLabel="Grammar" />
<f:ajax render="logClassPanelGrdBook" />
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup id="logClassPanelGrdBook">
<h:panelGrid columns="2" rendered="#{(logClassBean.classLog.classTitle ne 'Language') and (logClassBean.classLog.classTitle ne 'Grammar')}">
<p:outputLabel value="Book" />
<h:selectOneMenu id="book" value="#{logClassBean.classLog.classStatus}">
<f:selectItem itemValue="first" itemLabel="first" />
<f:selectItem itemValue="second" itemLabel="second" />
<f:selectItem itemValue="third" itemLabel="third" />
<f:selectItem itemValue="fourth" itemLabel="fourth" />
<f:selectItem itemValue="fifth" itemLabel="fifth" />
</h:selectOneMenu>
</h:panelGrid>
<h:panelGroup>
I also changed select item value from Grammer to Grammar because it didn't match the value in rendered attribute.
If this doesn't work, you should also check if bean value is properly set when you click <h:selectOneMenu>.

Conditionally render p:selectOneRadio based on checked values of p:selectManyCheckbox

I have two checkboxes.
<h:panelGrid id="userActivationGridcheckbox">
<p:selectManyCheckbox value="#{user.activationModecheckbox}" layout="pageDirection">
<f:selectItem itemLabel="Account Expiration(in days)" itemValue="byEmailcheckbox" />
<f:selectItem itemLabel="Reset User Password" itemValue="byAdmincheckbox" />
<f:ajax event="change" render="userActivationGridcheckbox" />
</p:selectManyCheckbox>
<h:panelGrid id="manualActivationGridcheckbox" rendered="#{user.manualActivationcheckbox}" columns="2">
<p:selectOneRadio value="#{user.activationModecheckbox}" layout="pageDirection">
<f:selectItem itemLabel="label1" itemValue="value1" />
<f:selectItem itemLabel="label2" itemValue="value2" />
<h:outputLabel>label</h:outputLabel>
<h:inputText value="" />
</p:selectOneRadio>
</h:panelGrid>
</h:panelGrid>
When the first checkbox is checked, then 2 more radio buttons should show up. When the second checkbox is not checked, then the radio buttons should not show up. How can I achieve this?
You need to decide in some listener method whether or not to show the radio group to the user, for example, by keeping a boolean in a backing bean. Then just render the component via AJAX.
Example usage:
The view:
<h:form>
<p:selectManyCheckbox id="check" value="#{bean.options}">
<p:ajax process="#this" update="radio" listener="#{bean.listener}" />
<f:selectItem itemLabel="Option 1" itemValue="Option 1" />
<f:selectItem itemLabel="Option 2" itemValue="Option 2" />
</p:selectManyCheckbox>
<h:panelGroup id="radio" layout="block">
<h:panelGrid rendered="#{bean.needsSuboptions}" columns="2">
<p:selectOneRadio value="#{bean.suboption1}" layout="pageDirection" >
<f:selectItem itemLabel="Select ---" itemValue="" />
<f:selectItem itemLabel="Suboption 1-1" itemValue="Suboption 1-1" />
<f:selectItem itemLabel="Suboption 1-2" itemValue="Suboption 1-2" />
</p:selectOneRadio>
<p:selectOneRadio value="#{bean.suboption2}" layout="pageDirection" >
<f:selectItem itemLabel="Select ---" itemValue="" />
<f:selectItem itemLabel="Suboption 2-1" itemValue="Suboption 2-1" />
<f:selectItem itemLabel="Suboption 2-2" itemValue="Suboption 2-2" />
</p:selectOneRadio>
</h:panelGrid>
</h:panelGroup>
</h:form>
And the bean:
List<String> options;//getter+setter
String suboption1;//getter+setter
String suboption2;//getter+setter
boolean needsSuboptions = false;//getter
public void listener() {
needsSuboptions = options.contains("Option 1");
}
You can also do with f:ajax as the code that skuntsel provided.
<f:ajax render="" execute="" listener=""/>
maps to:
<p:ajax update="" process="" listener=""/>
<p:selectManyCheckbox id="check" value="#{displayPanel.options}">
<f:ajax event="change" render="radio" listener="#{displayPanel.listener}" />
<f:selectItem itemLabel="Option 1" itemValue="Option 1" />
<f:selectItem itemLabel="Option 2" itemValue="Option 2" />
</p:selectManyCheckbox>
<h:panelGroup id="radio" layout="block">
<h:panelGrid rendered="#{displayPanel.n}" columns="2">
<p:selectOneRadio value="#{displayPanel.a}" layout="pageDirection">
<f:selectItem itemLabel="Select ---" itemValue="" />
<f:selectItem itemLabel="Suboption 1-1" itemValue="Suboption 1-1" />
<f:selectItem itemLabel="Suboption 1-2" itemValue="Suboption 1-2" />
</p:selectOneRadio>
<p:selectOneRadio value="#{displayPanel.b}" layout="pageDirection">
<f:selectItem itemLabel="Select ---" itemValue="" />
<f:selectItem itemLabel="Suboption 2-1" itemValue="Suboption 2-1" />
<f:selectItem itemLabel="Suboption 2-2" itemValue="Suboption 2-2" />
</p:selectOneRadio>
</h:panelGrid>
you forgot the provide listener for f:ajax.

multiple p:ajax in one h:form not invoking

<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<h:outputText value="Region: " />
<p:selectOneMenu id="regionSelection" value="#{haf.selectedRegion}" effect="fade">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{haf.regions}" var="region"
itemLabel="#{region.regionName}" itemValue="#{region.regionCode}" />
<p:ajax listener="#{haf.selectRegion}" update="provinceSelection" />
</p:selectOneMenu>
<h:outputText value="Province: " />
<p:selectOneMenu id="provinceSelection" value="#{haf.selectedProvince}" effect="fade">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{haf.provinces}" var="province"
itemLabel="#{province.provName}" itemValue="#{province.provCode}" />
<p:ajax listener="#{haf.selectProvince}" update="citySelection" />
</p:selectOneMenu>
<h:outputText value="City/Municipality: " />
<p:selectOneMenu id="citySelection" value="#{haf.selectedCity}" effect="fade">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{haf.cities}" var="city"
itemLabel="#{city.cityName}" itemValue="#{city.cityCode}" />
<p:ajax listener="#{haf.selectCity }" update="brgySelection" />
</p:selectOneMenu>
<h:outputText value="Barangay: " />
<p:selectOneMenu id="brgySelection" value="#{haf.selectedBrgy}"
effect="fade">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{haf.brgys}" var="brgy"
itemLabel="#{brgy.brgyName}" itemValue="#{brgy.brgyCode}" />
</p:selectOneMenu>
</h:panelGrid>
</h:form>
May I ask what is the problem of the about code... the first ajax fires but the second doesn't. Does JSF have rule, 1 form, 1 ajax? Thanks in advance for answering a naive question.

Resources