Skip validation conditionally, when empty f:selectItem in p/h:selectOneMenu is selected

谁都会走 提交于 2019-12-02 02:11:21
BalusC

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.

E.g. check if the desired save button is invoked by determining the presence of its client ID in the HTTP request parameter map as available by implicit EL object #{param}:

<h:form>
    <p:selectOneMenu ... required="#{not empty param[save.clientId]}">
        ...
        <p:ajax ... />
    </p:selectOneMenu>
    <p:selectOneMenu ... required="true">
        ...
    </p:selectOneMenu>
    <p:commandButton binding="#{save}" ... />
</h:form>

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>

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>

Or without binding the form by referencing the form via UIComponent#getNamingContainer() (if you know the position in the component tree; if the form is e.g. 2 naming container parents back, then use #{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.

See also:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!