Why was "immediate" attribute added to the EditableValueHolders? - jsf

Initially immediate flag was only intended for ActionSource interface. But later on it was added to the EditableValueHolder interface also. What was the reason for design decision ?

It's to be used to prioritize validation on several EditableValueHolder components in the same form.
Imagine a form containing input components with immediate="true" as well as input components without this attribute. The immediate inputs will be validated during apply request values phase (which is one phase earlier than usual). The non-immediate inputs will be validated during validations phase (which is the usual phase). If validation fails for at least one of the immediate inputs, then the non-immediate inputs won't be converted/validated at all and thus won't generate any conversion/validation error messages. This is particularly useful in forms with complex validation rules where it doesn't make sense to validate component Y when validation for (immediate) component X has failed anyway.
When used in combination with immediate="true" on a command button in the same form, this will cause all non-immediate inputs being completely skipped. A good real world example is a login form with 2 fields "username" and "password" with required="true" and 2 buttons: "login" and "password forgotten". You could put immediate="true" on the "username" field and the "password forgotten" button to skip the required="true" check on the password field.
In the dark JSF 1.x ages, the immediate="true" was also often (ab)used as a hack in combination with valueChangeListener and FacesContext#renderResponse(), more than often in cascading dropdown lists. Long story short, here's an old blog article on that. To the point, it enables developers to execute a backing bean method on change of a <h:selectOneMenu> without that all other inputs in the same form are been validated. But these days, with the ajax awesomeness, this hack is unnecessary. You can find a concretre example of this case at the bottom of our <h:selectOneMenu> wiki page.
These days, the immediate="true" is still often (ab)used in order to have a specific button which completely bypasses all other inputs, such as a logout button in a "God-form" antipattern (whereby everything is been thrown together in a huge <h:form>), or a cancel button which incorrectly submits the form. Such a button would break when you start to actually need the immediate="true" the right way on one of the inputs. You'd better put such a logout button in its own form, or to change it to process only itself (process="#this" in PrimeFaces). And you'd better change such a cancel button to just refresh the page synchronously by <h:button value="Cancel" />. This works fine if the form is tied to a request/view scoped bean and browser caching is disabled on dynamic pages.
See also:
Should immediate="true" never be used when dealing with an AJAXified JSF 2.0 component?
Trying to understand immediate="true" skipping inputs when it shouldn't

Related

Bean value is getting set on click of a cancel button in JSF, How to avoid this? [duplicate]

I have a JSF/PrimeFaces form page set up to edit some configuration details. At the bottom are Submit and Cancel buttons implemented as CommandButton. The Cancel button looks like this:
<p:commandButton
action="priorPage.xhtml?faces-redirect=true"
value="Cancel" />
The problem is that the view bean still winds up doing more processing on the data that's been entered into the form than I'd like. It isn't updating anything in the database, but if (say) I enter a string into a field that's looking for a numeric in the bean, it still produces errors.
Part of my solution is, of course, to get the bean to gracefully handle that sort of bad data, and I'm working on it. But I'd also like to tweak that button so that it just takes the user to the prior page. Is there some attribute I can set that will prevent the form from being processed at all?
The <p:commandButton> submits the form. You don't want to submit the form. You should then not use the <p:commandButton>, but just <p:button>.
<p:button value="Cancel" outcome="priorPage.xhtml" />
See also:
Difference between h:button and h:commandButton

How to stop action delete when reload page in jsf [duplicate]

