I have two p:selectOneMenu in a page, both have the same content, the user has to choose two different items, the user cannot choose same item in both selectOneMenu. How do I implement this validation ? My current code is something like this :
<p:selectOneMenu id="itemOne"
value="#{backingBean.itemOne}"
required="true" label="Item One:" requiredMessage="Item one is required!">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{backingBean.itemList}" var="item"
itemLabel="#{item.QLabel}" itemValue="#{item.QLabel}" />
</p:selectOneMenu>
<p:selectOneMenu id="itemTwo"
value="#{backingBean.itemTwo}"
required="true" label="Item Two:" requiredMessage="Item two is required!">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{backingBean.itemList}" var="item"
itemLabel="#{item.QLabel}" itemValue="#{item.QLabel}" />
</p:selectOneMenu>
The first thing came to my mind was to attach a listener in both menus with 'onchange' event, remove already selected item and update the other menu but this seems overkill for such simple task. Is there any other way I can do this ?
Related
<h:form id="newStudentForm">
<h:outputLabel value="Student" for="studentId" />
<p:selectOneMenu value="#{myBean.studentId}" id="studentId">
<f:selectItems value="#{myBean.studentList}" var="student"
itemLabel="#{student.name}" itemValue="#{student.id}" />
</p:selectOneMenu>
<h:outputLabel value="Address" for="addressId" />
<p:selectOneMenu value="#{myBean.addressId}" id="addressId">
<f:selectItems value="#{myBean.addressList}" var="address"
itemLabel="#{address.name}" itemValue="#{address.id}" />
</p:selectOneMenu>
<h:outputLabel value="Address" for="addressId" />
<p:selectOneMenu value="#{myBean.subjectId}" id="subjectId">
<f:selectItems value="#{myBean.subjectList}" var="subject"
itemLabel="#{subject.name}" itemValue="#{subject.id}" />
<a4j:ajax event="valueChange"
render="newStudentForm"
listener="#{myBean.checkSubject}"
execute="#this"/>
</p:selectOneMenu>
<h:outputLabel value="Price" for="priceId" rendered="#{myBean.checkSubject}" />
<p:selectOneMenu value="#{myBean.priceId}" id="priceId"
rendered="#{myBean.checkSubject}">
<f:selectItem itemValue="#{null}" itemLabel="" />
<f:selectItems value="#{myBean.priceList}" var="price"
itemLabel="#{price.name}" itemValue="#{price.id}"/>
</p:selectOneMenu>
</h:form>
I am trying to make a field dynamic i.e field Price, when i am selecting a value from subject, the price field is dependent on that value. Everything is working fine in this code except that when i am rendering the form, the values that i enter in other fields(like address) before selecting subject is being overridden by the initial values. So how should i refactor this ajax event call so that the values do not get overridden.
The checkSubject function is returning true or false based on subject selected.
I am relatively new to JSF and Primefaces. I have a page in which I have three selectOneMenu displaying the same set of values from a map. I would like to make sure that the user selects different values for the three drop downs. I have achieved this by writing a custom validator. But the validator works only if I click the submit page. I want to have an ajax call which would show an error message for drop down 2 as soon as the user selects the same value as drop down 1.Also the same case for drop down 3.Here is my code snippet:
user.xhtml
<h:outputLabel for="Question1" value="#{msg['account.question1']}"/>
<h:message styleClass="validation-error" for="Question1"/>
<h:selectOneMenu id="Question1" required="true" value="#{account.question1}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
<f:validator validatorId="com.validator.QuestionsValidator"></f:validator>
</h:selectOneMenu>
<h:outputLabel for="Answer1" value="#{msg['account.answer1']}"/>
<h:message styleClass="validation-error" for="Answer1"/>
<h:inputText id="Answer1" required="true" value="#{account.answer1}" />
<h:outputLabel for="Question2" value="#{msg['account.question2']}"/>
<h:message styleClass="validation-error" for="Question2"/>
<h:selectOneMenu id="Question2" required="true" value="#{account.question2}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
</h:selectOneMenu>
<h:outputLabel for="Answer2" value="#{msg['account.answer2']}"/>
<h:message styleClass="validation-error" for="Answer2"/>
<h:inputText id="Answer2" required="true" value="#{account.answer2}" />
<h:outputLabel for="Question3" value="#{msg['account.question3']}"/>
<h:message styleClass="validation-error" for="Question3"/>
<h:selectOneMenu id="Question3" required="true" value="#{account.question3}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
</h:selectOneMenu>
<h:outputLabel for="Answer3" value="#{msg['account.answer3']}"/>
<h:message styleClass="validation-error" for="Answer3"/>
<h:inputText id="Answer3" required="true" value="#{account.answer3}" />
I am using JSF 2 and Primefaces 5.2.
Thanks in advance
If you want to execute your validator on an AJAX call, you have to add <f:ajax /> to your <h:selectOneMenu>
<h:selectOneMenu id="Question1" required="true" value="#{account.question1}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
<f:validator validatorId="com.validator.QuestionsValidator"></f:validator>
<f:ajax />
</h:selectOneMenu>
Side question: You state, that you use Primefaces 5.2, but you use JSF standard components (<h:selectOneMenu> instead of <p:selectOneMenu>). Is that on purpose?
You can apply listener on selectonemenu.linke this:
<p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px">
<p:ajax listener="#{dropdownView.onCountryChange}" update="city" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
And then in this oncountrychange() function you will get the values of all the three select items and compare them.
I have a selectOneMenu with two items and a panelGroup.
When item 1 is selected I want to show the panelGroup and when item 2 is selected hide it.
I try to do it with the onchange event but I don't know how show/hide the panelGroup. Maybe using the panelGroup ID ?
<p:selectOneMenu id="list" value="#{myBean.list}" onchange="???" >
<f:selectItem itemLabel="Item 1" itemValue="Item 1" />
<f:selectItem itemLabel="Item 2" itemValue="Item 2" />
</p:selectOneMenu>
<h:panelGroup id="myPanelGroup">
...
</h:panelGroup>
the change="" will either give u access to a EL Listener or a javascript, which has no update component to it. You're best off adding a ajax call inside the selectOneMenu.
e.g.
<p:selectOneMenu id="list" value="#{myBean.list}">
<f:selectItem itemLabel="Item 1" itemValue="Item 1" />
<f:selectItem itemLabel="Item 2" itemValue="Item 2" />
<p:ajax event="change" process="#this" update="myPanelGroup" />
</p:selectOneMenu>
<h:panelGroup id="myPanelGroup" rendered="#{myBean.list == '1'">
...
</h:panelGroup>
(you need to have rendered on it to ensure it's only shown if your value is 1 (not 2 etc). Although this is the AJAX solution, you could do it using jQuery by binding a change listener to the selectOneMnu 'list' - on change, run your javascript and show/hide the panelgroup div (means u dont need the rendered etc)..
Example:
$("#list").change(function(event){
//get value here and show/hide div using javascript/css what ever you prefer
});
you can use <p:remoteCommand> tag to update you form. And use rendered to show/hide your panel.
see below code and it is working on my side and much easier.
<p:remoteCommand id="remotecommand" name="updatePanel"
update="#form"></p:remoteCommand>
<p:selectOneMenu id="list" value="#{myBean.list}" onchange="updatePanel()" >
<f:selectItem itemLabel="Item 1" itemValue="Item 1" />
<f:selectItem itemLabel="Item 2" itemValue="Item 2" />
</p:selectOneMenu>
<h:panelGroup id="myPanelGroup" rendered="#{myBean.list eq 'Item 1'}">
...
</h:panelGroup>
When the value of list is Item 1 on that time show the panel otherwise it is hide
Rendering content on demand is a common practice in jsf. You should also rethink the use of a two choices selectOneMenu. You have to wrap the content in a panelGroup element and set the inner element to be rendered like this:
<p:selectBooleanCheckbox id="cboOverview" value="#{ctrlBean.bValue}">
<p:ajax event="change" update="outputOverviewWrapper" />
</p:inputSwitch>
<h:panelGroup id="outputOverviewWrapper">
<h:panelGroup id="toggleOverview" rendered="#{!ctrlBean.bValue}">
...
</h:panelGroup>
</h:panelGroup>
If you want to stick with the selectOneMenu you should also use a valueChangeListener to set the rendering attribute properly.
Reference is here.
We are using JSF 1.2 for our project. Requirement is to update another selectonemenu options based on a value change in the current selectonemenu.
Based on select1 option, select2 needs to be updated.
<h:selectOneMenu id="select1" value="#{subscription.subscriptions}" onchange="javascriptMethod()">
<f:selectItem id="item1" itemLabel="News" itemValue="1" />
<f:selectItem id="item2" itemLabel="Sports" itemValue="2" />
</h:selectOneMenu>
<h:panelGroup id="panel2">
<h:selectOneMenu id="select2" value="#{subscription.subscriptions2}">
<f:selectItem id="item1" itemLabel="News" itemValue="1" />
<f:selectItem id="item2" itemLabel="Sports" itemValue="2" />
</h:selectOneMenu>
</h:panelGroup>
You can use ajax support like this
<h:selectOneMenu id="select1" value="#{subscription.subscriptions}" >
<f:selectItem id="item1" itemLabel="News" itemValue="1" />
<f:selectItem id="item2" itemLabel="Sports" itemValue="2" />
</h:selectOneMenu>
Jsf 1.2 doesn't have ajax support the only thing you can do is full page reload which happens on a command button.
I presumed you are using richfaces as a third party for ajax and rich ui components.
Hope this helps.
If you are using primefaces then you can replace tag with like this
<p:ajax event="onchange" update="select2" action="if you want to anything in
backend"/>
If you want to do by javascript then have a hidden h:commandButton and put code in your
javascriptMethod() method like this
document.getElementById("myHiddenButtonId").click();
I have a page with a <h:selectOneMenu> and I want to show some fields or others depending on the chosen value of the menu. Is this possible and if so, how?
<h:selectOneMenu id="productname" value="#{product.productname}" required="true">
<f:selectItem itemLabel="select" itemValue="null" />
<f:selectItem itemLabel="Detetgent" itemValue="Detergent"/>
<f:selectItem itemLabel="Dishwash" itemValue="Dishwash" />
<f:selectItem itemLabel="Powder" itemValue="Powder" />
<f:selectItem itemLabel="Liquid" itemValue="Liquid" />
</h:selectOneMenu>
<h:panelGroup rendered="Detergernt">
<p>This will be shown if the selected item Detergent.</p>
</h:panelGroup>
<h:panelGroup >
<p>This will be shown if the selected item Dishwash.</p>
</h:panelGroup>
<h:panelGroup >
<p>This will be shown if the selected item equal to powder.</p>
</h:panelGroup>
<h:panelGroup >
<p>This will be shown if the selected item equals to Liquid.</p>
</h:panelGroup>
You just need to check in the rendered attribute if #{product.productname} returns the desired value. In order to update all those components, you should add an <f:ajax> to the menu which updates a common parent component —which is always rendered— of all conditionally rendered components.
<h:selectOneMenu id="productname" value="#{product.productname}" required="true">
<f:selectItem itemLabel="select" itemValue="null" />
<f:selectItem itemLabel="Detetgent" itemValue="Detergent"/>
<f:selectItem itemLabel="Dishwash" itemValue="Dishwash" />
<f:selectItem itemLabel="Powder" itemValue="Powder" />
<f:selectItem itemLabel="Liquid" itemValue="Liquid" />
<f:ajax render="groups" />
</h:selectOneMenu>
<h:panelGroup id="groups">
<h:panelGroup rendered="#{product.productname == 'Detergent'}">
<p>This will be shown if the selected item Detergent.</p>
</h:panelGroup>
<h:panelGroup rendered="#{product.productname == 'Dishwash'}">
<p>This will be shown if the selected item Dishwash.</p>
</h:panelGroup>
<h:panelGroup rendered="#{product.productname == 'Powder'}">
<p>This will be shown if the selected item equal to Powder.</p>
</h:panelGroup>
<h:panelGroup rendered="#{product.productname == 'Liquid'}">
<p>This will be shown if the selected item equals to Liquid.</p>
</h:panelGroup>
</h:panelGroup>
See also:
Conditionally displaying JSF components
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
<h:selectOneMenu id="productname" value="#{product.productname}" required="true">
<f:selectItem itemLabel="select" itemValue="null" />
<f:selectItem itemLabel="Detetgent" itemValue="Detergent"/>
<f:selectItem itemLabel="Dishwash" itemValue="Dishwash" />
<f:selectItem itemLabel="Powder" itemValue="Powder" />
<f:selectItem itemLabel="Liquid" itemValue="Liquid" />
<p:ajax event="onselect" update="selectedOp" listener="#{product.updateSelectedValue}" />
</h:selectOneMenu>
<h:panelGroup rendered="{product.updateSelectedValue ne null}" id="selectedOp">
<p>This will be show selected value</p>
#{product.updateSelectedValue}
</h:panelGroup>
This is how you can display the selected value from drop down on the page. I assume that you are using PrimeFaces, so using an ajax event tag <p:ajax> inside <h:selectOneMenu >. Also adding the condition on <h:panelGroup rendered="{product.updateSelectedValue ne null}">, so that it will be displayed when selected value is other than null.
Yea, you can achieve this . Please do paste your page , so that it is easy for me to explain on the page itself.
The idea is to use an <a4j:outputPanel> as a container and <h:panelGrourp layout="block" rendered="#{}"> as a wrappper for the fields which are need to hidden.
The selected value of selectOneMenu will be used in the rendered attribute of <h:panelGroup>.