【问题标题】:Skip invalid fields on second form submit跳过第二个表单提交时的无效字段
【发布时间】:2018-02-06 15:47:16
【问题描述】:

当验证失败时,我仍想通过忽略第二次提交中的无效字段来提交表单。孤立的问题如下:

我的表单包含两个必需的输入 foobar,它们在 h:hiddenInput 和一个名为 MyValidator 的自定义验证器中额外验证,例如确保输入的不等式。如果MyValidator 失败,我会通过仅处理输入foobar 来呈现另一个跳过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 现在按预期被跳过了。有趣的是,PrimeFaces args.validationFailed 表示验证成功。

谁能解释一下,为什么没有调用#{myControl.doAnotherThing()},尽管似乎没有验证失败?

【问题讨论】:

  • 您是否尝试在第二个commandButton 上设置immediate="true"
  • 那么- 在你的process 属性值中做了什么,即-#{p:component('fooBarWrapper')},因为你可以简单地设置process="fooBarWrapper"。此外,如果您正在调用无参数 bean 方法,则无需添加 ()
  • (1.) - 是我的javax.faces.SEPARATOR_CHAR,因为我不需要在任何 jQuery 选择器中转义它。但是,process="fooBarWrapper" 在这里绝对足够了。我更新了我的问题。谢谢! (2.) 我看不到 immediate="true" 在这里可以如何帮助我。正如stackoverflow.com/a/12961162 中所指出的,这将忽略所有 具有immediate="true" 的输入。但我确实想将它们包含在我的表单提交中。

标签: validation primefaces jsf-2.2


【解决方案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"/>

【讨论】:

    猜你喜欢
    • 2016-11-10
    • 1970-01-01
    • 2018-01-10
    • 2013-01-18
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多