We're using JSF 2.0 on WebSphere v8.5 with several component libraries PrimeFaces 4.0, Tomahawk 2.0, RichFaces, etc.
I am looking for generic mechanism to avoid form re-submission when the page is refreshed, or when the submit button is clicked once again. I have many applications with different scenarios.
For now I have considered disabling the button with a piece of JavaScript in onclick attribute, but this is not satisfying. I'm looking for a pure Java implementation for this purpose, something like the Struts2 <s:token>.
I am looking for generic mechanism to avoid form re-submission when the page is refreshed
For that there are at least 2 solutions which can not be combined:
Perform a redirect after synchronous post. This way the refresh would only re-execute the redirected GET request instead of the initial request. Disadvantage: you can't make use of the request scope anymore to provide any feedback to the enduser. JSF 2.0 has solved this by offering the new flash scope. See also How to show faces message in the redirected page.
Perform the POST asynchronously in the background (using ajax). This way the refresh would only re-execute the initial GET request which opened the form. You only need to make sure that those forms are initially opened by a GET request only, i.e. you should never perform page-to-page navigation by POST (which is at its own already a bad design anyway). See also When should I use h:outputLink instead of h:commandLink?
or when the submit button is clicked once again
For that there are basically also at least 2 solutions, which could if necessary be combined:
Just block the enduser from being able to press the submit button during the submit and/or after successful submit. There are various ways for this, all depending on the concrete functional and design requirements. You can use JavaScript to disable the button during submit. You can use JSF's disabled or rendered attributes to disable or hide the button after submit. See also How to do double-click prevention in JSF 2. You can also use an overlay window during processing ajax requests to block any enduser interaction. PrimeFaces has <p:blockUI> for the purpose.
Validate uniqueness of the newly added entity in the server side. This is way much more robust if you absolutely want to avoid duplication for technical reasons rather than for functional reasons. It's fairly simple: put a UNIQUE constraint on the DB column in question. If this constraint is violated, then the DB (and DB interaction framework like JPA) will throw a constraint violation exception. This is best to be done in combination with a custom JSF validator which validates the input beforehand by performing a SELECT on exactly that column and checking if no record is returned. A JSF validator allows you to display the problem in flavor of a friendly faces message. See also among others Validate email format and uniqueness against DB.
Instead of creating a token manually, you can use BalusC' solution. He proposed a Post-Redirect-GET pattern in his blog
Alternative solutions can be found in these answers:
Simple flow management in Post-Redirect-Get pattern
How can Flash scope help in implementing the PostRedirectGet (PRG) pattern in JSF2.0
<!--Tag to show message given by bean class -->
<p:growl id="messages" />
<h:form>
<h:inputText a:placeholder="Enter Parent Organization Id" id="parent_org_id" value="#{orgMaster.parentOrganization}" requiredMessage="Parent org-id is required" />
<h:commandButton style="margin-bottom:8px;margin-top:5px;" class="btn btn-success btn-block " value="Save" type="submit" action="#{orgMaster.save}" onclick="resetform()" />
</h:form>
public String save() {
FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().getFlash().setKeepMessages(true); //This keeps the message even on reloading of page
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Your submission is successful.", " ")); // To show the message on clicking of submit button
return "organizationMaster?faces-redirect=true"; // to reload the page with resetting of all fields of the form.. here my page name is organizationMaster...you can write the name of form whose firlds you want to reset on submission
}

PrimeFaces CommandButton that Doesn't Process Data

I have a JSF/PrimeFaces form page set up to edit some configuration details. At the bottom are Submit and Cancel buttons implemented as CommandButton. The Cancel button looks like this:
<p:commandButton
action="priorPage.xhtml?faces-redirect=true"
value="Cancel" />
The problem is that the view bean still winds up doing more processing on the data that's been entered into the form than I'd like. It isn't updating anything in the database, but if (say) I enter a string into a field that's looking for a numeric in the bean, it still produces errors.
Part of my solution is, of course, to get the bean to gracefully handle that sort of bad data, and I'm working on it. But I'd also like to tweak that button so that it just takes the user to the prior page. Is there some attribute I can set that will prevent the form from being processed at all?
The <p:commandButton> submits the form. You don't want to submit the form. You should then not use the <p:commandButton>, but just <p:button>.
<p:button value="Cancel" outcome="priorPage.xhtml" />
See also:
Difference between h:button and h:commandButton

JSF: Button/Link without form submit

In earlier projects I often used an s:button or s:link from Seam 2 when caceling something, because it wouldn't submit the form and thus no model updates occured.
Now I switched to WELD + Seam 3 and couldn't find it there anymore - am I just blind or do I have to use something else?
Geziefer
You can do it in plain JSF 2.0 by setting immediate attribute to true in the h:commandButton.
From the MyFaces wiki:
The immediate attribute can be used to achieve the following effects:
Allow a commandLink or commandButton to navigate the user to
another page without processing any data currently in input fields of
the current screen. In particular, this allows navigation to occur
even when there are currently validation errors. A "cancel" button
typically falls into this category.
Allow a commandLink or commandButton to trigger back-end logic
while ignoring validation for some of the fields on the screen. This
is a more general version of the item above.
Make one or more input components "high priority" for validation,
so that if any of these are invalid then validation is not performed
for any "low-priority" input components in the same page. This can
reduce the number of error messages shown.
I found a way to handle it by using the commandButton from RichFaces 4 and setting bypassUpdates to true:
<a4j:commandButton value="Cancel" action="#{myHandler.cancel}"
bypassUpdates="true" render="myTable" />
For me this solution is ok, since I'm allready using RichFaces 4 - but I'm still interested, how to solve this with standard JSF 2.0?

Skip form validation on command button

I have a JSF page that includes a tree form tag which is rendered depending on some bean property. There are two buttons for next and previous page. I want to skip form validation on the button which goes to the previous page.
I tried the following ways to disable the validation:
Set h:commandButton immediate="true"
Change button by a4j:commandButton ajaxSingle="true" rerender="someparts"
It does not work. Why does the navigation fail when I want to skip validation?
immediate="true" does skip the validation. Make sure you have redeployed successfully, and the there aren't any errors.
I solve problem using a4j:commandButton ajaxSingle="true" reRender=":outhercomponent:formconteningcomponent:component"
reRender needs absolute path to component even if component id unique

Resources