Fire AJAX for certain selectItem in selectOneMenu - jsf

I have following selectOneMenu
<p:selectOneMenu value="#{bean.value}">
<f:selectItem value="#{bean.item1}"/>
<f:selectItem value="#{bean.item2}"/>
<f:selectItem value="#{bean.item3}"/>
<p:ajax listener="#{bean.item3AjaxEvent}" update="fieldToUpdate"></p:ajax>
</p:selectOneMenu>
Now I want to do some AJAX action only when item3 is selected from selectOneMenu. Not for all the items. Is there any way of doing that?
Putting ajax tag will fire the event for all the select items. I don't want to generate unwanted ajax requests to server.

I would do it in this way.
xhtml
<p:selectOneMenu widgetVar="selectOneMenuWV"
onchange="checkItem()">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItem itemLabel="Option 1" itemValue="1" />
<f:selectItem itemLabel="Option 2" itemValue="2" />
<f:selectItem itemLabel="Option 3" itemValue="3" />
</p:selectOneMenu>
<p:remoteCommand name="myRemoteCommand"
actionListener="#{bean.item3AjaxEvent()}"
update="fieldToUpdate"/>
<script>
function checkItem() {
if(selectOneMenuWV.getSelectedValue() == 3) {
myRemoteCommand();
}
}
</script>
Hope this helps.

Related

Cannot click on selected Item when the value is null primefaces

I have a selectOneMenu, in my xhtml page, when i want to click in a selectItem with the itemValue is null, there is no effect, it shows the default selection
<p:selectOneMenu id="cout" style="width: 120px;" value="#{serviceManagedBean.selectedService.coutSmsCalc}">
<f:selectItem itemLabel="Sélectionnez une" itemValue="" />
<f:selectItem itemLabel="oui" itemValue="oui" />
<f:selectItem itemLabel="non" itemValue="" />
</p:selectOneMenu>
So, when i click in the itemLabel "non", it remains on "Sélectionnez une"
The selectOneMenu use itemValue to change the displayed value. So if your value is null like the default one, the action changeListener is not called. Try to change the itemValue by empty or other key.
Try this if the item value is a String
<f:selectItem itemLabel="Sélectionnez une" itemValue="{null}" />
<f:selectItem itemLabel="oui" itemValue="oui" />
<f:selectItem itemLabel="non" itemValue="non" />
Or try this if the item value is boolean
<f:selectItem itemLabel="Sélectionnez une" itemValue="{null}" />
<f:selectItem itemLabel="oui" itemValue="true" />
<f:selectItem itemLabel="non" itemValue="false" />

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.

How to save value of p:selectOneRadio

I have this selectOneRadio:
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<h:outputText value="Options: " />
<p:selectOneRadio id="options" value="#{formBean.number}">
<f:selectItem itemLabel="Option 1" itemValue="1" />
<f:selectItem itemLabel="Option 2" itemValue="2" />
<f:selectItem itemLabel="Option 3" itemValue="3" />
</p:selectOneRadio>
</h:panelGrid>
How I can save value in bean, without submit button?
You can use a <p:ajax /> inside the selectOneRadio
Just add one row inside your p:selectOneRadio
In your case it should be this:
<p:ajax listener="#{formBean.setNumber(formBean.number)}"/>
It worked for me in this case:
<p:selectOneRadio id="answer" value="#{test.selectedAnswer}" layout="grid" columns="1">
<f:selectItem itemValue="0" itemLabel="#{test.activeAnswers.get(0).getText()}" itemDisabled="#{progressBar.disabled}" />
<f:selectItem itemValue="1" itemLabel="#{test.activeAnswers.get(1).getText()}" itemDisabled="#{progressBar.disabled}" />
<f:selectItem itemValue="2" itemLabel="#{test.activeAnswers.get(2).getText()}" itemDisabled="#{progressBar.disabled}" />
<f:selectItem itemValue="3" itemLabel="#{test.activeAnswers.get(3).getText()}" itemDisabled="#{progressBar.disabled}" />
<p:ajax listener="#{test.setSelectedAnswer(test.selectedAnswer)}"/>
</p:selectOneRadio>

JSF/PrimeFaces selectOneMenu change view-id

