【问题标题】:Xpages Reusable Bootstrap fields bound to a java bean: validation绑定到 java bean 的 Xpages Reusable Bootstrap 字段:验证
【发布时间】:2016-03-09 17:00:30
【问题描述】:

我找到了一个 Bootstrap 可重复使用的字段自定义控件,并一直在我的最新项目中使用它。它运行良好,但验证是由 Xpage 中的 SSJS 完成的,我将尽可能多地从 Xpage 中移出编程并进入 Java bean。

我在我的 bean 中进行了验证,但它将错误放在表单顶部的显示错误控件中。我希望我的 Java 验证使用 Bootstrap 样式错误。

我在BootstrapForXpages site 上找到了一个很好的讨论。

StackOverflow addressed this same issue 中的另一个问题,但我无法弄清楚如何让它工作。

How to use XPages Java code to set valid method of input control inside a custom control?

这里是字段 CC

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:div>
        <xp:this.styleClass><![CDATA[#{javascript:"form-group" + ( getComponent("inputText1").isValid() ? "" : " has-error" )}]]></xp:this.styleClass>
        <xp:label styleClass="col-sm-2 control-label" for="inputText1"
            value="${compositeData.fieldLabel}" />
        <div class="col-sm-10">
            <xp:inputText type="text" id="inputText1"
                loaded="${!empty compositeData.placeholder}" value="#{compositeData.dataSource[compositeData.fieldName]}"
                required="${compositeData.required}">
                <xp:this.attrs>
                    <xp:attr name="placeholder" value="${compositeData.placeholder}" />
                </xp:this.attrs>
                <xp:this.validators>
                    <xp:validateRequired
                        message="#{javascript:compositeData.fieldLabel + ' is required'}" />
                </xp:this.validators>
            </xp:inputText>
            <xp:text escape="true" id="computedField1" styleClass="help-block"
                value="${compositeData.helpText}">
                <xp:this.rendered><![CDATA[#{javascript:getComponent("inputText1").isValid() && compositeData.helpText != null}]]></xp:this.rendered>
            </xp:text>
            <xp:message id="message1" for="inputText1" styleClass="help-block" />
        </div>
    </xp:div>
</xp:view>

以及带有控件的简单 Xpage 的代码:

<?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"
    xmlns:xe="http://www.ibm.com/xsp/coreex">   
    <xc:ccCustomField placeholder="Enter your email address"
        fieldLabel="Email" helpText="Guess what you have to enter here..."
        fieldName="model">
        <xc:this.dataSource>
            <xe:objectData var="PCModel">
                <xe:this.createObject><![CDATA[#{javascript:var pc = new com.scoular.data.PC().create();
return pc;}]]></xe:this.createObject>
            </xe:objectData>
        </xc:this.dataSource>
    </xc:ccCustomField>
</xp:view>

【问题讨论】:

  • com.scoular.data.PC 类有属性模型吗??
  • 是的。也许这不是一个很好的字段名称?
  • 可能model是一个保留字,比如view
  • 不,我认为这不是问题,因为我已经使用这个属性很长时间了,没有任何问题。此外,如果我使用不同的字段名称,我仍然会收到错误,但使用其他字段名称。所以我有一个属性 officeLoc,如果我把它放在那里,我会收到相同的消息,但使用的是 officeLoc 而不是模型。

标签: xpages


【解决方案1】:

定义objectData在自定义控件之外包括和
将属性dataSource设置为objectData的变量PCModel:dataSource="#{PCModel}"

<?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"
    xmlns:xe="http://www.ibm.com/xsp/coreex">
    <xp:this.data>
        <xe:objectData
            var="PCModel">
            <xe:this.createObject><![CDATA[#{javascript:
                var pc = new com.scoular.data.PC();
                pc.create();
                return pc;
            }]]></xe:this.createObject>
        </xe:objectData>
    </xp:this.data>
    <xc:ccCustomField
        placeholder="Enter your email address"
        fieldLabel="Email"
        helpText="Guess what you have to enter here..."
        fieldName="model"
        dataSource="#{PCModel}">
    </xc:ccCustomField>
</xp:view>

所以,这不是 bean 的问题,而是为自定义控件设置 dataSource 属性。

另外,要小心 bean 的方法 create()。它可能不会返回 bean 的实例。如果是这样的话,那么你的代码行

var pc = new com.scoular.data.PC().create();

不会将 pc 设置为 PC 实例,并且 dataSource 不会正确初始化。

【讨论】:

  • 克努特,为什么您认为原始代码不会返回实例?我没有看到使用该方法的问题。谢谢!
  • @David:如果 create() 有最后一行 return this;,它就可以工作。我看到了实现public void create() 虽然...
  • 谢谢。好的我明白了。我没有注意到 Bryan 的原始代码只使用了一行。是的,如果 create() 返回一个 void 那么它需要在单独的行上,但是将它分成 2 行也可以。呸。我在那里有点困惑。 :)
【解决方案2】:

要将错误消息传递给特定字段,我有 Utility 方法,找到该字段,然后将错误添加到引用 clientId 的 FacesContext,它是通过 findComponent 方法找到的

public static void addMessageToSpecificField(String fieldId, String    message) {
        String clientId = JSFUtil.findComponent(fieldId).getClientId(
                JSFUtil.getFacesContext());
        JSFUtil.getFacesContext().addMessage(clientId,
                new javax.faces.application.FacesMessage(message));
    }

/** 
 * Finds an UIComponent by its component identifier in the current 
 * component tree. 
 * 
 * @param compId the component identifier to search for 
 * @return found UIComponent or null 
 * 
 * @throws NullPointerException if <code>compId</code> is null 
 */ 
public static UIComponent findComponent(String compId) { 
        return findComponent(FacesContext.getCurrentInstance().getViewRoot(), compId); 
} 

 /** 
 * Finds an UIComponent by its component identifier in the component tree 
 * below the specified <code>topComponent</code> top component. 
 * 
 * @param topComponent first component to be checked 
 * @param compId the component identifier to search for 
 * @return found UIComponent or null 
 * 
 * @throws NullPointerException if <code>compId</code> is null 
 */ 
@SuppressWarnings("unchecked")
public static UIComponent findComponent(UIComponent topComponent, String compId) { 
        if (compId==null) 
                throw new NullPointerException("Component identifier cannot be null"); 

        if (compId.equals(topComponent.getId())) 
                return topComponent; 

            if (topComponent.getChildCount()>0) { 
                List<UIComponent> childComponents=       topComponent.getChildren(); 

                for (UIComponent currChildComponent : childComponents) { 
                        UIComponent       foundComponent=findComponent(currChildComponent, compId); 
                        if (foundComponent!=null) 
                                return foundComponent; 
                } 
        } 
        return null; 
}

【讨论】:

    猜你喜欢
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    相关资源
    最近更新 更多