4Money
4Money

Reputation: 179

p:selectOneMenu get just first value from list primefaces JSF

i have p:selectOneMenu, all values are viewed correctly but just first on my list can be chosen for example, on my list i have e-mail addresses, i can choose everyone but mail is sending just on first of them on list. My JSF code:


<p:dataTable value="#{additionalOrdersBean.additionalOrdersList}"
var="additionalOrders" rowIndexVar="lp" id="myTable" editable="true>
    <p:column>
        <p:selectOneMenu id="recipient"  value="#{additionalOrdersBean.mailTo}" converter="#{mailConverter}" required="true" requiredMessage="#{loc['fieldRequired']}">
            <f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail1}" itemValue="#{mail.mail1}" />
            <f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail2}" itemValue="#{mail.mail2}" />
            <f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail3}" itemValue="#{mail.mail3}" />
        </p:selectOneMenu>
        <h:message for="recipient" style="color:red"/>
        <h:commandButton value="#{loc['send']}" action="#{additionalOrdersBean.sendProtocol()}" onclick="sendProtocolDialog.hide()"/>
    </p:column>
</p:dataTable>


My bean:

private String mail1;
private String mail2;
private String mail3;

public List<Building> getBuildingList2() {
    buildingList2 = getBldRepo().findByLocationId(lid);
    return buildingList2;
}



Can anyone know how to fix it? I wont to send e-mail on choosen address not just on first on my list. Thanks

Upvotes: 1

Views: 1832

Answers (1)

BalusC
BalusC

Reputation: 1108642

You seem to expect that only the current row is submitted when you press the command button in the row. This is untrue. The command button submits the entire form. In your particular case, the form is wrapping the whole table and thus the dropdown in every single row is submitted.

However, the value attribute of all those dropdowns are bound to one and same bean property instead of to the currently iterated row.

The consequence is, for every single row, the currently selected value is set on the bean property, hereby everytime overriding the value set by the previous row until you end up with the selected value of the last row.

You've here basically a design mistake and a fundamental misunderstanding of how basic HTML forms work. You basically need to move the form to inside the table cell in order to submit only the data contained in the same cell to the server.

<p:dataTable ...>
    <p:column>
        <h:form>
            ...
        </h:form>
    </p:column>
</p:dataTable>

If that is design technically not an option (for example, because you've inputs in another cells of the same row, or outside the table which also need to be sent), then you'd need to bind the value attribute to the currently iterated row instead and pass exactly that row to the command button's action method:

<p:dataTable value="#{additionalOrdersBean.additionalOrdersList}" var="additionalOrders" ...>
    <p:column>
        <p:selectOneMenu value="#{additionalOrders.mailTo}" ...>
            ...
        </p:selectOneMenu>
        ...
        <h:commandButton value="#{loc['send']}" action="#{additionalOrdersBean.sendProtocol(additionalOrders)}" ... />
    </p:column>
</p:dataTable>

It's by the way not self-documenting and quite confusing to have a plural in the var name. Wouldn't you rather call it additionalOrder? Or is the javabean/entity class representing a single additional order really named AdditionalOrders?


Unrelated to the concrete problem: doing business logic in getter methods is killing your application. Just don't do that. See also Why JSF calls getters multiple times.

Upvotes: 1

Related Questions