繁体   English   中英

使用Ajax的JSF表单验证卡住了

[英]JSF Form Validation Using Ajax getting stuck

我在表单上有两个经过交叉验证的字段。 最初,用户看到以下内容:

在此处输入图片说明

<p:inputText size="5" 
  value="#{bean.maximum_hole_diameter}">
  <f:validator validatorId="doubleNotLessThanSecondDouble" />
  <f:attribute name="secondDouble" 
    value="#{bean.minimum_hole_diameter}" />
  <p:ajax event="change" update="@this" />
</p:inputText>

<p:inputText size="5" 
  value="#{bean.minimum_hole_diameter}">
  <f:validator validatorId="doubleNotGreaterThanSecondDouble" />
  <f:attribute name="secondDouble"
    value="#{bean.maximum_hole_diameter}" />
  <p:ajax event="change" update="@this" />
</p:inputText>

如果用户首先为最大值输入一个正值,然后为最小值输入一个较小的值,那么一切都会按预期进行。

如果他们输入的第一个最小值被标记为无效:

在此处输入图片说明

到目前为止,效果很好-2大于0.0。 凭直觉,用户将输入最大孔径,该孔径大于最小值。 但是表格卡住了。 最小值仍然无效,因为从技术上讲,该最小值仍为0.0。 Ajax从未将值2存储在模型中,但浏览器仍然显示值2。如何获取2进行重新验证并存储在bean中?

在此处输入图片说明

我可以执行update =“ @ form”来将2值清除为零,但这会使用户感到沮丧。 并且,如果用户重新输入2,则不会提交表单,因为表单尚未“更改”。 用户必须更改为另一个数字,然后返回2。执行“ onblur”也有其问题。

当用户输入3时,如何获取2值以重新提交并重新验证?

这里有两个问题:

  1. 您在<f:attribute> ,将模型值而不是组件值传递给验证器。 在验证阶段(更新模型值阶段之前运行)期间,更新的模型值不一定可用。 仅在先前的请求中成功处理了引用该模型值的输入字段后,该选项才起作用。 您最好传递通过binding引用的物理组件,并在其上使用UIInput#getValue()

  2. 默认情况下, <p:ajax>仅处理其嵌套的组件,如process="@this" 您实际上也需要处理其他组件,以便在验证器中具有正确的值。

  3. 更改一个输入时,您没有更新其他输入。 因此,其他输入在验证成功时将永远无法删除错误突出显示。

总而言之,这应该做到:

<p:inputText id="max" binding="#{max}" ...>
    <f:validator validatorId="doubleNotLessThanSecondDouble" />
    <f:attribute name="secondComponent" value="#{min}" />
    <p:ajax process="@this min" update="@this min" />
</p:inputText>

<p:inputText id="min" binding="#{min}" ...>
    <f:validator validatorId="doubleNotGreaterThanSecondDouble" />
    <f:attribute name="secondComponent" value="#{max}" />
    <p:ajax process="@this max" update="@this max" />
</p:inputText>

在这些验证器中具有以下逻辑:

double firstDouble = (double) value;
UIInput secondComponent = (UIInput) component.getAttributes().get("secondComponent");
double secondDouble = (double) secondComponent.getValue();
// ...

也可以看看:


如果您碰巧使用了JSF实用工具库OmniFaces或愿意使用它,那么很高兴知道<o:validateOrder>也可以满足以下要求(不需要任何自定义验证器):

<h:panelGroup id="diameter">
    <p:inputText id="max" ...>
        <p:ajax process="diameter" update="diameter" />
    </p:inputText>

    <p:inputText id="min" ...>
        <p:ajax process="diameter" update="diameter" />
    </p:inputText>

    <o:validateOrder type="gt" components="max min" />
</h:panelGroup>

具体问题无关 ,如果准确性非常重要,则最好使用BigDecimal而不是double

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM