0

I have a simple form like the one below with two buttons.

<h:form>

    <h:inputText required="#{empty param[save.clientId]}"
        value="#{bean.a}" id="a" />

    <h:inputText required="#{empty param[save.clientId]}"
        value="#{bean.b}" id="b" />

    <h:commandButton binding="#{save}" value="WORKING SAVE JSF"
        action="#{bean.submit}">
    <f:ajax execute="@form" render="@none" />
    </h:commandButton>

    <h:commandButton value="WORKING SUBMIT JSF" action="#{bean.submit}">
    <f:ajax execute="@form" render="@none" />
    </h:commandButton>

One button (save) should only pass the values (and exactly the values) to the model without validation. The second one (submit) should validate the input fields and if there is no error, pass to the model.

It does work without <f:ajax> or with <p:commandButton>. But simply not with <f:ajax>

How can I achieve this?

alexander
  • 1,191
  • 2
  • 20
  • 40
  • 2
    There are several related (almost) identical questions on stackoverflow. Try what is in them first – Kukeltje Apr 26 '15 at 21:30
  • So similar to this question I answered last week: http://stackoverflow.com/questions/29848032/omit-validation-for-pselectonemenu-for-ajax-requests/29848568#29848568 – Aritz Apr 27 '15 at 09:16
  • none of them seem to work for `f:ajax`. – tt_emrah Apr 27 '15 at 09:18
  • I agree with tt_dev. It's all about ``. It is also working without ` fine. See updated question. – alexander Apr 27 '15 at 09:20

2 Answers2

1

here is a working example.

on xhtml level, you should set a custom validator to your input fields:

    <h:form id="form">      
        <h:inputText value="#{bean.a}" >
            <f:validator validatorId="myCustomValidator"/>
        </h:inputText>
        <h:inputText value="#{bean.b}" >
            <f:validator validatorId="myCustomValidator"/>
        </h:inputText>

        <h:commandButton id="noValidationButton" action="#{bean.submit}" value="Submit only">
            <f:ajax execute="@form" render="@form" />
        </h:commandButton>
        <h:commandButton action="#{bean.submit}" value="Submit and validate">
            <f:ajax execute="@form" render="@form" />
        </h:commandButton>
        <h:messages/>
    </h:form>

this custom validator class should check the event source by its exact id on rendered html (form:noValidationButton in this case), and just return if the button for "no validation" is clicked. it will look like this:

@FacesValidator("myCustomValidator")
public class MyCustomValidator implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String[] eventSource = ((HttpServletRequest)context.getExternalContext().getRequest()).getParameterMap().get("javax.faces.source");
        if (eventSource != null && 
            eventSource.length > 0 &&
            eventSource[0].equals("form:noValidationButton"))
        {
            return;
        }
        else
        {
            // do regular validation here
            if (value == null || value.equals(""))
            {
                throw new ValidatorException(new FacesMessage("failed."));
            }
        }
    }
}

the web.xml configuration below makes sure that jsf validates all submitted input values, even if they are left empty.

<context-param>
    <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
    <param-value>true</param-value>
</context-param>
tt_emrah
  • 1,043
  • 1
  • 8
  • 19
  • That is looking nice. I have no time to test it now (You know why). I will comment it in a couple days. Can you please add some explanation? – alexander Apr 27 '15 at 15:13
  • sure, i had limited time when i first submitted the answer. i provided some explanation now. – tt_emrah Apr 27 '15 at 17:57
  • On my testpage it is working like a charm! I will implement this to my current app. Thank you! – alexander May 11 '15 at 08:01
  • Do you know, how I can add a buttons which are present in a ` to the if-condition? I am struggeling with this. Those have all `IDs` like `:form:datatableID:index:buttonID` – alexander Jul 24 '15 at 19:00
  • 1
    @Alexander just check `eventSource[0].endsWith("noValidationButton")`, don't bother with the prior part of the id. but make sure you `execute` only the current (clicked) row with the ajax request. – tt_emrah Jul 27 '15 at 14:50
0

To skip validation you can do like this-

<h:inputText required="#{param['req']=='1'}"
    value="#{bean.a}" id="a" />

<h:commandButton binding="#{save}" value="WORKING SAVE JSF"
    action="#{bean.submit}">
<f:ajax execute="@form" render="@none" />
<f:param id="req" value="1"/>
</h:commandButton>

Gaurav Jeswani
  • 4,410
  • 6
  • 26
  • 47
  • How can I add a second button, where the validation is triggered correctly? The 'do not validate-thing' does indeed work. – alexander Apr 27 '15 at 12:19
  • Sorry i am not able to understand your question properly, would you elaborate? – Gaurav Jeswani Apr 27 '15 at 13:05
  • Basically: Two buttons. One should pass values without validation (ignore requried = true) and the other one should validate and pass values. – alexander Apr 27 '15 at 13:39
  • So according to thia the button in which you pass the parameter will check validation and one in which you won't pass parameter will skip validation. – Gaurav Jeswani Apr 27 '15 at 13:49
  • Yes exactly. But how does the second button looks like? I tried some cases, but they dosnt work correctly. You may have a hint for me? – alexander Apr 27 '15 at 13:52