2017-08-29 8 views
1

検証に失敗した場合でも、2回目の送信で無効なフィールドを無視してフォームを送信します。次のように単離された問題である。2番目のフォームの無効なフィールドをスキップします。

私の形態は、さらに、例えば入力の不等式を保証MyValidator命名h:hiddenInputとカスタムバリデータに検証された2つの必要な入力foobar、から成ります。 MyValidatorが失敗した場合は、foobarの入力だけを処理して、h:hiddenInputとそのバリデータをスキップする別の送信ボタンをレンダリングします。

@Named 
@FacesValidator("myValidator") 
public class MyValidator implements Validator { 

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

     String foo = (String) ((UIInput) component.getAttributes().get("foo")).getValue(); 
     String bar = (String) ((UIInput) component.getAttributes().get("bar")).getValue(); 

     if (foo != null && bar != null && foo.equals(bar)) { 
      throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Foo and bar must not be equal", "")); 
     } 
    } 
} 

@Named 
@ViewScoped 
public class MyControl implements Serializable { 

    private String foo; 
    private String bar; 

    public void doSomething() { 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Did something")); 
    } 

    public void doAnotherThing() { 
     FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Did another thing")); 
    } 

    ... 
} 

<h:form> 
    <h:panelGroup layout="block" id="fooBarWrapper"> 
     <p:inputText value="#{myControl.foo}" binding="#{foo}" required="true"/> 
     <p:inputText value="#{myControl.bar}" binding="#{bar}" required="true"/> 
    </h:panelGroup> 

    <h:inputHidden validator="myValidator" binding="#{myValidation}"> 
     <f:attribute name="foo" value="#{foo}"/> 
     <f:attribute name="bar" value="#{bar}"/> 
    </h:inputHidden> 

    <p:messages/> 

    <p:commandButton action="#{myControl.doSomething()}" value="Do something" 
        process="@form" update="@form" 
        rendered="#{myValidation.valid}"/> 

    <p:commandButton action="#{myControl.doAnotherThing()}" value="Do another thing" 
        process="fooBarWrapper" update="@form" 
        rendered="#{not myValidation.valid}" 
        oncomplete="if (!args.validationFailed) { console.log('valid'); }"/> 
</h:form> 

予想通りMyValidatorが現在スキップされるものの、第二ボタンの動作は、呼び出されません。興味深いことに、PrimeFaces args.validationFailedは、検証が成功したことを示しています。

誰でも説明できますが、なぜ#{myControl.doAnotherThing()}が呼び出されないのですか?

+0

2番目の 'commandButton'で' immediate = "true"を設定しようとしましたか? –

+1

あなたの 'process'属性の値' '#{p:component( 'fooBarWrapper'})'では '' process = "fooBarWrapper" 'を単純に設定することができます。また、less beanメソッドを呼び出す場合は、 '()'を追加する必要はありません。 –

+0

(1) '' -'は私の 'javax.facesSEPARATOR_CHAR'です.JQueryセレクタでエスケープする必要はありません。しかし、 'process =" fooBarWrapper "'はここでは絶対に十分です。私は私の質問を更新しました。ありがとうございました! (2.)「即時=真実」が私にここで助けてくれる方法はわかりません。 https://stackoverflow.com/a/12961162で指摘されているように、 'immediate =" true "'を持たないすべての入力を無視します。しかし私は私のフォーム提出にそれらを含めることを望む。 – stan

答えて

1

問題はh:inputHiddenのバリデータとはまったく関係ありません。 あなたのサンプルをさらに細分化することができます。

<h:form> 
    <h:panelGroup layout="block" id="fooBarWrapper"> 
     <p:inputText value="#{myControl.foo}"/> 
     <p:inputText value="#{myControl.bar}"/> 
    </h:panelGroup> 

    <p:messages/> 

    <p:commandButton action="#{myControl.doAnotherThing()}" value="Do another thing" process="fooBarWrapper" update="@form"/> 
</h:form> 

この例も機能しません。 この作業を行うには、commandButtonも処理する必要があります。

<p:commandButton action="#{myControl.doAnotherThing()}" value="Do another thing" process="@this fooBarWrapper" update="@form"/> 
関連する問題