9

I have specific use case for JSF validation. For example I have an inputText field:

<p:inputText id="input" required="#{myBean.required}" value="#{myBean.value}" maxlength="20" disabled="#{myBean.disabled}">
  <p:ajax event="blur" process="@this" update="name" listener="#{myBean.listener}"/>
</p:inputText>

Value of input is number (in some cases it can also be a string, because this is part of composite component, but problem is better described if we assume this is a number). This input is part of the form, at the end of form I have submit button:

<p:commandButton value="Save" actionListener="#{myBean.save}"/>

What are my requests:

  1. When submit button is pressed all validation should be processed and this is OK, this works fine.
  2. When blur event is fired on input field if field is not empty a number validation should be processed, and this is also OK. At the end I update field with id name with some value.
  3. Now I have a problem. My third request is when input is empty validation on input should not be processed. This is special case in which I will clear field with id name. This is also case when i remove text which is already entered in input, remove focus from component (press TAB for example) and in that case AJAX request should also be processed and name input will also be cleared.

How I can disable validation of this input field in case when it is empty, and just for this ajax event?

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
partlov
  • 13,789
  • 6
  • 63
  • 82

2 Answers2

12

Let the input's required attribute check if the save button is pressed or not (which can be identified by the presence of its client ID in the request parameter map).

<h:form>
    <p:inputText ... required="#{not empty param[save.clientId] and myBean.required}" />

    <p:commandButton binding="#{save}" ... />
</h:form>

(note: do not bind it to a bean property! the code is as-is)

This way it would only evaluate true when the save button is actually pressed.

Or, if you have problems with binding and/or don't have a problem hardcoding the button's client ID:

<h:form id="formId">
    <p:inputText ... required="#{not empty param['formId:buttonId'] and myBean.required}" />

    <p:commandButton id="buttonId" ... />
</h:form>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • You think that required validation will be skipped in that case? Why? – partlov Feb 06 '13 at 14:17
  • As long as you don't fill (and thus change) the input, the validation won't be fired on blur. – BalusC Feb 06 '13 at 14:22
  • Maybe I was not clear with specific use case in third request. I edited it. User can (probably accidentally) remove text and in that case name input will be cleared. – partlov Feb 06 '13 at 14:30
  • Oh, wouldn't have expected that. Well, just let `required` attribute check if save button is pressed. See edited answer. – BalusC Feb 06 '13 at 14:31
  • As I use `@ViewScoped` backing bean I would prefer not to use `binding`. Maybe some `f:param` can be used instead? – partlov Feb 06 '13 at 14:38
  • Uh, the code in the answer doesn't bind the component to a view scoped bean property. It just binds directly to the view itself. The code in the answer is complete as-is. You don't need to declare a `save` property anywhere in some bean class or something. I would otherwise have mentioned that explicitly in the answer and have demonstrated by `#{myBean.save}` or something. – BalusC Feb 06 '13 at 14:52
  • I am trying to use this with MyFaces 2.0, but it doesn't work. Is it something to do with primefaces only? I tried MyFaces bundled with WebSphere 9.0.5.7 – Mohammad Ashfaq Jun 01 '23 at 09:12
  • The solution here only works for regular HTTP Post form submissions, not for Ajax requests.. If the request is done via AJAX, then check will need to be different since the source is sent as part of the `javax.faces.source` name, value pair. – volosied Jun 07 '23 at 17:54
  • @volosied: that's probably a bug or overoptimization in JSF impl being used. – BalusC Jun 07 '23 at 18:18
  • Yep, it was a bug. It's fixed here in MyFaces: https://issues.apache.org/jira/browse/MYFACES-4606 – volosied Jul 18 '23 at 18:21
2

Just remove the required attribute as you accept the input if the input is empty. Then write a custom validator which accepts only empty input or numerical input.

<p:inputText id="input" value="#{myBean.value}" maxlength="20" disabled="#{myBean.disabled}" validator="customerNumericInputValidator">   <p:ajax event="blur" process="@this" update="name" listener="#{myBean.listener}"/> </p:inputText>
public class customerNumericInputValidator implements Validator {

    @Override
    public void validate(FacesContext facesContext, UIComponent uIComponent,
            Object object) throws ValidatorException {

        String number = (String) object;
        number = Strings.nullToEmpty(number).trim();

        //if the request is a full request then number can not be empty
        if(!FacesContext.getCurrentInstance().isPostback() && Strings.isNullOrEmpty(number))
        {
             FacesMessage message = new FacesMessage();
             message.setSummary(Messages.getMessage("error empty value"));
             message.setSeverity(FacesMessage.SEVERITY_ERROR);
             throw new ValidatorException(message);
        } 

        if(!Strings.isNullOrEmpty(number))
        { 
            if(!isNumber(number))
            {
               FacesMessage message = new FacesMessage();
               message.setSummary(Messages.getMessage("error not numerical value"));
               message.setSeverity(FacesMessage.SEVERITY_ERROR);
               throw new ValidatorException(message);
            }
        }
    }

}
Community
  • 1
  • 1
cubbuk
  • 7,800
  • 4
  • 35
  • 62
  • But required validation should be processed in case when form is submitted with `commandButton`. – partlov Feb 06 '13 at 13:23
  • When form is submitted with commandButton your customValidator will be executed also and it will throw an exception if the entered value is not number; but it won't complain if the input is empty. – cubbuk Feb 06 '13 at 13:26
  • OK, in request 1 I wrote that when form is submitted with button, required must not be ignored! We can say that field is required when submitting with button, but should not be required when submitting with ajax on blur event. – partlov Feb 06 '13 at 13:29
  • Ok then you might check whether the request is an ajax request or not in your validator and process your input according to that. I updated my answer to show you an example. – cubbuk Feb 06 '13 at 13:37
  • As you can see, this Prmefaces `commandButton` is also AJAX :), so no it can't be processed like that. It should be little more robust component (it is, as I wrote, part of composite component). – partlov Feb 06 '13 at 13:42
  • In your question the commandButton is not making an ajax call =) Well I guess lets wait for BalusC's answer, most probably he will come up with the most efficient solution :) – cubbuk Feb 06 '13 at 13:48
  • Bu default in Primefaces, commandButton is AJAX, you should explicitly set it to false. Please read reference. – partlov Feb 06 '13 at 13:49
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24037/discussion-between-cubbuk-and-partlov) – cubbuk Feb 06 '13 at 13:56