【问题标题】:Skip validation of Primefaces Inputtext on keyup event but validate on submit在 keyup 事件上跳过 Primefaces Inputtext 验证,但在提交时验证
【发布时间】:2014-06-01 14:41:46
【问题描述】:

我的 InputText 有两个要求:

  1. p:inputText 的值应立即显示在屏幕上 h:outputText 与 keyup-event
  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";
    }
}

但在这里我认为将验证代码和逻辑代码混合在一种方法中并不是一个好习惯。

所以我希望你有一个更好的解决方案;)

【问题讨论】:

    标签: java validation jsf primefaces


    【解决方案1】:

    问题在于 inputText 组件内的 ajax 标签:

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

    这意味着您在每个 keyup 事件上提交组件。因此每次都会调用验证器。

    一种可能的解决方法是将验证器移动到另一个组件,遵循用于验证多个组件的相同技术:

    在 facelets 页面中添加一个使用 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 
            }
        }
    
    }
    

    }

    与您的方法一样,这种方法意味着每个 keyup 事件上输入内容的往返客户端-服务器-客户端。如果这不是必需的,您可以使用另一个答案中解释的 javascript 方法来避免它。

    链接

    【讨论】:

      【解决方案2】:

      您可以摆脱 p:inputText 中的 ajax 请求,只需使用 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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-28
        相关资源
        最近更新 更多