Ajax event never fires in <p:inptText> when required="true" - jsf-2

In PrimeFaces when I use:
<p:inputText required="true"
requiredMessage="message"
value="#{backingBean.value}">
<p:ajax event="focus"
update="infoText"
listener="#{backingBean.something()}" />
</p:inputText>
The Ajax-event is never fired.
However, if I remove the required="true" everything works fine and the event fires.
Can anyone tell me how to use p:inputText with p:ajax and required="true"?

This is probably occurring because when you gain focus to the text field an ajax event occurs that posts back the ViewState for the components on the page.
When it does this it is attempting to set the current value of the text field to #{backingBean.value} which is empty, causing a ValidatorException to be thrown. Because this validation error occurred the action event #{backingBean.something()} is never being fired.
Try adding the property immediate="true" to the <p:ajax> tag and see if that allows the event to fire before the validation phase.

Related

JSF Validation error not printed in open dialog

I have to validate that a field in a form is not empty.
The problem is that the form is in a JQueryUI dialog (since I don't know how to create "windows" in JSF), so when I click the commandButton the page is refreshed and the JQuery dialog is lost. After refreshing, I can see the error message was printed in the page code by looking at the source code. If I use ajax in the commandButton then the page is not refreshed but I don't get the message printed, I got it as a sort of "Javascript alert" in the browser.
How can I get the error message without refreshing the page?
<h:inputText value="#{myController.name}" id="myname" required="true" requiredMessage="Name required">
<f:ajax />
</h:inputText>
<h:message errorClass="..." for="myname" />
Note: This looked similar to my problem but I don't think the solution is what I'm looking for.
Note: I am not using additional libraries like Primefaces, etc
With the hint of the comment, I was able to solve it this way:
In the commandButton, use ajax with both render and execute (render only doesn't work):
<h:commandButton id="...." action="#{myController.doSomething()}" type="submit" value="Do something">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
Create a "pageUpdate()" method in myController that is called at the end of myController.doSomething(). This way, after the actions, the page is refreshed and the dialog is gone. There are of course other ways to close the dialog, but it is convenient for me to update the page when there is no error in the dialog action, so my objects in memory are updated too.
I think JQuery dialog messes with my styles after the ajax call returns with error, so check that out if you do it.

Prevent primefaces datatable select new row when validation fails

I have a master detail ui showing some items in a dataTable. If a item is selected the details are shown in a form.
If there is invalid data in the form I want to prevent that the user is able to select a new item from the dataTable. A validation already error is shown on the details side and the form is not updated when a validation error is existing (seems to be a bulit-in behaviour).
Unfortunately I wasn't able to prevent that the user can select another row in the dataTable. I tried:
<p:dataTable ...>
<p:ajax event="rowSelect" update="someId" />
<p:ajax event="rowUnselect" update="someId" oncomplete="if (args && args.validationFailed) return false;" process=":detialsFormId" />
...
</p:dataTable>
But this doesn't work. As I know only in oncomplete there is the args variable available. I think in both rowSelect and rowUnselect it is too late.
Maybe there is another approach? Thought about a remote command which sets the t-1 selection when validation failed. But maybe there's another fancier solution?
Regards
Oliver

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

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>

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