2011-04-27 66 views
2

我有一个表格两个输入字段必须是一起验证。我用这个BalusC tutorial作为起点。错误验证两个inputText字段在一起

要求是一个逻辑XOR:必须填写其中一个字段,但不能同时填写

也能正常工作的所有情况,除了这一个:

1)填写的第一场,让第二空白

2)移动到下一个页面(价值得到保存)

3 )回到第一页,删除第一个字段并填写第二个字段

然后,我从我的验证错误信息(“不要填写这两个字段”),但我删除了第一。

下面是代码:

<h:inputText id="bbvol" size="10" value="#{a6.behandlungsvolumen.wert}" 
     required="#{empty param['Laborwerte:pvol']}"> 
    <f:convertNumber locale="de"/> 
</h:inputText> 

<h:inputText id="pvol" size="10" value="#{a6.plasmavolumen.wert}" 
     required="#{empty param['Laborwerte:bbvol']}"> 
    <f:convertNumber locale="de"/> 
    <f:validator validatorId="volumeValidator" for="pvol"/> 
    <f:attribute name="bbv_value" value="Laborwerte:bbvol" /> 
</h:inputText> 

VolumeValidator:

public class VolumeValidator implements Validator { 

    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { 
     // Obtain the client ID of the first volume field from f:attribute. 
     String bbvolID = (String) component.getAttributes().get("bbv_value"); 
     // Find the actual JSF component for the client ID. 
     UIInput bbvolInput = (UIInput) context.getViewRoot().findComponent(bbvolID); 
     // Get its value, the entered value of the first field. 
     Number bbvol = (Number) bbvolInput.getValue(); 
     // Get the value of the second field 
     Number pvol = (Number) value; 
     // Check if only one of the fields is set 
     if (bbvol != null && pvol != null) { 
      throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Do not fill both fields!", null)); 
     } 
    } 
} 

调试这种情况表明,该行

Number bbvol = (Number) bbvolInput.getValue(); 

仍持有旧值,而不是新的。

我试过用getSubmittedValue()而不是getValue()这个工程。但Javadoc中此方法表示:

此方法应该仅由 解码中使用()和验证此 组分()方法,或它的相应 呈现器。

我不知道我是否可以使用此方法,而不会在以后运行问题。

所以我的问题是:

,这是什么问题的原因是什么?

是使用getSubmittedValue()代替getValue()一个真正的解决方案?

回答

3

这并不解决问题。如果您测试getSubmittedValue(),则在填写两个字段时验证将(错误地)通过。在JSF中,输入组件按照出现在组件树中的顺序进行验证。当组件成功转换/验证后,提交的值将被设置为null,并且该值将使用转换/验证的提交值进行设置。

但是,你的具体情况给我的印象。我可以在Tomcat 7.0.11上用Mojarra 2.0.4复制这个问题。 getValue()返回模型值而不是组件值。我不确定这是JSF2中的一个错误还是新东西,但我确信它已经在JSF 1.x中以这种方式工作了。我相信这与新的JSF2国家管理方面的变化有关。我必须先验证其中一个(也可能重写多个字段验证博客文章)。

作为另一种解决方案,你可以添加一个<h:inputHidden>以前两种成分如下这样就可以利用getSubmittedValue()的正确方法:

<h:form id="form"> 
    <h:inputHidden value="true"> 
     <f:validator validatorId="xorValidator" /> 
     <f:attribute name="input1" value="form:input1" /> 
     <f:attribute name="input2" value="form:input2" /> 
    </h:inputHidden> 
    <h:inputText id="input1" value="#{bean.input1}" required="#{empty param['form:input2']}" /> 
    <h:inputText id="input2" value="#{bean.input2}" required="#{empty param['form:input1']}" /> 
    <h:commandButton value="submit" action="#{bean.submit}" /> 
    <h:messages /> 
</h:form> 

@FacesValidator(value="xorValidator") 
public class XorValidator implements Validator { 

    @Override 
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { 
     UIInput input1 = (UIInput) context.getViewRoot().findComponent((String) component.getAttributes().get("input1")); 
     UIInput input2 = (UIInput) context.getViewRoot().findComponent((String) component.getAttributes().get("input2")); 

     Object value1 = input1.getSubmittedValue(); 
     Object value2 = input2.getSubmittedValue(); 

     // ... 
    } 

} 
+0

谢谢BalusC。我会尝试这个,并报告它是否适合我。这听起来像是一个老问题:“这是一个错误还是一个特征?” ;-) – 2011-04-27 16:29:49

+0

它适合我。 – BalusC 2011-04-27 16:31:08

+0

它的工作原理!非常感谢! – 2011-04-28 07:28:34

1
从{功能

除了| bug},使用2.x中的getValue()/ getSubmittedValue() - 方法,您可以尝试RequiredIf-Annotation进行异或验证:

@RequiredIf(validationErrorMsgKey = "requiredField", valueOf = { "pvol" } , is = RequiredIfType.empty) private String bbvol;

@RequiredIf(validationErrorMsgKey = "requiredField", valueOf = { "bbvol" } , is = RequiredIfType.empty) private String pvol;

这对我来说就像一个类似验证星座中的魅力。

+0

感谢您的回答。有趣的方法。从来没有听说过这个注释。谷歌表示这是一个MyFaces扩展,对吗? – 2011-07-28 19:20:23

+0

是的,它包含在myfaces-extval-property-validation-2.x.jar中。不幸的是,几乎没有关于其用法的文档。 (至少我找不到任何...)。你还需要myfaces-extval-core.jar。 (甚至可能是persistence-api.jar)。 – 2011-07-29 11:03:29