我正在构建一个自定义控件来格式化我的 Bootstrap 输入控件。我验证数据的方式我有一个带有验证方法的 bean(遵循 validator 的方法签名)。但是,我找不到通过自定义控件属性指定 validator 的方法...
这是“正常的”inputText 控件:
<xp:inputText xp:key="inputControl" id="inputCity" value="#{User.user.city}"
validator="#{User.validate}">
<xp:this.attrs>
<xp:attr name="placeholder" value="Enter city"></xp:attr>
</xp:this.attrs>
<xp:this.validators>
<xp:validateRequired message="You must enter a city"></xp:validateRequired>
</xp:this.validators>
</xp:inputText>
这是来自自定义控件的:
<xp:inputText type="text" id="inputText1" value="#{compositeData.dataSource[compositeData.fieldName]}"
required="${compositeData.required}" disableClientSideValidation="true" validator="${compositeData.dataValidator}">
<xp:this.attrs>
<xp:attr name="placeHolder" value="${compositeData.placeHolder}"></xp:attr>
</xp:this.attrs>
<xp:this.validators>
<xp:validateRequired message="${compositeData.helpText}"></xp:validateRequired>
</xp:this.validators>
</xp:inputText>
<xp:message id="message1" for="inputText1"></xp:message>
... 在 XPage 上我尝试这样调用它:
<xc:field fieldName="city" dataSource="#{User.user}" placeHolder="Enter city" fieldLabel="City" required="true"
helpText="You must enter a city" dataValidator="#{User.validate}">
</xc:field>
“dataValidator”被指定为“com.ibm.xsp.validator.ValidatorImpl”——我也尝试过使用“object”……——但同样的错误 500:
> Page Name: /editUser.xsp javax.faces.el.PropertyNotFoundException:
> Error getting property 'validate' from bean of type
> dk.dtu.aqua.catchlog.bean.UserBean at
> com.sun.faces.el.PropertyResolverImpl.getValue(PropertyResolverImpl.java:119)
> at
> com.ibm.xsp.el.PropertyResolverImpl.getValue(PropertyResolverImpl.java:144)
很明显,自定义控件试图将其作为属性读取(通过隐式“getter”)。
有什么想法吗??
编辑:
好的,在与 Toby Samples 来回写了一些内容之后,我尝试将 bean 注册为 faces-config.xml 中的 validator 并给它一个 id。这似乎奏效了 - 在某种程度上。
在自定义控件中,我删除了“validator”属性并在 attrs 下添加了一个“validator”:
<xp:validator validatorId="${compositeData.validatorId}"></xp:validator>
在我从 XPage 调用它的地方我添加了新属性(作为字符串):
<xc:field fieldName="city" dataSource="#{User.user}" placeHolder="Enter city" fieldLabel="City" required="true"
helpText="You must enter a city" validatorId="userValidator">
</xc:field>
但是,我真正想要的是使用一个包含所有 Bootstrap 格式的通用 CC,以及一个可以放置各种输入类型(例如 inputText、comboBox 等)的可编辑区域。这样 Bootstrap 标记的结构是相同的,而无需一遍又一遍地复制相同的代码。
因此,如果我创建一个新的 CC,请使用以下内容(为简单起见)说 fieldLayout:
<xp:label value="#{compositeData.label}" for="#{compositeData.inputField}"></xp:label>
<xp:div styleClass="col-sm-6">
<xp:callback facetName="inputControl" id="callback1"></xp:callback>
</xp:div>
然后将它放到我的字段 CC(在开头提到)中,我将所有的都放入可编辑区域 - 具有相同的属性等,这样它现在看起来像这样:
<xc:fieldLayout label="#{compositeData.label}" inputField="inputText1">
<xp:this.facets>
<xp:inputText xp:key="inputControl" type="text" id="inputText1" value="#{compositeData.dataSource[compositeData.fieldName]}"
required="${compositeData.required}" disableClientSideValidation="true">
<xp:this.attrs>
<xp:attr name="placeHolder" value="${compositeData.placeHolder}"></xp:attr>
</xp:this.attrs>
<xp:this.validators>
<xp:validator validatorId="${compositeData.validatorId}"></xp:validator>
<xp:validateRequired message="You must enter something"></xp:validateRequired>
</xp:this.validators>
</xp:inputText>
<xp:message id="message1" for="inputText1"></xp:message>
</xp:this.facets>
</xc:fieldLayout>
然后失败....并出现以下错误:
Caused by: java.lang.NullPointerException: Argument Error: One or more parameters are null. validatorId null
at com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:630)
at com.ibm.xsp.application.ApplicationExImpl.createValidator(ApplicationExImpl.java:1161)
at com.ibm.xsp.validator.ValidatorImpl.getValidator(ValidatorImpl.java:75)
at com.ibm.xsp.validator.ValidatorImpl.validate(ValidatorImpl.java:48)
at javax.faces.component.UIInput.validateValue(UIInput.java:828)
这可能与 compositeData.validatorId 现在在另一个 CC 的构面内的 inputText 中引用的事实直接相关。请注意,我将“validateRequired”消息更改为字符串文字。因此,当我在没有输入任何内容的情况下进行测试时,它会给我该消息。如果我只输入一个字符,它会改为调用 validator - 或尝试,因为这样会抛出异常...... :-(
有什么想法吗?这会严重影响自定义控件的使用 - 除非我做的完全错误...?
/约翰
最佳答案
您可以尝试在 xp:validator validator 中使用 validatorId。
人脸配置
<validator>
<validator-id>val</validator-id>
<validator-class>com.tobysamples.validators.user</validator-class>
</validator>
自定义控件
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:inputText>
<xp:this.validators>
<xp:validator validatorId="${compositeData.val}"></xp:validator>
</xp:this.validators></xp:inputText>
</xp:view>
X页面
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xc:inputfield val="val">
</xc:inputfield>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
</xp:eventHandler></xp:button></xp:view>
自定义控件定义
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<faces-config-extension>
<namespace-uri>http://www.ibm.com/xsp/custom</namespace-uri>
<default-prefix>xc</default-prefix>
</faces-config-extension>
<composite-component>
<component-type>inputfield</component-type>
<composite-name>inputfield</composite-name>
<composite-file>/inputfield.xsp</composite-file>
<composite-extension>
<designer-extension>
<in-palette>true</in-palette>
</designer-extension>
</composite-extension>
<property>
<property-name>val</property-name>
<property-class>string</property-class>
<display-name>val</display-name>
<property-extension>
<designer-extension>
<editor>com.ibm.std.String</editor>
</designer-extension>
</property-extension>
</property>
</composite-component>
</faces-config>
新的二次抄送
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
<xc:field val2="${compositeData.val}">
<xp:this.facets>
<xp:inputText xp:key="inputControl">
<xp:this.validators>
<xp:validator validatorId="${compositeData.val2}"></xp:validator>
</xp:this.validators></xp:inputText>
</xp:this.facets>
</xc:field>
</xp:view>
关于java - 如何将 validator 指定为自定义控件的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21607408/