[英]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值以重新提交并重新验证?
这里有两个问题:
您在<f:attribute>
,将模型值而不是组件值传递给验证器。 在验证阶段(更新模型值阶段之前运行)期间,更新的模型值不一定可用。 仅在先前的请求中成功处理了引用该模型值的输入字段后,该选项才起作用。 您最好传递通过binding
引用的物理组件,并在其上使用UIInput#getValue()
。
默认情况下, <p:ajax>
仅处理其嵌套的组件,如process="@this"
。 您实际上也需要处理其他组件,以便在验证器中具有正确的值。
更改一个输入时,您没有更新其他输入。 因此,其他输入在验证成功时将永远无法删除错误突出显示。
总而言之,这应该做到:
<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.