Question

I have a datatable where a lot of selectOneMenu items are available , for example, for 10 items each having one selectOneMenu combo. now if i click on any of the combos, they are supposed to save the value in the database and they do it. but after saving the changed value the selectOneMenu is returning back to its previous state. I want the selectOneMenu to keep its current state. also, the method is being invoked for every single combo in the datatable. i really wonder why!! i have been banging my head for the last 2 weeks. any help would be really appreciated. thanks in advance.

this is my first post here. this is my jsf datatable:

<h:dataTable value="#{careNeedBean.controlledCareNeedsList}" var="careNeed"
        id="careneed_table" binding="#{careNeedBean.dataTable}">
<h:column>
 <f:facet name="header">
  <h:outputText value="NeedsLevel"/>
 </f:facet>
 <h:selectOneMenu id="needs_level_combo" style="width:200px;font-size:9px;"
                                         onchange="submit()" 
                                         valueChangeListener="#{careNeedBean.saveTaskAsessment}"
                                         binding="#{careNeedBean.selectOneMenu}">                                      
  <f:selectItem itemValue="not_assessed" itemLabel="----Not assessed----"/>
                    <f:selectItems value="#{careNeed.humanReadableNeedsList}" />
 </h:selectOneMenu>
</h:column>

This is my bean code:

public String saveTaskAsessment(ValueChangeEvent event) {
   //does some things
   return "Success";
} 
Was it helpful?

Solution

The valueChangeListener doesn't run on the recently changed component only. In fact, you're using JavaScript submit() function to submit the entire form. The valueChangeListener will always be executed whenever the new selected value differs from the old value as is been declared in the value attribute.

You don't have declared a value attribute, so its default value is effectively null. If the default selected item of the list is not null, then the valueChangeListener will be invoked.

To fix this, you need to assign a value attribute to the component

<h:selectOneMenu value="#{careNeed.needsLevel}">

and you need to prefill it with the same value as the default value of the dropdown list.

this.needsLevel = "not_assessed";

Alternatively, you can also make the default value null.

<f:selectItem itemValue="${null}" itemLabel="----Not assessed----"/>

Unrelated to the problem, since you're already on JSF 2.0, I'd suggest to use <f:ajax> to submit only the recently changed dropdown by ajaxical powers instead of using onchange="submit()" to submit the entire form. That's after all better for user experience.

<h:selectOneMenu>
    <f:ajax />
</h:selectOneMenu>

Also, the valueChangeListener method doesn't need to return anything. It will be ignored anyway. Just declare it void.

OTHER TIPS

You can use AjaxSingle="true" and onsubmit="form.refresh();" on your ajax request.

So that it will process only the current component. form.refresh(); will remove the old cache value. You will get the refreshed bean value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top