我们为拥有工具或发行人的实体提供了UI,但两者都没有。您可以从弹出搜索对话框中选择其中一个,然后将其分配给实体。
用户可以在“搜索...”按钮旁边看到两者的编号和名称。这些必须都是不可编辑的,即我们相应的<p:inputText ... readonly="true" ... />
会使输入变灰。
我们现在的要求是,当选择了一个或两个工具和发行者时,不仅应该显示验证消息,而且用readonly="true"
标记的文本框以红色显示(以及他们的标签)。
添加时,在按“保存”之前:
添加后,按“保存”后:
我尝试了一些事情,然后我最终得到了OmniFaces <o:validateMultiple>
,这似乎朝着正确的方向发展。但是,我注意到验证器没有启动,正如您从图像中看到的那样......(我刚刚删除了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(?)不对只读组件进行验证。我还查看了<o:validateMultiple>
的OmniFaces VDL,但没有像allowReadOnlyComponentHighlighting
或类似的标志。
还有其他办法吗?
答案 0 :(得分:7)
出于安全原因,JSF确实会跳过处理(转换,验证和模型更新)中的只读(和禁用)字段。您不希望黑客无论如何都能通过操作请求参数来编辑这些值,对吗?出于明显的安全原因,OmniFaces也会以相同的方式跳过它们。
最好的办法是在readonly
属性中放置EL表达式,在申请请求值和验证阶段(第2阶段和第3阶段)评估false
,但在所有其他阶段true
。足以检查当前阶段序数是否为4或更大。这应该允许JSF无论如何都要对值进行验证。然后,您需要将EL表达式添加到rendered
属性中,该属性在更新模型值阶段(第4阶段)期间评估false
,以便模型值不会被更新,因为{{ 1}}在应用请求值和验证阶段期间readonly
(因此组件设置了local value,从而触发模型更新)。
您可以通过FacesContext#getCurrentPhaseId()
获取当前的JSF阶段,其中EL也可以由false
获得。 #{facesContext.currentPhaseId}
依次使用getOrdinal()
方法返回阶段索引(从标准阶段的1到6)。
总结一下,这应该是为了验证它们,但是阻止模型更新:
PhaseId