2014-04-17 113 views
2

我有我的inputText兩個要求:在P的跳過Primefaces的inputText的驗證上keyup事件,但驗證上提交

  1. 值:inputText的應h中立即顯示在屏幕上:的outputText與KEYUP事件
  2. 值應該在數據庫中是唯一

我使用Primefaces 4.0,JSF 2.2 Glassfish的4和Java 7

我的代碼看起來是這樣的此刻

Example.xhtml

<h:form> 
    <p:inputText id="value" value="#{myBean.value}" > 
     <p:ajax event="keyup" update="example" process="@this" /> 
     <f:validator binding="#{uniqueValueValidator}" /> 
    </p:inputText> 
    <h:outputText id="example" value="#{myBean.value}"> 
    <p:commandButton value="Save" action="#{myBean.saveValue}"/> 
</form> 

MyBean.java

@Named 
@RequestScoped 
public class MyBean { 

    @Inject 
    private DBService service; 

    private String value; 
    //getter, setter 

    public String saveValue() { 
     service.saveValue(value); 
     return "showall"; 
    } 
} 

UniqueValueValidator.java

@Named 
public class UniqueValueValidator implements Validator { 

    @Inject 
    private DBService service; 

    @Override 
    public void validate(FacesContext context, UIComponent component, Object value) 
     throws ValidatorException { 

     if(service.isValueNotUnique(value.toString()) { 
       // throw ValidatorException 
     } 
    } 
} 

我的問題是現在,這對每一個KEYUP事件的價值被驗證並且對數據庫進行調用。但我只想在表單提交時驗證該值。

我的第一個解決方案是將驗證移入saveValue方法。

public String saveValue() { 
    if(service.isValueNotUnique(value) { 
     // add a FacesMessage 
     return null; 
    } else { 
     service.saveValue(value); 
     return "showall"; 
    } 
} 

但是在這裏我認爲在一種方法中混用驗證碼和邏輯代碼並不是好習慣。

所以,我希望你對我有一個更好的解決方案;)

回答

3

問題在於inputText組件內部的AJAX標籤:

<p:ajax event="keyup" update="example" process="@this" /> 

這意味着,你在每個KEYUP提交組件事件。驗證器每次都會被調用。

可能的解決方法是給校驗器移動到另一個部件,以下用於驗證多個組件相同的技術:

在小面頁面添加使用uniqueValueValidator一個inputHidden:

<h:form id="formId" > 
    <p:inputText id="value" value="#{myBean.value}" > 
     <p:ajax event="keyup" update="example" process="@this" /> 
    </p:inputText> 
    <h:inputHidden id="hidden"> 
     <f:validator validatorId="uniqueValueValidator" /> 
    </h:inputHidden> 
    <p:message for="hidden" /> 
    <p:commandButton value="Save" action="#{myBean.saveValue}" process="@form" update="@form"/> 
</h:form> 

UniqueValueValidator

@Named 
@FacesValidator("uniqueValueValidator") 
public class UniqueValueValidator implements Validator { 

    @Inject 
    private DBService service; 

    @Override 
    public void validate(FacesContext context, UIComponent component, Object obj) { 

     Object inputValue = ((UIInput) context.getViewRoot().findComponent("formId:value")).getSubmittedValue(); 

     if(service.isValueNotUnique((String) inputValue) { 
      // throw ValidatorException 
     } 
    } 

} 

}

這種方法與您的一樣,意味着每個關鍵事件中的輸入內容的往返客戶端服務器客戶端。如果這不是必要的,您可以使用javascript方法避免它,如其他答案中所述。

鏈接

0

你可以擺脫在p Ajax請求的:inputText的,只是從輸入值複製到使用jQuery的的inputText如下所示:

<h:form id="myForm"> 
    <p:inputText id="value" value="#{myBean.value}" onkeyup="$("#myForm\\:example").html($(this).val()"> 
     <f:validator binding="#{uniqueValueValidator}" /> 
    </p:inputText> 
    <h:outputText id="example" value="#{myBean.value}"> 
    <p:commandButton value="Save" action="#{myBean.saveValue}"/> 
</form>