Immediate="true" causes update="component" to fail - jsf-2

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

Related

Using forms on multiple tabs to edit a single entity

In my application I have implemented a page where the user can edit its account information. Since there are a lot of fields I have broken them up into p:tab elements inside a p:tabView. Like this:
<p:tabView dynamic="true" rendered="#{account.accessOK}">
<p:tab title="Basic Information">
<h:form id="formBasic">
(some fields here)
<p:commandButton value="Save"
action="#{account.doSave()}"
update="formBasic msgs"
/>
</h:form>
</p:tab>
<p:tab title="Address">
<h:form id="formAddress">
(fields related to address here)
<p:commandButton value="Save"
action="#{account.doSave()}"
update="formBasic msgs"
/>
</h:form>
</p:tab>
<p:tab title="E-Mail & Phone Numbers">
(then another form here with more field)
</p:tab>
<p:tab title="Password">
<h:form id="formPass">
<p:panelGrid columns="3">
(and this form handles the password)
<p:commandButton value="Change"
action="#{account.doPassword()}"
update="msgs"
/>
</h:form>
</p:tab>
</p:tabView>
This seems pretty straightforward but there is a problem. Each tab has its own form so that the fields that gets processed when the user hits the p:commandButton are only those in the form. However the following sequence will probably confuse the user:
Change some fields on one tab but do not click the Save button.
Go to another tab and fill in fields there, then click the Save button. The fields on that form will be processed.
Go back to the tab edited in step 1 above and the fields will look like they have been processed, but have not. It will be a filled out form but no visual way to tell that the fields have not been saved.
Note that I do not want to put all the tabs into one form and execute all the fields on all the tabs at once. This is because some field changes might have side effects, such as setting the password. Also you don't want a validation pass to happen on fields that the user isn't changing during this visit.
So is there any method to solve this user interface deficiency?

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

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.

Logout Link is not working

I am using JSF and Primefaces in my web application.
In this i am using one form which includes some some details to be filled by student.
So there is some validation on that fields
And, On this page there are two button one is Submit and Other is Logout
When I pressed submit button form is displaying validation error if details are not completed.
But Same things also shown while pressing LOGOUT link also
Logout is p:commadLink
<p:commandLink styleClass="logout" type="submit" action="#{userManagedBean.logout}">
<p:graphicImage value="/images/logout.png"></p:graphicImage>
</p:commandLink>
Submit is h:commandButton
<h:commandButton image="/images/submit_button.png" type="submit" action="#{referManagedBean.saveDetails}" value="submit"></h:commandButton>
I need Logout link skip this validation step and directly goes to managed bean called function.
How can i skip Validation Step ??
Since the log-out action seems that has nothing to do with the details form (being validated), you could just move the button to different form (h:form) so it wouldn't trigger the details form validation anyway.
I solved my problem i used immediate="true" by which it skips the validation phase.
<p:commandLink styleClass="logout" type="submit" immediate="true" action="#{userManagedBean.logout}">
<p:graphicImage value="/images/logout.png"></p:graphicImage>
</p:commandLink>

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

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.

Resources