validator method not work in the JSF custom composite components

十年热恋 提交于 2019-12-08 03:02:27

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.

You'll only need to replace the tight coupled validator method by a real standalone Validator implementation.

BalusC, what if I like my tight coupled validator, for example if validation of this component depends on some state kept in my backing bean? I know this isn't proper componentized design, but it is what it is, which is temporary stop-gap solution to keep our backend developers going until I can develop a more full-featured component.

You need to define a cc:attribute "validator" with targets attribute:

<cc:interface>
    <cc:attribute name="validator" targets="inputId"/>
</cc:interface>

<cc:implementation>
    <h:inputText id="inputId"/>
</cc:implementation>

(Notice that I don't define validator attribute in h:inputText)

This is easy as long as you don't implement component class for your composite component. Well... even then it is easy, but it won't work if your component class extends UIInput. It works if it extends UINamingComponent class (I am not sure if this is the best solution, or if you can make it work with UIInput but it works).

So if you want to have your own component class try this one:

<cc:interface componentType="myComponent>
    <cc:attribute name="validator" targets="inputId"/>
</cc:interface>

<cc:implementation>
    <h:inputText id="inputId"/>
</cc:implementation>
@FacesComponent("myComponent")
public class MyComponent extends UINamingContainer {

    @Override
    public String getFamily() {
        return UINamingContainer.COMPONENT_FAMILY;
    }

    //your code here

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!