2

I have the following JSF 2 code:

    <p:selectOneMenu id="dropdown" value="#{data.selection}" required="true" converter="selectOneMenuConverter">
            <f:selectItem itemLabel="Select one..." itemValue="" noSelectionOption="true" />
            <f:selectItems value="#{data.entries}" var="entry" itemLabel="#{entry.name}" itemValue="#{entry}" />
            <p:ajax update="display" event="change" />
    </p:selectOneMenu>

    <h:panelGroup id="display">
            <h:outputText value="#{data.selection}" />
    </h:panelGroup>

Everything works as expected when I choose a value from the dropdown. When the user "deselects" an entry by choosing "Select One", JSF complains that this is not possible because the selectonemenu is required.

The problem comes from there that the p:ajax makes a partial submit that triggers validation. Immediate=true does also not work because in case the immediate happens on an input field (like selectonemenu is) a validation is performed. The validation shall only happen when the user presses the "go on" button on the bottom of the page (not shown in code)

Further the given converter converts the Strings to Objects and for the default value it returns null (that's also the expected value within the domain for "no selection").

So my question is what I must do to fulfill my case. For my this is a standard case and I cannot imagine that there is no solution for this.

Any ideas?

Best regards, Florian

Florian Huonder
  • 461
  • 1
  • 7
  • 17

1 Answers1

3

The validation shall only happen when the user presses the "go on" button on the bottom of the page (not shown in code)

Then just tell the dropdown's required attribute to do exactly that instead of hardcoding a true.

<h:form id="form">
    <p:selectOneMenu ... required="#{not empty param['form:go']}">
        ...
    </p:selectOneMenu>

    ...

    <p:commandButton id="go" ... />
</h:form>

The #{not empty param['form:go']} will only evaluate true when the form submit has actually been taken place by the submit button which has the client ID form:go in the particular example. If you don't like hardcoding client IDs either, then reference it as follows:

<h:form>
    <p:selectOneMenu ... required="#{not empty param[go.clientId]}">
        ...
    </p:selectOneMenu>

    ...

    <p:commandButton binding="#{go}" ... />
</h:form>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Hi, It's me again. We encounter a very strange problem. The stuff with the param and clientId works on textfields but not on a p:selectOneMenu. We have everywhere the required="not empty param..." el in textfields and dropdowns. The on the "go" button we have a binding and on the "save" button we have no binding. Now when I press the "save" button all selectOneMenus turn red with the hint that validation failed. – Florian Huonder Nov 26 '12 at 08:03
  • Addition, the expression: #{not empty param[go.clientId]} evaluates to false but jsf complains that a value is required. – Florian Huonder Nov 26 '12 at 08:50
  • Is it really the only way? One thing we miss using this approach is the automatic insertion of "*" pointing that this field is required. – Diego Urenia Feb 17 '16 at 18:43
  • 1
    @Diego: add `or facesContext.currentPhaseId.ordinal eq 6` to the condition. – BalusC Feb 17 '16 at 18:45
  • I said it too early. Unfortunately, it's evaluated to true indeed, but jsf let the required validation pass. The workaround was to add a NullValidator wrote by ourselves and mix both things. Any thoughts, @BalusC? – Diego Urenia Feb 25 '16 at 20:17