>I've been trying to get a custom validator working with Clay, but so far I 
>haven't figured out how to do it.
>
>I have a class named "a.b.c.IPAddressValidator" that validates that a String 
>is 
>a valid dotted-decimal IP address, as its name implies.  I've registered in my 
>faces-config under the validator-id "a.b.IPAddress".  
>
>It works fine when I invoke it using JSP (i.e., using <f:validator 
>validatorId="a.b.IPAddress" /> nested within a <h:input> element).
>
>However, I have not been able to get it to work with Clay views defined either 
>in HTML or XML.
>
>I tried this:
>
><component jsfid="my:inputIPAddress" extends="t:inputText">
>   <element renderId="0" jsfid="f:validator">
>      <attributes>
>         <set name="validatorId" value="a.b.IPAddress" />
>      </attributes>
>   </element>
></component>
>

There are a couple of flavors of JSF Validators.  One flavor allows using a 
method binding expression to a managed bean callback.  Components that realize 
the EditableValueHolder interface provide a "validator" attribute.


Using this method, you would need the following clay XML config.
<component jsfid="my:inputIPAddress" extends="t:inputText">
      <attributes>
         <set name="validator" value="#{mybean.validateIPAddress}" />
      </attributes>
   </element>
</component>


Your managed bean registered as "mybean" would have the following callback 
method.

public void validateIPAddress(FacesContext context, UIComponent input, Object 
value) {
...
} 

>but I got the error "Undefined component type override", presumably because 
>the 
>clay-config.xml that comes with Clay defines "f:validator" with a 
>componentType 
>of "override".
>
>I also tried this (as XML and also in the equivalent HTML using span tags):
>
><component jsfid="my:validateIPAddress" componentType="a.b.IPAddress" 
>extends="validator">
></component>
>
><component jsfid="my:inputIPAddress" extends="t:inputText">
>   <element renderId="0" jsfid="my:validateIPAddress" />
></component>
>
>but that resulted in the error "Undefined component type a.b.IPAddress".
>
>I also tried swapping out my validator with the f:validateLongRange validator, 
>with the same result.
>
>
>How do I get this to work?  The only examples of validation in the Clay intro 
>page show it being done with managed bean methods and the "validator" 
>attribute.
>


There is a second way to register a validator in the clay XML config.  The 
"component" and "element" allow a nested "validator" node.  In this case, the 
jsfid needs to point to a top-level component  definition that defines the 
validator.  The componentType captures the validatorId.

<component jsfid="myvalidator" componentType="a.b.IPAddress">
   <attributes>
      .....
   </attributes>
</component>

<component jsfid="my:inputIPAddress" extends="t:inputText">
    ...
    ...
    <validator jsfid="myvalidator">
       <attributes>
           .... overrides - like an an anonymous inner class
       </attributes>
    </validator>
</component>

Now, the nomenclature is getting in the way.  The Clay metadata is not really 
JSF component specific. We use the component node to represent, components, 
validators, converters and listeners.  At one time it was called 
"displayElement".


There is yet another way to define a validator.  If you are using the html 
namespaces, you would use JSP syntax.

<span jsfid="void" xmlns:f="http://java.sun.com/jsf/core"; 
      xmlns:t="http://myfaces.apache.org/tomahawk";>
    
   <t:inputText ...>
      <f:validator validatorId="a.b.IPAddress"/>
   </t:inputText>
</span>

Or, yet another...

<span jsfid="void" 
      xmlns:clay="http://shale.apache.org/xml/clay";>
    
    <clay:element jsfid="t:inputText">
      <clay:attributes>  
          <clay:set..../>
      </clay:attributes> 
      <clay:validator jsfid="a.b.IPAddress"/>
   </clay:element>
</span>


>
>Rich Eggert
>Member of Technical Staff
>Proteus Technologies, LLC
>http://www.proteus-technologies.com


Gary

Reply via email to