跳过第二个表单提交的无效字段
Skip invalid fields on second form submit
当验证失败时,我仍然想通过忽略第二次提交中的无效字段来提交表单。孤立的问题如下:
我的表单包含两个必需的输入 foo
和 bar
,它们在 h:hiddenInput
和一个名为 MyValidator
的自定义验证器中进行了额外验证,例如确保输入的不平等。如果 MyValidator
失败,我将通过仅处理输入 foo
和 bar
.
来呈现另一个跳过 h:hiddenInput
及其验证器的提交按钮
<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>
和
@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"));
}
...
}
然而,第二个按钮的动作没有被调用,尽管 MyValidator
现在按预期跳过了。有趣的是,PrimeFacesargs.validationFailed
表示验证成功
谁能解释一下,为什么 #{myControl.doAnotherThing()}
没有被调用,虽然没有验证似乎失败?
问题与 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"/>
当验证失败时,我仍然想通过忽略第二次提交中的无效字段来提交表单。孤立的问题如下:
我的表单包含两个必需的输入 foo
和 bar
,它们在 h:hiddenInput
和一个名为 MyValidator
的自定义验证器中进行了额外验证,例如确保输入的不平等。如果 MyValidator
失败,我将通过仅处理输入 foo
和 bar
.
h:hiddenInput
及其验证器的提交按钮
<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>
和
@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"));
}
...
}
然而,第二个按钮的动作没有被调用,尽管 MyValidator
现在按预期跳过了。有趣的是,PrimeFacesargs.validationFailed
表示验证成功
谁能解释一下,为什么 #{myControl.doAnotherThing()}
没有被调用,虽然没有验证似乎失败?
问题与 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"/>