検証に失敗した場合でも、2回目の送信で無効なフィールドを無視してフォームを送信します。次のように単離された問題である。2番目のフォームの無効なフィールドをスキップします。
私の形態は、さらに、例えば入力の不等式を保証MyValidator
命名h:hiddenInput
とカスタムバリデータに検証された2つの必要な入力foo
とbar
、から成ります。 MyValidator
が失敗した場合は、foo
とbar
の入力だけを処理して、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()}
が呼び出されないのですか?
2番目の 'commandButton'で' immediate = "true"を設定しようとしましたか? –
あなたの 'process'属性の値' '#{p:component( 'fooBarWrapper'})'では '' process = "fooBarWrapper" 'を単純に設定することができます。また、less beanメソッドを呼び出す場合は、 '()'を追加する必要はありません。 –
(1) '' -'は私の 'javax.facesSEPARATOR_CHAR'です.JQueryセレクタでエスケープする必要はありません。しかし、 'process =" fooBarWrapper "'はここでは絶対に十分です。私は私の質問を更新しました。ありがとうございました! (2.)「即時=真実」が私にここで助けてくれる方法はわかりません。 https://stackoverflow.com/a/12961162で指摘されているように、 'immediate =" true "'を持たないすべての入力を無視します。しかし私は私のフォーム提出にそれらを含めることを望む。 – stan