0

I've run into a problem validating a certain input (email) before submitting the whole object..

jsf looks like this:

<h:panelGroup id="reportingRecipientTable">
    <table cellspacing="0" class="table no-footer" width="100%" style="word-wrap: break-word;">
        <thead>
            <tr>
                <th><h:inputText p:type="email" p:placeholder="Add a valid Email address" value="#{viewModel.reportingRecipient}"
                        styleClass="form-control #{component.valid ? '' : 'has-errors'}">
                        <f:ajax execute="@this" />
                    </h:inputText></th>
                <th class="col-sm-3">
                    <div class="text-center">
                        <h:commandLink immediate="true" style="width:95px" styleClass="btn btn-default" actionListener="#{viewModel.addReportingRecipient}">
                            <i class="icon-plus" /> Add
                            <f:ajax render="reportingRecipientTable" />
                        </h:commandLink>
                    </div>
                </th>
            </tr>
        </thead>
        <tbody>
            <c:forEach items="#{viewModel.getReportingRecipients()}" var="reportingRecipient">
                <tr>
                    <td><h:outputText required="true" value="#{reportingRecipient}" styleClass="form-control" /></td>
                    <td class="col-sm-3">
                        <div class="text-center">
                            <h:commandLink styleClass="btn btn-default" style="width:95px" actionListener="#{viewModel.removeReportingRecipient(reportingRecipient)}">
                                <i class="icon-trash" /> Remove
                                <f:ajax render="reportingRecipientTable" />
                            </h:commandLink>
                        </div>
                    </td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
</h:panelGroup>

As you see, I'm adding a (supposedly valid) email address to a tablerow before submitting everything: enter image description here

    public void addReportingRecipient() {
        if (!Utils.isNullOrBlank(reportingRecipient) && reportingRecipient.matches("(^.*@.*\\..*$)")) {
            getReportingRecipients().add(reportingRecipient);
            this.reportingRecipient = "";
        } else{ //not valid
              }
    }

Well, this works (email is only added if it matches the pattern), missing one little detail: I want to mark the "inputText" as invalid (styleClass="form-control #{component.valid ? '' : 'has-errors'}") if it isnt a valid email address. adding a validator to the inputText like this:

<h:inputText p:placeholder="Add a valid Email address" validator = "#{emailValidator.isCorrectEmail}" value="#{viewModel.reportingRecipient}"
                        styleClass="form-control #{component.valid ? '' : 'has-errors'}">

does only work if i hit the final submit button - but i want to mark the field invalid the moment the user tries to add an invalid email.

Anyone got an idea/some hints?

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
mc_k
  • 41
  • 1
  • 5
  • Jspf validators are server-side, this is expected. If you want view-side validations, you'll have to implement them in Javascript. – M. Prokhorov Aug 24 '20 at 11:03
  • 1
    @M.Prokhorov: No this is not automatically expected. OP uses ajax so when a field is submitted it is directly validated. Yes, server-side, but not only on submission. OP should start with a basic jsf/ajax/validation tutorial since several basic errors are made. All can be fixed without adding client-side javascript... – Kukeltje Aug 24 '20 at 12:21
  • @Kukeltje, Ok then, good to know. – M. Prokhorov Aug 24 '20 at 12:48
  • I disagree in that this question is a duplicate of the ones at the top of the question. Yes, valid information in addition for validation, but not duplicates – Kukeltje Aug 24 '20 at 13:17

1 Answers1

0

Your code example of using a validator is the right way to go. Don't validate in business methods.

<h:inputText p:type="email" p:placeholder="Add a valid Email address" value="#{viewModel.reportingRecipient}"
                    styleClass="form-control #{component.valid ? '' : 'has-errors'}">
    <f:ajax execute="@this" />
</h:inputText></th>

Does correctly use #{component.valid...} to style the component. But it does not work on the ajax call because you do not (re)render the input on the ajax event. The default is for an f:ajax is render="@none", so nothing is updated. Adding a render="@this" or if you also want to display a message some other id will make it work.

The fact that it works on 'Remove' button is because the ajax call on the input has already updated the state and you do render the complete table. So the input is (re)renderd.

See also

Kukeltje
  • 11,924
  • 4
  • 19
  • 44