Passing selected value in h:selectOneMenu to h:link - jsf-2.2

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>.

Related

Conditional input text fields using primefaces/JSF/XHTML [duplicate]

Is there a way to render a component based on the current value the user has selected from a selectOneMenu component? My selectOneMenu component is populated with an enum consisting of two values, smoker and non-smoker. If the user has smoker selected I want to render a checkbox below it which lets the user check how many they smoke a day 10, 20, 30+, etc. I also want the opposite to work if they user has selected non-smoker i.e. the check boxes don't render/disappear.
Just check the dropdown menu's value in the rendered attribute of the target components and update their common parent by a <f:ajax>. Here's a kickoff example:
<h:selectOneMenu value="#{bean.item}">
<f:selectItem itemValue="one" />
<f:selectItem itemValue="two" />
<f:selectItem itemValue="three" />
<f:ajax render="results" />
</h:selectOneMenu>
<h:panelGroup id="results">
<h:panelGroup rendered="#{bean.item eq 'one'}">
You have selected "one".
</h:panelGroup>
<h:panelGroup rendered="#{bean.item eq 'two'}">
You have selected "two".
</h:panelGroup>
<h:panelGroup rendered="#{bean.item eq 'three'}">
You have selected "three".
</h:panelGroup>
</h:panelGroup>
If you'd like to perform some business logic based on the selected value, use <f:ajax listener>.
<f:ajax listener="#{bean.changeItem}" render="results" />
public void changeItem() {
someResult = someService.getByItem(item);
}
See also:
Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
How to load and display dependent h:selectOneMenu on change of a h:selectOneMenu
Conditionally displaying JSF components

<f:ajax> doesn't work on PrimeFaces component

I trying to use the onChange event of selectOneMenu, but it doesn't work and the component is not displayed when I add onChange attribue.
Can someone tell me how can I handle the onChange event of <p:selectOneMenu>?
Here is my view:
<p:selectOneMenu id="service" filterMatchMode="startsWith">
<f:selectItem itemLabel="Selectionner un Service : " />
<f:selectItems value="#{newOpProgramme.listeSevice}" var="service" itemValue="#{service.serviceId}" itemLabel="#{service.serviceNom}"/>
<f:ajax event="change" execute="#this" listener="#{newOpProgramme.serviceChange()}" render="nomCdp"/>
</p:selectOneMenu>
And here is the <f:ajax listener> method in a request scoped bean:
public void serviceChange() {
System.out.println("change");
}
When I change the menu, however, nothing is been printed.
How is this caused and how can I solve it?
First of all, onChange is the wrong event name. It's change. Secondly, if you intend to call the HTML attribute name, onChange is also the wrong attribute name. It's onchange.
Coming back to your concrete problem; the standard JSF <f:ajax> is not compatible with PrimeFaces components. You should be using PrimeFaces own <p:ajax> instead.
<p:selectOneMenu ...>
...
<p:ajax listener="#{newOpProgramme.serviceChange()}" update="nomCdp" />
</p:selectOneMenu>
Note that I omitted the event and the process attributes. They both have already the right default value of valueChange and #this respectively.
See also:
What values can I pass to the event attribute of the f:ajax tag?
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
When I want to update something after change in selectOneMenu, I use <f:ajax> tag inside selectOneMenu like this:
<h:selectOneMenu value="#{bean.selected}" >
... select items here
<f:ajax event="change" execute="#this" render="search" />
</h:selectOneMenu>
Where search is the Id of the object you want to update.
Other solution is that you should try onchange not onChange.
<p:selectOneMenu value="#{someBean.myAttr.id}" valueChangeListener="#someBean.mySelectioMethodListener}">
<f:selectItems value="#{someBean.listAttrs}" var="item"
itemLabel="#{item.name}" itemValue="#{item.id}" />
<p:ajax process="#this" update="someElementId" />
</p:selectOneMenu>
You must put an Id for <f:selectItems /> and set your selection on backing bean side by posted ajax itemValue (id).
Server side method bean without a converter:
public void mySelectionMethodListener(ValueChangeEvent event) {
ApplicationContext context = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
SomeBeanDao someBeanDao = (SomeBeanDao) context.getBean(SomeBeanDao.class);
myAttr = someBeanDao.byId((Long) event.getNewValue());
System.out.println("value changed...");
}

