h:selectOneRadio selection gets unselected - ajax

I have a table that uses a radio button to select a row. When the radiobutton is clicked ajax executes some code to update another field and then render the form. Everything works fine, except that the radio selection disappears and all the radio buttons are unselected. I'm not sure why this is happening? The button was clicked so the value shouldn't change. And it's not the onchange javascript, I removed that as a test and still the same problem. I also can't just render the updated field because it's separate from the code below, I get a servlet exception - unknown id error (maybe someone could tell me how to get around that also?)
<h:dataTable id="addClient" styleClass="dataTable"
value="#{AddEntryMB.clientValues}" var="c" binding="#{AddEntryMB.dataTable}"
rendered="#{AddEntryMB.renderClientTable}">
<f:facet name="header" >
Select Client to Associate with Appointment
</f:facet>
<h:column>
<f:facet name="header">Select</f:facet>
<h:selectOneRadio valueChangeListener="#{AddEntryMB.setSelectedItem}"
immediate="true" onchange="dataTableSelectOneRadio(this);" >
<f:selectItem itemValue="null" />
<f:ajax event="click" render="#form"/>
</h:selectOneRadio>
</h:column>

Look like the value of your selection isn't saved in the backing bean.
First you should bind your h:selectOneRadio component to a backing bean value:
<h:selectOneRadio valueChangeListener="#{AddEntryMB.setSelectedItem}"
value=#{c.radioValue}
immediate="true" onchange="dataTableSelectOneRadio(this);" >
then try to process the dataTable within your ajax like:
<f:ajax event="click" render="#form" execute="addClient"/>
Also I would also add an itemLabel beside itemValue to see what is selected:
<f:selectItem itemValue="null" itemLabel="NULL"/>

It gets unselected because the value is not been set in a model value and the form get refreshed by ajax. You could prevent the unselection by binding the value to the model.
<h:selectOneRadio ... value="#{AddEntryMB.selected[c.id]}">
with
private Map<Long, Boolean> selected = new HashMap<Long, Boolean>(); // +getter
In this example, I assume that the type represented by #{c} has a private Long id property which represents the unique ID.

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

Why are fields reset after ajax update with JSF

on a form : i have one page include two tab.
Tab rendered some boolean values.
e)
after first page i have command buton . Yes or no( its reset booelan value)
if ı click yes second page rendered true and page show but all values reset. All data reset ? What is problem ? How can i solve this.
All code is here :http://pastebin.com/Ffi33hdw
Uptade buton line 287 .
<h:selectOneRadio id="fikirorProje" required="true" value="#{ideaBean.newIdea.fikirProje}"
enabledClass="labelNormalRadio" disabled="#{ideaBean.createdIdea}"
requiredMessage="Bu alan boş bırakılamaz.">
<f:selectItem itemValue="#{false}"
itemLabel="Hayır" uptade="butonThree"/>
<f:selectItem itemValue="#{true}" itemLabel="Evet"/>
<p:ajax event="change" update="addIdeaForm" />
<p:ajaxStatus onstart="PF('status').show()" onsuccess="PF('status').hide()"/>
</h:selectOneRadio>
thans for answering
Theprocess attribute of p:ajax defaults to #this, so in the change event of your h:selectOneRadio your form is not being fully process which means that the ideaBean's properties will not be updated, (check more info about how update/process work here). Add process="#form" to your ajax event <p:ajax event="change" update="addIdeaForm process="#form" /> and it should work

JSF Ajax reset previously rendered input component values?

I have a small (but vital) problem with JSF and ajax. The form is here:
<h:form>
<h:panelGrid id="pg1" columns="2">
<h:outputText value="Type: "/>
<h:selectOneMenu id="selectOne" value="#{personBean.type}">
<f:selectItems value="#{listBean.personTypes}"/>
<f:ajax event="valueChange" render="pg2"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid id="pg2" columns="2">
<h:outputText value="Really bad?" rendered="#{personBean.type=='BAD'}"/>
<h:selectBooleanCheckbox id="checkbox" value="#{personBean.reallyBad}" rendered="#{personBean.type=='BAD'}">
<f:ajax event="click"/>
</h:selectBooleanCheckbox>
</h:panelGrid>
<h:commandButton value="Ajax Submit" action="#{personBean.printValues}">
<f:ajax execute="#form"/>
</h:commandButton>
</h:form>
The PersonBean is a simple bean with an enum PersonType that has two values: NICE, BAD and a Boolean called reallyBad. The ListBean returns the enum values in a list to populate the selectOneMenu.
Basically when I select BAD the panel for the boolean checkbox is rendered where I can tick it to say a person is reallyBad. I can then submit the form if I wish. The problem is when I tick the checkbox and then select NICE again, the checkbox is still ticked even though it is not rendered. So when I submit my form the person can be NICE and reallyBad, which doesn't make sense.
Rather than having to select BAD again to uncheck the box, is their a way that I can reset the checkbox and its input value to false when NICE is selected? I'm a bit of a noob to ajax with JSF! Thanks.
ps. I am printing the values of the two inputs on submit with the commandButtons action to verify the results...
You need to manually clear the checkbox when you change the menu.
<f:ajax listener="#{personBean.setReallyBad(false)}" render="pg2" />
By the way, the both <f:ajax event> values as you've in your code are the default values already. Just omit them.

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 pass an iterated parameter via ajax to a backing bean method

So, I have a dataTable that looks like this:
<h:form>
<h:dataTable value="#{backingBean.employeeLineItems}" var="emp">
<h:column>
<f:facet name="header">First</f:facet>
#{emp.lastname}
</h:column>
<h:column>
<f:facet name="header">Last</f:facet>
#{emp.firstname}
</h:column>
<h:column>
<f:facet name="header">Actions</f:facet>
<h:commandButton value="View Details">
<f:ajax execute="#{setCurrentEmployeeId(emp.id)}" render="employeeDetails"/>
</h:commandButton>
</h:column>
</h:dataTable>
<h:outputText value="#{backingBean.employeeDetails}" id="employeeDetails"/>
</h:form>
For each row of the datatable, there is a button that I want to, when clicked, ajax the employeeLineItem id value over to a method that sets that id in the backing bean, and then renders the outputText tag with id "employeeDetails" (The getEmployeeDetails method would use the employeeLineItem id to get the right employee details object from the database, of course)
My solution doesn't seem to be working, does anyone know what I'm doing wrong?
<h:commandButton value="View Details">
<f:ajax execute="#{setCurrentEmployeeId(emp.id)}" render="employeeDetails"/>
</h:commandButton>
This is wrong. The execute attribute of <f:ajax> should point to a space separated collection of component client IDs which are to be submitted and processed in the server side (the same way as you specify the render attribute with a space separated collection of component client IDs which are to be updated/re-rendered after the ajax request). In your particular case, it should have been the ID of the datatable or the form, or just #form to generically refer the parent form.
The action method wherein you pass the row ID should be definied in the action attribute of the <h:commandButton> instead. So, this should do:
<h:commandButton value="View Details" action="#{backingBean.setCurrentEmployeeId(emp.id)}">
<f:ajax execute="#form" render="employeeDetails"/>
</h:commandButton>
(note that I fixed the missing managed bean name in the action method)
By the way, are you aware that you can also just pass whole objects along as arguments in EL?
<h:commandButton value="View Details" action="#{backingBean.setCurrentEmployee(emp)}">
<f:ajax execute="#form" render="employeeDetails"/>
</h:commandButton>
This way you don't need to reload the employee from the DB.

Resources