无论如何都要在表单提交时验证只读组件 [英] Validate readonly components anyway on form submit

查看:113
本文介绍了无论如何都要在表单提交时验证只读组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个实体的UI,该实体既有工具也有发行人,但从来没有.您可以从弹出的搜索对话框中选择一个,然后将其分配给实体.

We have a UI for an entity that either has an instrument or an issuer, but never both. You can select one of each from a popup search dialog and assign it to the entity.

用户可以在搜索..."按钮旁边看到两者的编号和名称.这两个必须都是不可编辑的,也就是说,我们各自的<p:inputText ... readonly="true" ... />会使输入变灰.

The user can see the number and name of each of the two next to the "Search..." button. Both of these must be non-editable, that is we the the respective <p:inputText ... readonly="true" ... /> to grey out the inputs.

我们现在的要求是,不仅在未选择工具和发行人时,或者在未选择任何一种工具和发行人的情况下,都应该显示一条验证消息,而且标记为readonly="true"的文本框也应显示为红色(以及加上标签).

The requirement we have now is that not only a validation message is supposed to be shown when either none or both of the instrument and issuer are selected, but also that the text boxes tagged with readonly="true" are shown in red (along with their labels).

添加时,请先按保存":

When adding, before pressing "Save":

添加时,按保存"后:

我尝试了几件事,然后最终选择了OmniFaces <o:validateMultiple>,它似乎朝着正确的方向发展.但是,然后我注意到验证器没有启动,正如您从图像中看到的那样...(我只是移除了readonly="true"以便您看到效果)

I tried a few things and then I ended up with OmniFaces <o:validateMultiple>, which seemed to go into the right direction. However, I then noticed that the validator didn't kick in, as you can see from the images... (I just removed the readonly="true" for you to see the effect)

下面是代码摘录:

<!-- 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>

Q :

您如何解决这个问题?

问题似乎是OmniFaces或JSF(?)不对只读组件进行验证.我还查看了<o:validateMultiple>的OmniFaces VDL,但没有类似allowReadOnlyComponentHighlighting或类似标记的标记.

The problem seems to be that OmniFaces or JSF(?) doesn't do validation of readonly components. I also looked at the OmniFaces VDL for <o:validateMultiple>, but there wasn't a flag like allowReadOnlyComponentHighlighting or similar.

还有另一种方法吗?

推荐答案

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

JSF will for security reasons indeed skip readonly (and disabled) fields from processing (conversion, validation and model update). You don't want a hacker to be able to edit those values anyway by manipulating the request parameters, right? OmniFaces will also skip them the same way for obvious security reasons.

您最好的选择是将EL表达式放在readonly属性中,该属性在应用请求值和验证阶段(第二和第三阶段)期间评估false,但在所有其他阶段中评估true.足以检查当前相位序数是否为4或更大.无论如何,这应该允许JSF对值执行验证.然后,您需要向rendered属性添加一个EL表达式,该属性在更新模型值阶段(第4阶段)期间对false进行求值,因此不会更新模型值,因为在此过程中readonlyfalse应用请求值和验证阶段(因此该组件具有其设置本地值,将触发模型更新.

Your best bet is putting an EL expression in readonly attribute which evaluates false during apply request values and validations phases (the 2nd and 3rd phase), but true during all other phases. It suffices to check if the current phase ordinal is 4 or greater. This should allow JSF to perform validation on the value anyway. Then, you need to add an EL expression to the rendered attribute which evaluates false during update model values phase (the 4th phase), so that the model value won't be updated because readonly was false during apply request values and validations phases (and thus the component has its local value set, which triggers the model update).

您可以通过 也由#{facesContext.currentPhaseId}提供. PhaseId依次具有 getOrdinal() 方法返回相位索引(标准相位从1到6).

You can obtain the current JSF phase by FacesContext#getCurrentPhaseId() which is in EL also available by #{facesContext.currentPhaseId}. The PhaseId has in turn a getOrdinal() method returning the phase index (from 1 until with 6 for the standard phases).

总而言之,这样做应该是为了无论如何都要对其进行验证,但是要防止模型更新:

Summarized, this should do in order to validate them anyway, but prevent model update:

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

这篇关于无论如何都要在表单提交时验证只读组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