XPages: Create your own Required Validators

If you try to implement your own JSF Validator (by implementing javax.faces.validator.Validator), you will notice that you are unable to check for an empty value. The reason for this is rather simple: The method validate() is only called, if there is something to do. If the value is empty, there is nothing to do, that’s why nothing happens.

But wait! What about the available required validator for XPages?

<xp:inputText id="inputText1">
   <xp:this.validators>
      <xp:validateRequired></xp:validateRequired>
   </xp:this.validators>
</xp:inputText>

And yes, this is a validator, but the IBM implemented a workaround for their UIComponents: If the UIComponents required property is set to true, the UIComponent knows that she needs to be filled in. Or a validator has to be attached to the UIComponent which implements the com.ibm.xsp.validator.FacesRequiredValidator interface.

Here is an example:

package ch.hasselba.xpages.core;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import com.ibm.xsp.validator.FacesRequiredValidator;

public class RequiredValidator implements FacesRequiredValidator {

    public String getRequiredMessage() {
        return "Error! Required field is empty!";
    }

    public void validate(FacesContext facesContext, UIComponent uiComponent,
            Object obj) throws ValidatorException {

    }

}

When processing the UIComponent data, the attached validators are checked if they are an instance of FacesRequiredValidator, and this is the reason why you cannot attach this validator to a component in the DDE directly: Because if you define the validator in the faces-config.xml and add it to the UIComponent with the validator id…

<xp:inputText id="inputText1">
   <xp:this.validators>
      <xp:validator validatorId="myValidator" />
   </xp:this.validators>
</xp:inputText>

… the XPages engine attaches a validator which is not implementing the FacesRequiredValidator interface. Instead, an instance of com.ibm.xsp.validator.ValidatorImpl is attached.

You have to do this by your own, for example in the beforeRenderResponse event:


<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

   <xp:this.beforeRenderResponse>
      <![CDATA[#{javascript:getComponent('inputText1').addValidator(
         new ch.hasselba.xpages.core.RequiredValidator()
      );}]]>
   </xp:this.beforeRenderResponse>

   <xp:button
      value="Label"
      id="button1">
      <xp:eventHandler event="onclick" submit="true"
         refreshMode="complete" immediate="false" save="true" />
   </xp:button>

   <xp:br />

   <xp:messages id="messages1"></xp:messages>

   <xp:br />

   <xp:inputText id="inputText1" />

</xp:view>

[This example is just for a demonstration. It contains a bug, the validator will attached over and over again, so you have to check if the validator is already attached or not]

If you now open the XPage, your validator will work as expected:

 

Dieser Beitrag wurde unter Java, JSF, ServerSide JavaScript, XPages abgelegt und mit , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

4 Kommentare zu XPages: Create your own Required Validators

  1. Paul Withers sagt:

    Thanks, a great tip and will hopefully be the solution to a problem I had last week.

  2. ThanIli sagt:

    A Rookie question:

    Can JSF tags can be used combined with XP tags?

    e.g.

    ???

  3. Dennis Kronbügel sagt:

    Great Tip, thank you.

    To avoid the validator gets added multiple times i just put your code in the afterPageLoad, at the moment i cant see any problems.

    I wrote that, to check the validatorCount on the ‚inputText1‘

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.