2011-04-27 26 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