跳过验证有条件地,当空F:选择信息中的p/H:selectOneMenu用于选择 [英] Skip validation conditionally, when empty f:selectItem in p/h:selectOneMenu is selected

查看:132
本文介绍了跳过验证有条件地,当空F:选择信息中的p/H:selectOneMenu用于选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

父母:

<p:selectOneMenu id="parentList"
                 value="#{bean.selectedParent}"
                 converter="#{parentConverter}"
                 required="true">

        <f:selectItem itemLabel="Select" itemValue="#{null}"/>

        <f:selectItems var="parent"
                       value="#{bean.parentList}"
                       itemLabel="#{parent.parentName}"
                       itemValue="#{parent}"/>

        <p:ajax update="childrenList" listener="#{bean.setchildren}"/>
</p:selectOneMenu>

孩子:

<p:selectOneMenu id="childrenList"
                     value="#{bean.selectedchild}"
                     converter="#{childConverter}"
                     required="true">

        <f:selectItem itemLabel="Select" itemValue="#{null}"/>

        <f:selectItems var="child"
                       value="#{bean.childrenList}"
                       itemLabel="#{child.childName}"
                       itemValue="#{child}"/>
</p:selectOneMenu>

托管bean:

@Named
@ViewScoped
public class Bean implements Serializable {

    @Inject
    private Service service;

    private Parent selectedParent;
    private Child selectedChild;
    private List<Parent> parentList;
    private List<Child> childrenList;

    private static final long serialVersionUID = 1L;

    public Bean() {}

    @PostConstruct
    private void init() {
        parentList = service.getParentList();

        // Not necessary unless selectedParent is already available in edit mode.
        if(selectedParent != null) {
            childrenList = service.getChildrenListByParent(selectedParent);
        }
    }

    public void setChildren() {
        if(selectedParent != null) {
            childrenList = service.getChildrenListByParent(selectedParent);
        } else {
            childrenList = null;
        }
    }

    // Getters and setters.
}

子级列表将根据其父级进行填充,即子级列表应仅包含与特定父级关联的子级.

The children list is to be populated based on their parent i.e. the children list should only contain children associated with a particular parent.

在选择父级列表中的第一个父级时,子级列表应重置为空,即在没有父级的情况下子级不可见.

When the first parent in the parent list is selected, the children list should be reset to empty i.e. children should not be visible without their parent.

由于父列表具有必需的字段验证器,因此将导致验证.当选择在父列表中的第一项,孩子列表将来自因被更新来防止.从技术上讲,这没有什么错,但是没有父母的孩子的存在可能会给最终用户带来不好的体验.

Since the parent list has a required field validator, it causes validation. When the first item in the parent list is selected, the children list will be prevented from being updated because of required="true". There is technically nothing wrong but existence of children without their parent may give end-users a bad experience.

应该发生什么是,被选择在父列表中的第一项的情况下,它不应该导致验证即验证将被有条件地跳过.

What should happen is, when the first item in the parent list is selected, it should not cause validation i.e. the validation is to be skipped conditionally.

一种执行此操作的方法是检查selectedChildchildrenList本身是否为空/空.例如

One way of doing this is to check either the selectedChild or childrenList itself is null/empty. Such as,

required="#{empty selectedChild or empty childrenList}"

但是,在这种情况下,这似乎并不是规范地跳过验证的规范方法.

But this does not appear to be a canonical way of skipping validation conditionally in such cases.

是否存在跳过的验证中,当在父列表中的第一项被选择,以使孩子列表可以清空作为与父列表以及沿一个更好的方法(审定应该引起在所有其他情况下,例如,那么表单本身是同步提交还是异步提交)?

Does there exist a better way of skipping validation, when the first item in the parent list is selected so that the children list can be emptied as well along with the parent list (The validation should cause in all other cases. For example, when the form itself is submitted either synchronously or asynchronously)?

推荐答案

基本上,您需要与操作有关的验证. IE.调用特定的<p:ajax>动作时跳过验证,而不是其他动作.

Basically, you want action-dependent validation. I.e. skip validation when that specific <p:ajax> action is invoked, and not on other actions.

不幸的是,在视图中声明这确实不是一件容易的事.有几种技巧/解决方法.最常用的一种方法是仅检查是否(不)调用了特定操作.

This is unfortunately indeed not trivial to declare in the view. There are several tricks/workarounds for that. Most used one is to just check if the particular action is (not) invoked.

例如通过确定

或者通过确定组件自身的客户端ID是否不等于HTTP请求参数(具有预定义名称javax.faces.source来表示ajax请求的源)来检查是否调用了组件自身的<p:ajax>(下面的#{component}是隐式的表示当前 UIComponent 的EL变量):

Or check if component's own <p:ajax> is not invoked by determining if component's own client ID does not equal the HTTP request parameter with predefined name javax.faces.source representing the source of the ajax request (the #{component} below is an implicit EL variable representing the current UIComponent):

<h:form>
    <p:selectOneMenu ... required="#{param['javax.faces.source'] ne component.clientId}">
        ...
        <p:ajax ... />
    </p:selectOneMenu>
    <p:selectOneMenu ... required="true">
        ...
    </p:selectOneMenu>
    <p:commandButton ... />
</h:form>

或检查父表单是否由中使用完整表单提交"时,它才会评估true(<p:ajax process>默认为@this,不会触发完整表单提交",而<p:commandButton process>默认为@form,因此将触发完整表单提交"):

Or check if the parent form is submitted by UIForm#isSubmitted(), which would only evaluate true when a "full form submit" is used as in process="@form" (the <p:ajax process> defaults to @this which wouldn't trigger a "full form submit", and the <p:commandButton process> defaults to @form, which would thus trigger a "full form submit"):

<h:form binding="#{form}">
    <p:selectOneMenu ... required="#{form.submitted}">
        ...
        <p:ajax ... />
    </p:selectOneMenu>
    <p:selectOneMenu ... required="true">
        ...
    </p:selectOneMenu>
    <p:commandButton ... />
</h:form>

或者不通过通过 UIComponent#getNamingContainer() (如果您知道组件树中的位置;例如,如果表单是2个将容器父级命名回去的,则使用#{component.namingContainer.parent.namingContainer.submitted}):

<h:form>
    <p:selectOneMenu ... required="#{component.namingContainer.submitted}">
        ...
        <p:ajax ... />
    </p:selectOneMenu>
    <p:selectOneMenu ... required="true">
        ...
    </p:selectOneMenu>
    <p:commandButton ... />
</h:form>

选择.第一种解决方案之前已经被提供了好几次,因为初学者最容易理解和调整它.

Take your pick. The first solution has been offered several times before as it's most easy to understand and tweak by starters.

  • How to let validation depend on the pressed button?
  • Primefaces dependent selectOneMenu and required="true"
  • How to disable the required tag on a selectOneMenu when p:ajax event=change?

这篇关于跳过验证有条件地,当空F:选择信息中的p/H:selectOneMenu用于选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