JSF custom composite components input.xhtml
<cc:interface>
<cc:attribute name="validator"/>
</cc:interface>
<cc:implementation>
<h:inputText validator="#{cc.attrs.validator}"/>
</cc:implementation>
*.xhtml
<l:input value = ... validator="#{testValidator.validator}"/>
java code
@ManagedBean
public class TestValidator {
public void validator(FacesContext context, UIComponent component, Object value) throws ValidatorException {
System.out.println("Call validator");
}
}
PropertyNotFoundException:
validator="#{testValidator.validator}": The class 'TestValidator' does not have the property 'validator'.
How to solve this problem? my final way:
This is indeed not going to work. In order to attach a validator to an input component specified by the composite, you need to register the input component as a <cc:editableValueHolder>
in the <cc:interface>
first.
<cc:interface>
<cc:editableValueHolder name="yourInputName" targets="yourInputId" />
</cc:interface>
<cc:implementation>
<h:inputText id="yourInputId" ... />
</cc:implementation>
This way, any <f:validator for="yourInputName">
nested in the composite component declaration will be applied to the desired input component.
<l:input>
<f:validator validatorId="myValidator" for="yourInputName" />
</l:input>
You'll only need to replace the tight coupled validator method by a real standalone Validator
implementation.
@FacesValidator("myValidator")
public class MyValidator implements Validator {
// ...
}
Note: the standard JSF validators like <f:validateLength>
, <f:validateRequired>
, etc have all also a for
attribute for this purpose.