Validation 在表单提交时验证只读组件

Validation 在表单提交时验证只读组件,validation,jsf,readonly,Validation,Jsf,Readonly,我们为一个实体提供了一个UI,该实体要么拥有一个工具,要么拥有一个发行人,但决不能同时拥有这两个工具。您可以从弹出的搜索对话框中选择其中一个并将其分配给实体 用户可以在搜索旁边看到两个搜索的编号和名称。。。按钮这两个都必须是不可编辑的,也就是说,我们将相应的输入灰显 我们现在的要求是,当仪器和发卡机构均未选择或均未选择时,不仅应显示验证消息,还应将标有readonly=true的文本框与其标签一起显示为红色 添加时,在按Save之前: 添加时,按保存后: 我尝试了一些东西,最后我得到了OmniF

我们为一个实体提供了一个UI,该实体要么拥有一个工具,要么拥有一个发行人,但决不能同时拥有这两个工具。您可以从弹出的搜索对话框中选择其中一个并将其分配给实体

用户可以在搜索旁边看到两个搜索的编号和名称。。。按钮这两个都必须是不可编辑的,也就是说,我们将相应的输入灰显

我们现在的要求是,当仪器和发卡机构均未选择或均未选择时,不仅应显示验证消息,还应将标有readonly=true的文本框与其标签一起显示为红色

添加时,在按Save之前:

添加时,按保存后:

我尝试了一些东西,最后我得到了OmniFaces,它似乎朝着正确的方向发展。然而,我随后注意到验证器没有启动,正如您从图像中看到的。。。我刚刚删除了readonly=true,以便您看到效果

以下是代码摘录:

<!-- this panel is insider a form, yes -->
<h:panelGroup id="subpanel"
              layout="block">
    <o:validateMultiple id="instrument-or-issuer-validator"
                        validator="#{barrierCrossingManager.validateInstrumentOrIssuer}"
                        components="instrument-isin instrument-description issuer-number issuer-name"
                        message="..." />
    <!-- some panel grid with the inputs -->
    ...
        <p:panelGrid id="issuer-subpanel">
            <p:row>
                <p:column>
                    <p:outputLabel for="issuer-number" value="#{msg['common.number.label']}:" />
                </p:column>
                <p:column colspan="3">
                    <p:inputText id="issuer-number"
                                 value="#{barrierCrossingManager.selectedIssuer.nbr}"
                                 readonly="false" />
                </p:column>
                ...
            </p:row>
        </p:panelGrid>
    ...
    <h:messages id="msgs"
                layout="list"
                styleClass="subcontent-validation-msg-wrapper"
                showDetail="false"
                showSummary="true" />
</h:panelGroup>
问:

你如何解决这个问题

问题似乎在于OmniFaces或JSF没有对只读组件进行验证。我还查看了OmniFaces的VDL,但没有类似AlloreAndonlyComponentThighLighting或类似的标志


还有其他方法吗?

出于安全原因,JSF确实会跳过处理转换、验证和模型更新过程中的只读和禁用字段。你不希望黑客通过操纵请求参数来编辑这些值,对吧?出于明显的安全原因,OmniFaces也将以同样的方式跳过它们

最好的选择是在readonly属性中放置一个EL表达式,该表达式在第2和第3阶段的应用请求值和验证阶段计算为false,但在所有其他阶段计算为true。检查当前相位顺序是否为4或更大就足够了。这应该允许JSF对值执行验证。然后,您需要将EL表达式添加到渲染属性中,该属性在更新模型值阶段(第4阶段)期间求值为false,这样模型值就不会更新,因为在应用请求值和验证阶段readonly为false,因此组件具有其集合,从而触发模型更新

您可以通过{facesContext.currentPhaseId}获得当前JSF阶段,该阶段在EL中也可用。PhaseId反过来有一个方法,将标准相位的相位索引从1返回到6

总之,为了验证它们,应该这样做,但要防止模型更新:

<p:inputText
    readonly="#{facesContext.currentPhaseId.ordinal ge 4}" 
    rendered="#{facesContext.currentPhaseId.ordinal ne 4}" 
/>

谢谢,我用你的解决方案做了一些尝试。问题是当我们提交带有只读输入的面板时,命令按钮的操作被调用,导致调用创建或更新例程,这将失败,因为没有设置某些内容。有没有一种方法可以让你不采取行动?注意,只要表单上有空的非只读必填项,就不会发生这种情况。