stakahop
stakahop

Reputation: 951

p:datatable not updating rows properly

I have p:datatable and p:inputSwitch in one column which indicates "selected" row. I trigger p:ajax event on p:inputswitch, and other rows become unselected by listener, and current row becomes selected. On that event I update datatable, all entries in backing bean have a proper values, switch is on, but it is still red.

<h:panelGroup layout="block" styleClass="ui-g-12 refinance" id="cotPanel">

    <p:dataTable id="cot" value="#{cot.cods}" var="offer" reflow="true">
            <p:column width="18%" headerText="OFFER">
                    <p:outputLabel value="#{offer.name}" />
            </p:column>
            <p:column headerText="AAA" width="18%" styleClass="num">
                    <p:outputLabel value="#{of:formatNumberDefaultForLocale(offer.aaa, 'nl_NL')}" />
            </p:column>
            <p:column headerText="BBB" width="18%">
                    <p:outputLabel value="#{offer.bbb}" />
            </p:column>
            <p:column headerText="CCC" width="18%" styleClass="num">
                    <p:outputLabel value="#{of:formatNumberDefaultForLocale(offer.ccc, 'nl_NL')}" />
            </p:column>
            <p:column headerText="DDD" width="18%" styleClass="num">
                    <p:outputLabel value="#{offer.ddd}" />
                        </p:column>
            <p:column headerText="Select" width="10%">
                    <h:panelGroup styleClass="Width100 Flex">
                            <p:inputSwitch value="#{offer.selected}">
                                    <p:ajax event="change" listener="#{cot.onSelectCod(offer)}" process="@this"
                                        update="mainForm:cotPanel" />
                            </p:inputSwitch>
                    </h:panelGroup>
            </p:column>
            <p:column headerText="SELECTED" width="10%">
                    <p:outputLabel value="#{offer.selected}"/>
            </p:column>
    </p:dataTable>
</h:panelGroup>

and in backing bean listener:

public void onSelectCod(Cod entry) {
    if (entry.isSelected()) {
        for (Cod codTemp : cods) {
            if (!entry.equals(codTemp)) {
                codTemp.setSelected(false);
            }
        }
    }else {
        // i dont let it become unselected if click on selected row, it becomes unselected only if it is clicked on another entry
        entry.setSelected(true);
    }
}

Last column in datatable shows me that all values are right, input switch is on right side, but it is red. I also tried to write a styleClass which is "green" when selected is true and "red" otherwise, and I see in DOM that all other rows get correct class, but selected row not.

enter image description here

Upvotes: 0

Views: 523

Answers (1)

Aritz
Aritz

Reputation: 31679

The problem comes with the fact that you're altering many values in your listener method. When you update the table, the other switches are changed and this triggers the rest of the listeners.

Instead, you could use the click event instead of change:

<p:inputSwitch value="#{offer.selected}" styleClass="#{offer.selected ? 'green' : 'red'}">
        <p:ajax event="click" process="@this" listener="#{cot.onSelectCod(offer)" 
            update="mainForm:cotPanel" />
</p:inputSwitch>

This way you ensure that the listener method gets invoked only for the switch the user interacts with.

Also you'll need to rewrite your listener method a bit, because now it should get called only with the object you're interested in:

public void onSelectCod(Cod entry) {
    // The entry here is now selected (you set it in the inputSwitch value)
    // So just mark the rest of the entries as unselected
    for (Cod codTemp : cods) {
        if (!entry.equals(codTemp)) {
            codTemp.setSelected(false);
        }
    }
}

Upvotes: 1

Related Questions