JSF h:selectOneMenu wont call relevant setter method - jsf

Hi I've got a question
<h:selectOneMenu id="cmbFileStatus1" disabled="#{!schedulerController.oldFile}"
value="#{schedulerController.test}">
<f:selectItem itemValue="#{null}" itemLabel="--Show All--" noSelectionOption="true"/>
<f:selectItems value="#{schedulerController.statusList}"/>
<f:ajax execute="#this" render="dataTable"/>
</h:selectOneMenu>
The above code the ajax executes(I checked through firebug). But the thing is the selected value wont be set to h:selectOneMenu value parameter.
There is a h:form tag that is wrapping this element, plus there are two other elements similarly using ajax as shown here. But they are positioned before this element in the DOM, they call the relevant setter methods and the updates the bean variables.
But this element it doesn't set necessary selected value.
Also another detail, the list that is populated for selection, it is a list created from enum values.
One instance I moved the problematic code to the top of the DOM (before the other two elements that ajax is applied) and then it hit the setter method when ran in debug mode.
I cannot understand whats wrong, it doesn't show any javascript errors and such. The JSF version is 2.0, this is an old project.
Any ideas guys?

Related

h:selectOneMeny valueChangeListner is not working

I am using h:selectOneMenu for dropdown but the valueChangeListner is not firing.
I can not use submit() onChange as it will refresh my entire page and i will lose the selected values for other components. Please suggest how to fire valueChangeListner without affecting other components on the page.
The h:selectOneMenu implemented like below:
<h:selectOneMenu id="Q1List"
value="#{myBean.q1Value}" onclick="showHideQ1()"//To open another field based on value selected, working fine
valueChangeListener="#{myBean.q1ValueChangeListner}">
<f:selectItem itemValue="" itemLabel="Make a selection"/>
<f:selectItems value="#{RateComparision.q1OptionsList}" id="dr1"/>
</h:selectOneMenu>
Note: i can not use ajax or anything like that as my page is not supporting them.
Any JS solution or component property may help me.
Thanks,
Mahesh

How to get value in JSF xhtml page from f:selectItems

I have select menu in JSF xhtml page. The select menu contains a
<h:selectOneMenu value="#{bean.statusFlag}">
<f:selectItems value="#{bean.statusList}"/>
</h:selectOneMenu>
The value is be being stored in status.
This works fine. I have to print the value in h:outputText in next column.
<h:outputText value="#{bean.statusFlag}" />
prints code rather value corresponding value of code, since the value is in statusList.
Is there any way to achieve this without having to modify the backing bean.
You could perhaps implement some sort of <f:ajax> within your <h:selectOneMenu>.
You could also use jquery with an onchange() event.
$('#select').change(function() {
$('#outText').val($('#select').val());
});
Hope that helps!

<h:selectOneMenu> value change listener invoked for all dropdowns instead of only the current

I'm using MyFaces 1.1. I have two <h:selectOneMenu>s dropdowns which each point to same valueChangeListener method.
<h:selectOneMenu id="d1" value="#{mybean.selectedChannel1}"
onchange="submit()" valueChangeListener="#{myform.channelValuechange}">
<f:selectItems value="#{mybean.channelList}"/>
</h:selectOneMenu>
<h:selectOneMenu id="d2" value="#{mybean.selectedChannel2}"
onchange="submit()" valueChangeListener="#{myform.channelValuechange}">
<f:selectItems value="#{mybean.channelList}"/>
</h:selectOneMenu>
When I change the first dropdown, then the value change listener method get fired correctly. In the method, I'm obtaining the ID of the current component as sourceId via ValueChangeEvent argument and then comparing it as follows:
if (sourceId.equals("d1")) {
// ...
} else if (sourceId.equals("d2")) {
// ...
}
However, my concrete problem is that d2 block is also called when d1 is changed.
I tried the one and other and figured that the following helped to solve the problem:
if (!event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
}
However, I don't feel like that it's the best solution. How is this caused and how can I solve it without using the above code?
With onchange="submit()" you're basically submitting the entire form when the current input element is changed, not only the currently changed input! In contrary to what many starters incorrectly think, there is no means of any input-specific JavaScript/Ajax magic here. As you're submitting the entire form, it would trigger the processing of all input components.
The valueChangeListener is always invoked when the submitted value of the input component does not equals() the initial model value as in the backing bean. Given that in your case both menus hit the value change listener when you change only the first one, that can only mean that the default select item value of the second menu does not equals() the initial model value in the backing bean.
You need to make sure that #{mybean.selectedChannel2} of the second menu has by default exactly the same value as the first item of #{mybean.channelList} of the second menu's list. This way the value change listener won't be invoked for the second menu when you change the first menu.
See also:
When to use valueChangeListener or f:ajax listener? (just to learn what's different in JSF 2, for the case you're interested)

How to implement foreach in jsf?

How do I create ofer_has_location objects (join object from location and ofer) using the current ofer and the selected items from the h:selectManyCheckBox
<h:selectOneMenu id="companyidCompany"
value="#{oferController.selected.companyidCompany}"
title="#{bundle.CreateOferTitle_companyidCompany}"
required="true"
requiredMessage="#{bundle.CreateOferRequiredMessage_companyidCompany}">
<f:ajax event="valueChange" execute="companyidCompany"
render="locationCollection" />
<f:selectItems value="#{companyController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>
<h:outputLabel value="#{bundle.CreateOferLabel_locationCollection}"
for="locationCollection" />
<h:selectManyListbox id="locationCollection" value="locations"
title="#{bundle.CreateOferTitle_locationCollection}">
<c:forEach items="locations">
<f:selectItems var="locations"
value="#{oferController.selected.companyidCompany.locationCollection}" />
</c:forEach>
</h:selectManyListbox>
What you need to do in order to achieve 'connected elements' functionality:
Have two elements ( <h:selectOneMenu> and <h:selectManyLisBox> in your case), where the second one will be dependent on the selected option(s) of the first one. The second element must have an id in order to be rerendered afterwards.
Every HTML select element (that's rendered by both JSF tags of your choice) will have a set of options that are not supposed to be created via iterative element like <c:forEach> (though, it is in fact possible), but rather via the <f:selectItem>/<f:selectItems> tags (thus, remove your iterative tag in comment).
When values in the components are bound not as plain Strings, or primitive wrappers (Integer, etc.), but rather as model objects (YourClass objects, etc.), then you need to tell JSF two things: how can it print option's value from your class and how can it reconstruct an object from request parameter that is a string. For this you need to implement Converter, that is, explain JSF how to do the abovementioned transformations. Use this answer and BalusC's blog as reference points. Note the appropriate syntax for <f:selectItems itemValue="..."> here.
Model values bound by these two components also need to represent your classes, just in a same way as selected items' values. For <h:selectOneMenu> it is value="#{}"; for <h:selectManyListbox> it is value="#{}" with YourClass selectOneMenuValue and List<YourClass> selectManyListboxValues or YourClass[] selectManyListboxValues bean properties respectively.
Population of second select will be handled via <f:ajax> tag. As contents need to be calculated 'on the fly', the right spot to make it is within its listener attribute (i.e. to have List<YourClass> contentsOfSecondListbox = createListboxValues(YourClass oneMenuSelectedOption);) . As you'd desire to rerender the second element, specify its client id in render attribute of <f:ajax>. Example here.
In case you are binding, for example, to String/String[] values, you won't need the converter parts.
Try to go through it step by step to find out your errors and correct them.

JSF selectOneMenu is refreshing and going back to its previous state rather than showing the new value

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";
}
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.
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.

Resources