Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

jsf - Add global message when field validation fails

Usually the PrimeFaces tag for messages shows the global as well as the field specific messages. What I want to do is to just show the global messages (globalOnly="true") but also show a common message if the validation of any field fails. No matter how many fields fail, just one message like 'Please correct your data'. The field specific errors are already shown next to the input fields so no need to display them twice.

I'm using composite components for each of my inputs (Textbox, Dropdown, Radios, ...). The validation of each field should be done on blur with textboxes and probably on valuechanged for dropdowns and radios.

Now there are two types of validation I want to handle. First is the standard validators brought by JSF itself. required="true" for example, but also validateRegex, validateLength, ...

And then there are values I've to check against another backend. For those I would probably create methods in my bean and call them as listener of my

<p:inputText id="#{cc.attrs.name}"
             value="#{cc.attrs.val}"
             styleClass="#{cc.attrs.iconClass}"
             required="#{cc.attrs.required}"
             requiredMessage="#{cc.attrs.requiredMessage}">
    <p:ajax event="blur" process="@form" update="outer-wrapper" 
            listener="#{cc.attrs.someValidationMethod}" />
</p:inputText>

So basically I want to have just one global message if any of the field validations fails. I know could just render an additional box with rendered="#{facesContext.validationFailed}" but I prefer to have a global message. Is there a out-of-the-box setting or does it have to be implemented?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I use a phase listener to do so. This is roughly my implementation (using OmniFaces):

public class ValidationFailedListener implements PhaseListener {

  @Override
  public PhaseId getPhaseId() {
    return PhaseId.RENDER_RESPONSE;
  }

  @Override
  public void beforePhase(PhaseEvent event) {
    if (Faces.isValidationFailed()) {
      Messages.addGlobalError("Your validation failed message");
    }
  }

  @Override
  public void afterPhase(PhaseEvent event) {
    // NOOP
  }

}

You should register it in your faces-config.xml:

<lifecycle>
  <phase-listener>your.ValidationFailedListener</phase-listener>
</lifecycle>

My actual implementation uses a message bundle to display a localized message.


If you cannot use OmniFaces, here is the relevant code using vanilla JSF:

if (FacesContext.getCurrentInstance().isValidationFailed()) {
  FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                                          "Your validation failed message",
                                          null);
  FacesContext.getCurrentInstance().addMessage(null, message);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...