NeplatnyUdaj
NeplatnyUdaj

Reputation: 6242

Disable validation for immediate actions

I have a complex page with a p:commanButton with actionListener and immediate="true"

Upon clicking this commandButton, I need to process a single inputField(thus skipping rest of the form). The problem is, that the inputField has a validator which I'd like to use only in full page submit.

<p:inputText id="#{cc.attr.id2}_input" value="#{myBB.value}" 
                 immediate="true">
    <f:validateLength minimum="4"/>
</p:inputText>

<p:commandButton id="#{cc.attr.id2}_search" immediate="true" 
     process="#{cc.attr.id2}_input @this"
     actionListener="#{myBB.listener}">
</p:commandButton>

When I do this with i.e. 3 letters in the inputText, the myBB.value is not updated because of the failed validation. So I'd like to disable the validator for the inputField for the immediate processing by the commandButton. But I don't know how.

I know I can get the value from the ExternalContext, but this seems like a very hacky solution to me(and in my case is not even applicable, because it's inside composite component and I have no way of knowing the clientId of the textField.) I also know about disabled attribute of the validator tag, but I have no idea how could I put that to use in this situation.

EDIT: I've changed a code a bit, because the IDs I'm using are actually not as simple as I first stated and don't allow me to use simple proposed solution.

I use Mojarra 2.2.4 and Primefaces 4.0

Upvotes: 0

Views: 882

Answers (1)

skuntsel
skuntsel

Reputation: 11742

So, first of all, you haven't got the problem with immediate, but rather with <f:validateLength> validator.

That is, to rephrase your question, you'd like to skip validation of a given component in case the particular button is clicked.

Depending on whether you are on Mojarra 2.1.18+ or not there are two solutions. The first one is quite straightforward: use the disabled attribute of <f:validateLength>, while the other one takes into account issue 1492. As we've nowadays have advanced past the aforementioned version of Mojarra, I'll post the first and easier solution, otherwise, scroll through the excellent answers to Why does f:validateDoubleRange only work for @SessionScoped? and Disabled attribute of <f:validateLength> does not evaluate request parameters by BalusC.

So, the solution is the following:

<h:form id="formId">
    <p:inputText id="inputId" value="#{myBB.value}">
        <f:validateLength minimum="4" disabled=#{not empty param['formId:buttonId']}" />
    </p:inputText>
    <p:commandButton id="button" process="@this inputId" actionListener="#{myBB.listener}" />
</h:form>

As a side note, you can see that I didn't use immediate attribute at all because I supposed that you abused it to perform a given task. With the rise of AJAX in particular within JSF-based applications you can now easily group a subset of input elements validation by specifying the process attribute of <p:commandButton> or <p:ajax> instead of the previously used prioritized validation especially in synchronous requests. Only those components whose ids are supplied will be processed on the server and all other components will be omitted prom processing lifecycle. Also note that process="@this ..." is also mandatory to execute actions associated with the button itseld.

Regarding the appropriate usage of immediate I'd strongly suggest to refer to the classics: Debug JSF lifecycle blog post by BalusC to check whether you've used it correctly.

Upvotes: 3

Related Questions