RichFaces: partial form validation

I have a form containing several fields(name, surname, etc) and a datatable. Datatable is dedicated to store addresses into the backing bean. A person can have more than one address so I add a button as follows:
<a4j:commandButton action="#{bean.addAddressRow}" value="Add address" reRender="addresses" />
where "addresses" is the id of my datatable. I use a4j because there's no need to refresh the page.z
What I want to do is to skip the validation of the entire form except the address fields when this button is pressed. So a user can add one more address if all the previous addresses are correctly filled. The other fields should not be validated.
Is it possible to do?
Wrap your address table and the commandButton with <a4j:region> tags and set the attribute renderRegionOnly to true. Look at following example. Here only the last two text boxes (txt2 and txt3) are validated when you press the first button. If you press the second button all three text boxes are validated.
<h:form>
<h:inputText required="true" id="txt1"/>
<rich:message for="txt1" style="color:red"/>
<a4j:region renderRegionOnly="true">
<h:inputText required="true" id="txt2"/>
<rich:message for="txt2" style="color:red"/>
<h:inputText required="true" id="txt3"/>
<rich:message for="txt3" style="color:red"/>
<a4j:commandButton value="Ok1" />
</a4j:region>
<a4j:commandButton value="Ok2" />
</h:form>

JSF2: cannot get data from a HtmlSelectOneMenu in java code

