Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF immediate="true" for cancel button doesn't work

Tags:

jsf-2

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>
like image 831
Xiè Jìléi Avatar asked Oct 10 '11 02:10

Xiè Jìléi


1 Answers

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. When UIInput#getSubmittedValue() doesn't return null, 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 with execute="@this" (which is actually the default) on the button instead of execute="@form". The PrimeFaces buttons defaults to @form, so you need to change this:

<p:commandButton value="Cancel"
    actionListener="#{formBean.cancelForm}"
    update="main" async="true" process="@this" />
like image 77
BalusC Avatar answered Sep 16 '22 16:09

BalusC