h:selectOneMenu with Please select displays previous selection on validation error - jsf-2

I am using Spring Webflow 2.4.0.M1 with Mojara JSF 2.1.21.
I have a very simple h:selectOneMenu like so:
<h:selectOneMenu id="title" value="#{person.title}" required="true" requiredMessage="Required title">
<f:selectItem noSelectionOption="true" itemLabel="Please Select" itemValue="" />
<f:selectItem itemLabel="Mr" itemValue="MR" />
<f:selectItem itemLabel="Mrs" itemValue="MRS" />
</h:selectOneMenu>
<p:message for="title"/>
After submitting the form with the value left on Please Select, I get the required message displayed. If I then choose option 'Mr', and then submit again, but with other fields on the page having errors, then the page is reloaded, and the required message for title is gone and Mr is selected, as expected. If I then change it back to Please Select and submit again, I get the required message display again, but the selected option has gone back to being 'Mr' instead of 'Please Select'. The #{person.title} EL is binding to a String, which is defaulted to an empty string. So far, this only seems to be an issue on selectOneMenu, as doing the same kind of thing on a h:inputText works correctly.
Any ideas? Have also tried with webflow 2.3.2.RELEASE and same issue occurs.
Looks like it is the same issue as this: JAVASERVERFACES-932 which is about 4 years old, and has a resolution of fixed. It's definitely not fixed. I will try extending the MenuRenderer and overriding the renderOption method with the suggestion mentioned at the end of the Jira issue.

I can confirm that extending MenuRenderer and overriding the renderOption method with the suggestion mentioned at the end of the Jira issue fixes the issue.
Don't forget to add your patched renderer to your faces-config.xml
<render-kit>
<renderer>
<component-family>javax.faces.SelectOne</component-family>
<renderer-type>javax.faces.Menu</renderer-type>
<renderer-class>your.package.PatchedMenuRenderer</renderer-class>
</renderer>
</render-kit>

Related

JSF Ajax called only 1st time

In JSF2 I have an XHTML like this:
<h:form id="myForm">
...
<c:forEach items="#{myController.header}" var="hd" varStatus="count">
#{hd}
<h:selectOneMenu value="#{myController.type[count.index]}" id="formtype" >
<f:selectItem itemValue="Nop" itemLabel="Nop" />
<f:selectItem itemValue="Yep" itemLabel="Yep" />
<f:ajax render="#form" />
</h:selectOneMenu>
#{myController.type[count.index]}
<h:selectBooleanCheckbox value="#myController.valid[count.index]}" id="valid">
<f:ajax render="#form"/>
</h:selectBooleanCheckbox>
#{myController.valid[count.index]}
</c:forEach>
...
</h:form>
And my managed bean has:
private String[] type;
private boolean[] valid;
which I initialise (type = new String[...]; and assign a value to each position) when the named bean is 1st loaded.
If I modify the combo or the check box, it works, the value is changed in the managed bean and the new value gets printed (rendered) in the JSF page. But only the 1st time. Next changes do not modify anything at all. It is strange because I have similar code in other apps and works fine, so I am doing something incorrectly but cannot find it. My template has a h:header and I cannot see any logs in the JS console or in TomEE (I only see .INFO - The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/myApp]] after start() had already been called. The second call will be ignored but I think it is unrelated). I have tried to add execute="#this"/execute="#form" and others unsuccessfully, and check all points of this post but nothing seems to apply to me.
What is the mistake I am not seeing?
EDIT
#Named(value = "myController")
#ViewScoped
public class MyController implements Serializable {
...
I also have a <h:messages globalOnly="true" showDetail="true" showSummary="true" /> in my template.
I think I got it, finally!
Thanks to two things:
Point 3 in BalusC answer. I added an id to my message in the template <h:messages id="msg" and then use <f:ajax render="#form msg"..... This made an error j_idt1: Validation Error: Value is required to appear.
Then I could find the solution in this post: to change the required parameter from true to <f:viewParam required="#{!facesContext.postback}". This was not required in my other apps because required was "false", since it could be called with parameter or without it. When it was called with a parameter, it worked because by serendipity the page could be called without it.
Ran into the exact same problem, my <f:ajax> tag would work the first time and then nothing... no error or anything on the page. After a few hours and countless googling nothing was turning up. (Most of the questions on StackOverflow were actually having the opposite problem, the Ajax wouldn't fire the first time but then it would work fine). I finally stumbled on this question which described exactly what I was seeing.
I was previously trying to re-render only a section of the page, but I noticed that once I changed the render attribute to "#all", I got the same error message describe above:
j_idt1: Validation Error: Value is required
I scrolled up and noticed I had a <f:viewParam> with required set to "true". I made the change described by user1156544 and that did the trick.

Is it possible to fill the background color of some items of f:selectitem in one color and others in others?

I'm a new member of stackoverflow but since this is the first problem I really can't seem to fix.
I know the question probably is unclear but here is my problem. For our backend application we use JSF.
Now there is a p:selectOneMenu with selectItems that are automatically filled (DatabaseServers) but we've added a new attribute (boolean full) and my question now is if it is possible to edit the background-color of the full databases in red and the not full databases in green.
<p:outputLabel for="emrDatabaseServer"
value="#{msg['tenants.label.emrDatabase']}" />
<p:selectOneMenu id="emrDatabaseServer" style="width:250px;"
value="#{tenantController.entity.emrDatabaseServer}"
effect="fade" required="true"
converter="#{databaseServerConverter}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{tenantController.emrDatabaseServers}"
var="emrDB"
itemLabel="#{emrDB.name} (#{emrDB.host}:#{emrDB.port}) (#{emrDB.nbDatabases} dbs)"
itemValue="#{emrDB}" />
<p:ajax event="change"
listener="#{tenantController.onValueChange}" update="save" />
</p:selectOneMenu>
I've tried countless things but it just doesn't seem to work.
I would also like to mention that I don't have the option of using code from other packages and so.
Styling options of a select-element is not possible in a clean and cross-browser-compatible way, as described here.
But if you would use some hack that satisfied your styling-requirement, there is no style or styleClass attribute for <f:selectItem> resp. <f:selectItems>. For this problem you could try using a pass-through-attribute as described by this anser (which uses the title-attribute instead of style, but you got the idea).
But all in all, what you are trying to do would result in a big hack and should be avoided.

JSF tag for disabling a checkbox on selecting a dropdown without using JavaScript

I have a dropdown and checkbox in my page and if we select a dropdown then the checkbox has to be disabled. We should not use JavaScript for this. I am new to JSF. Is there a way by using JSF. Any ideas.
Just add a <f:ajax> which executes on change of the dropdown and updates the checkbox whereby its disabled attribute checks if the dropdown's value is not empty.
E.g.:
<h:selectOneMenu value="#{bean.selectedItem}">
<f:selectItems value="#{bean.availableItems}" />
<f:ajax render="checkbox" />
</h:selectOneMenu>
<h:selectBooleanCheckbox id="checkbox" disabled="#{not empty bean.selectedItem}" />
That's basically all.
Please note that this uses under the covers still JavaScript for the job! The only difference is that you don't need to manually write any line of JavaScript code, instead JSF autogenerates the necessary JS code for you.

Immediate="true" causes update="component" to fail

I have a command button (a Cancel button to be specific) that I want to bypass the validation of some components on my page. When I have immediate="true" set on my command button, the update attribute does not work. By "not work" I mean that the values on :centerForm:p_definition do not reset to what they should be. If I select an item from a dropdown or enter data into an input text, the information should disappear when clicking cancel. Setting immediate="false" or leaving it off completely does reset the fields as expected. Here is the definition of the commandbutton I am having trouble with.
<p:commandButton value="Cancel" style="float: right;"
immediate="true"
actionListener="#{manageBomPropHandler.doCancel()}"
update=":centerForm:p_definition"/>
Is that the expected behavior from immediate="true"? If so, how have you gotten around this for cancel buttons?
"Update" will be called/executed at Update Model Value phase. When you set "immediate" attribute to button command, this phase is ignored.See below images for more detail.
P1: Standard Lifecycle executes Update Model Values phase
P2: Immediate Lifecycle ignored Update Model Values phase
If may help, there's a already solution for clean input fields with primefaces:
<p:commandButton value="Reset Tag" update="panel" process="#this" style="margin-right:20px;" >
<p:resetInput target="panel" />
</p:commandButton>
OR
<h:commandButton value="Reset p:ajax" style="margin-right:20px;" >
<p:ajax update="panel" resetValues="true" />
</h:commandButton>
Source: http://www.primefaces.org/showcase/ui/misc/resetInput.xhtml
In my case, in order to update the fields, I have attached p:ajax against the required component.
That ensured that corresponding fields/variable in backing bean is updated as soon as user makes changes in any of those fields.
Another requirement I had is to refresh a data table after user clicks a immediate - true command button.
In order to do that, I have used code like:
RequestContext.getCurrentInstance().reset("Datatable ID");
Yup, displaying my ignorance of the JSF lifecycle. Found the answer here: JSF commandButton with immediate="true" and here: https://cwiki.apache.org/confluence/display/MYFACES/Clear+Input+Components

How do I get PrimeFaces <p:selectOneMenu> to call valueChangeListener?

Using PF 3.0-RC1 Snapshot (11/22/2011)
I have a in a composite component.
I want to call the valueChangeListener when a selection is made, but it does not appear to be calling the listener.
Here is the code for the component:
<p:selectOneMenu style="width: 220px;"
value="#{customerProfileSessionBean.selectedAccount}"
valueChangeListener="#{customerProfileSessionBean.accountValueChange}" >
<f:selectItems value="#{sessionBean1.custAccountList}"/>
</p:selectOneMenu>
The listener in the backing bean has a print statement that is not being called (at least I do not see it in the server log).
Is there something else that I need to do to get the valueChangeListener to be called when the value changes?
Do I need to use ?
Also, in the listener, is there a ValueChangeEvent that is passed?
Thanks.
You seem to be expecting that the valueChangeListener method in the server side is called immediately when a change event occurs on the client side. This is not correct. It will only be invoked when the form is submitted to the server and the new value does not equals() the old value.
There are at least two ways to achieve your functional requirement:
Add onchange="submit()" so that JavaScript will submit the form whenever you change the value:
<p:selectOneMenu style="width: 220px;"
value="#{customerProfileSessionBean.selectedAccount}"
valueChangeListener="#{customerProfileSessionBean.accountValueChange}"
onchange="submit()">
<f:selectItems value="#{sessionBean1.custAccountList}"/>
</p:selectOneMenu>
This is however very JSF-1.x-ish and poor for user experience. It will also submit (and convert/validate!) all other input fields which may not be what you want.
Make use of an ajax listener instead, for sure if you are not interested in the actual value change (i.e. the old value is not interesting for you), but you're actually interested in the change event itself. You can do this using <f:ajax> or in PrimeFaces components using <p:ajax>:
<p:selectOneMenu style="width: 220px;"
value="#{customerProfileSessionBean.selectedAccount}">
<p:ajax listener="#{customerProfileSessionBean.accountValueChange}" />
<f:selectItems value="#{sessionBean1.custAccountList}"/>
</p:selectOneMenu>
And replace the ValueChangeEvent argument by the AjaxBehaviorEvent argument.
Add f:ajax statement for p:selectOneMenu , it will create ajax call and your value will be submitted EX:
<p:selectOneMenu style="width: 220px;" value="#
{customerProfileSessionBean.selectedAccount}"
valueChangeListener="#{customerProfileSessionBean.accountValueChange}" >
<f:selectItems value="#{sessionBean1.custAccountList}"/>
<f:ajax render="#form"/>
</p:selectOneMenu>
Or you can provide panel id or datatable id ,if you dont want torender the whole form, like:
<f:ajax render=":formid:panelGroupId"/>

Resources