I am working with MyFaces/Primefaces and I have a problem to get information using ajax.
My page contains a list of panel, inside each panel, the user can select value in a dropdown list, and click on a checkbox which will update its panel (Ajax), I hope I am clear.
This is my code:
<p:panel>
...
<h:selectOneMenu id="beanSet" value="#{myBean.selectedSet}">
<f:selectItem itemLabel=" " noSelectionOption="true" />
<f:selectItems value="#{langSet}" />
</h:selectOneMenu>
<h:selectBooleanCheckbox
id="chkbxBeanSet"
value="#{myBean.selectedSetChkbx}" >
<p:ajax
event="click" render="#parent"
listener="#{action.updateSet}"
execute="#form"
immediate="true"
/>
</h:selectBooleanCheckbox>
...
<p:panel>
And here my java code:
public void updateSet(AjaxBehaviorEvent e) {
UIComponent source = (UIComponent)e.getSource();
System.out.println("Value:"+((HtmlSelectBooleanCheckbox)source).getValue());
UIComponent parent = source.getParent();
List<UIComponent> children = parent.getChildren();
HtmlSelectOneMenu lvSet = (HtmlSelectOneMenu)parent.findComponent("beanSet");
Object value = lvSet.getValue();
System.out.println("value: " + value);
I get the beanSet component, but I can't get its value. As I understand, the getValue calls the getSelectedSet from myBean which is not set (it is in request scope).
I don't understant how I can get the selected value in the dropdown list using ajax.
Another way is to post all the form, but in that case, I have to determine which checkbox was clicked by the user...
If someone can explain me where I am wrong?
The culprit is immediate="true" on the ajax action. This will skip all input components which do not have this attribute set during the processing. You should finetune the to-be-processed components in the process attribute of <p:ajax>. Yes, another culprit is that you used execute instead of process. The <p:ajax> uses process where <f:ajax> uses execute. Also, the way how you accessed the dropdown value is unnecessarily overcomplicated. Just access the selectedSet property directly. JSF will set it in the same bean anyway.
So, this should do
<h:selectOneMenu id="beanSet" value="#{myBean.selectedSet}">
<f:selectItem itemLabel=" " noSelectionOption="true" />
<f:selectItems value="#{langSet}" />
</h:selectOneMenu>
<h:selectBooleanCheckbox id="chkbxBeanSet" value="#{myBean.selectedSetChkbx}">
<p:ajax process="#this beanSet" listener="#{action.updateSet}" update="#parent" />
</h:selectBooleanCheckbox>
with
public void updateSet() {
System.out.println(selectedSet);
}
Note that I omitted event="click" from <p:ajax>. It's already the default for checkboxes.
place this (listener is optional) , the <f:ajax event="change" is what you need the most
<f:ajax event="change" render="IdsOfComponentToRender" listener="#{myBean.someMethod}" />
inside your <h:selectOneMenu id="beanSet" value="#{myBean.selectedSet}">
this is the signature of the listener
public void someMethod(AjaxBehaviorEvent ev) {...
b.t.w what is that updateLvSet method , and where you call it , and you should not access you data that way...

How to save 2 dependent selectOneMenu values

I'm running in a little issue here regarding jsf related dropdown selection.
I have 2 dropdown selection: the first one is independent, the second one shows result depending from This is the code:
<h:panelGroup id="addressPanel">
<h:outputLabel styleClass="label" value="Provincia: " />
<h:selectOneMenu onchange="updateCombos()"
value="#{indirizzoCtrl.codiceProvincia}" >
<f:selectItem itemValue="" itemLabel=""></f:selectItem>
<f:selectItems value="#{indirizzoCtrl.allProvincia}" var="c"
itemLabel="#{c.nome}" itemValue="#{c.siglaProvincia}" />
</h:selectOneMenu>
<h:outputLabel styleClass="label" value="Comune: " />
<h:selectOneMenu
value="#{indirizzoCtrl.codiceComune}" >
<f:selectItem itemValue="" itemLabel=""></f:selectItem>
<f:selectItems value="#{indirizzoCtrl.allComuni}" var="c"
itemLabel="#{c.descrizione}" itemValue="#{c.codiceComune}" />
</h:selectOneMenu>
</h:panelGrid>
</h:panelGroup>
<p:remoteCommand name="updateCombos" update="addressPanel masterForm:msg" />
<p:commandButton styleClass="commandButton" value="Save"
actionListener="#{indirizzoCtrl.save}">
</p:commandButton>
Well, when the user save the form after selecting both the value, the managed bean indirizzoCtrl (request scoped) cannot map the value of the second dropdown back to the list, because there's no list.
In fact the #{indirizzoCtrl.allComuni} call a getter that retrieve the data from the DB only if indirizzoCtrl.codiceProvincia!=null... and that's false before the update model phase.
So the first time the getter for the list is called cannot retrieve any values, and that's bring the update model phase to fail.
How can I handle this scenario... I think it's a pretty common one, so I'm missing something here...
Put the bean in the view scope instead. It will live as long as you're interacting with the same view by ajax. A request scoped bean get indeed recreated on every single request, also ajax requests, so bean properties would reinitialize to their defaults.
#ManagedBean
#ViewScoped
public class IndidizzoCtrl implements Serializable {
// ...
}
See also:
How to load and display dependent h:selectOneMenu on change of a h:selectOneMenu
How to choose the right bean scope?
Unrelated to the concrete problem, I also strongly recommend to change your getter methods to not do any business job, but just return data. Do the business job in (action)listener methods instead. E.g.
<h:selectOneMenu value="#{bean.menu1item}">
<f:selectItems value="#{bean.menu1items}" />
<f:ajax listener="#{bean.updateMenu2}" render="menu2" />
</h:selectOneMenu>
<h:selectOneMenu id="menu2" value="#{bean.menu2item}">
<f:selectItems value="#{bean.menu2items}" />
</h:selectOneMenu>
with
public void updateMenu2() {
menu2items = loadItBasedOn(menu1item);
}
See also:
Why JSF calls getters multiple times

Resources