I'm using JSF2 and PrimeFaces3. How can I write selectOneMenu that would invoke JSF navigation to redirect user to another page when he change option in menu?
Attach an ajax listener and let it navigate by NavigationHandler.
E.g.
<h:form>
<h:selectOneMenu value="#{navigator.outcome}">
<f:selectItem itemLabel="Select page..." />
<f:selectItem itemValue="page1" itemLabel="Page 1" />
<f:selectItem itemValue="page2" itemLabel="Page 2" />
<f:selectItem itemValue="page3" itemLabel="Page 3" />
<f:ajax listener="#{navigator.navigate}" />
</h:selectOneMenu>
</h:form>
(the above example expects page1.xhtml, page2.xhtml and page3.xhtml in the same context; you can even make it a <f:selectItems> instead)
with
private String outcome;
public void navigate() {
FacesContext context = FacesContext.getCurrentInstance();
NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
navigationHandler.handleNavigation(context, null, outcome + "?faces-redirect=true");
}
The ?faces-redirect=true is not necessary, but it effectively sends a redirect so that the URL in browser address bar will properly change which is better for user experience and bookmarkability of the pages.
You could have something like:
<p:selectOneMenu value="#{myBean.mySelectedPage}">
<f:selectItem itemValue="http://www.yahoo.com" itemLabel="yahoo" />
<f:selectItem itemValue="http://www.google.com" itemLabel="google" />
<f:selectItem itemValue="search.jsf" itemLabel="search" />
<p:ajax event="change" listener="#{myBean.myNavigationMethod}" />
</p:selectOneMenu>
and on your navigationMethod you have:
String myPage = mySelectedPage
FacesContext.getCurrentInstance().getExternalContext().redirect(myPage);
The first two selectItem are for a full url and the last one is for another page in your web application(be careful that the extension must be the one set in your web.xml - it could be .jsf, .xhtml, .htm etc)
Instead of using ajax navigation use the following:
<p:selectOneMenu value="#{navigator.outcome}" onchange="window.location =this.options[this.selectedIndex].value">
<f:selectItem itemLabel="Select page..." />
<f:selectItem itemValue="page1" itemLabel="Page 1" />
<f:selectItem itemValue="page2" itemLabel="Page 2" />
<f:selectItem itemValue="page3" itemLabel="Page 3" />
<p:ajax event="change" listener="#{navigator.navigate}" />
</p:selectOneMenu>
This works even if the session times out.

Render other selectOneMenu components after selection of one selectOneMenu

I want to have multiple <h:selectOneMenu> that are displayed by selection of main <h:selectOneMenu>
example which is not working
<h:form id="selectForm">
<h:selectOneMenu id="main" value="#{bean.main}">
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
<f:selectItem itemValue="3" itemLabel="3"/>
<f:selectItem itemValue="4" itemLabel="4"/>
<f:ajax render="hotelSearch"/>
</selectOneMenu>
//this one is displayed if main is greater than 1
<h:selectOneMenu id="2" rendered="main>1">
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
<f:selectItem itemValue="3" itemLabel="3"/>
<f:selectItem itemValue="4" itemLabel="4"/>
</h:selectOneMenu>
//this one is displayed if main is greater than 2
<h:selectOneMenu id="3" rendered="main>2">
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
<f:selectItem itemValue="3" itemLabel="3"/>
<f:selectItem itemValue="4" itemLabel="4"/>
</h:selectOneMenu>
</h:form>
How can I achieve this?
You need to make it a valid EL expression #{}.
(update: code example is updated to reflect the new functional requirement to make it to work without the need for a managed bean)
<h:form id="selectForm">
<h:selectOneMenu binding="#{mainMenu}">
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
<f:selectItem itemValue="3" itemLabel="3"/>
<f:selectItem itemValue="4" itemLabel="4"/>
<f:ajax render="#form"/>
</h:selectOneMenu>
<h:selectOneMenu rendered="#{mainMenu.value gt 1}">
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
<f:selectItem itemValue="3" itemLabel="3"/>
<f:selectItem itemValue="4" itemLabel="4"/>
</h:selectOneMenu>
<h:selectOneMenu rendered="#{mainMenu.value gt 2}">
<f:selectItem itemValue="1" itemLabel="1"/>
<f:selectItem itemValue="2" itemLabel="2"/>
<f:selectItem itemValue="3" itemLabel="3"/>
<f:selectItem itemValue="4" itemLabel="4"/>
</h:selectOneMenu>
</h:form>
Note that I used gt instead of > as it's an illegal character in XML. You can find all EL operators in the Java EE tutorial.
See also:
Conditionally displaying JSF components

Resources