I have a two tab page, one tab is the record list, click on the record will switch to the Edit tab, and there’s Save and Cancel buttons in the Edit tab.
Now, I click on the record #1, do some edit, and click the Cancel button. Certainly I don’t want to validate the form because it’s canceled, so I set immediate="true" on the Cancel button. Now the edit tab is closed, back to the record list. Then, I click on another record #2, the problem occurred: In the edit tab, it’s still the previous content of record #1, rather then record #2. I’ve checked the variables in debug view, the back bean for the edit form was ACTUALLY filled with record #2.
I.e., something broken after an immediate command.
(Everything had been well before I have added the validation and immediate=”true”.)
class FormBean {
Record activeRecord;
...
public void clickOnList() {
activeRecord = loadRecord(clickIndex);
}
public void cancelForm() {
activeRecord = null;
}
}
page.xhtml:
<h:form id="main">
...
<p:tab title="Edit" rendered="#{formBean.activeRecord != null}">
...
<p:commandButton value="Cancel"
actionListener="#{formBean.cancelForm}"
update="main" async="true" immediate="true" />
</p:tab>
</h:form>
The
immediate="true"doesn’t work nicely with ajax requests on the same view. It boils down to that the submitted-but-not-validated values are still there in the input components. Without ajax, a normal synchronous request/response of a subsequent form submit would silently “solve” this. But with ajax, this does not happen. The submitted values of the previous ajax request are still there in the input components. WhenUIInput#getSubmittedValue()doesn’t returnnull, it will be displayed instead, irrespective of the (changed) model value.Basically, when you want to stick to ajax for a cancel button, you need to exclude the inputs from being processed instead of relying on the
immediate="true"(which is actually kind of a hack). In standard JSF<f:ajax>terms, you could do this withexecute="@this"(which is actually the default) on the button instead ofexecute="@form". The PrimeFaces buttons defaults to@form, so you need to change this: