0
votes

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

1
I see you've got static styleClass attributes, how could they be switched?Xtreme Biker
It doesnt change even if I remove this.stakahop
I mean, where are your red and green classes supposed to be set for the table line? You don't tell JSF about this, at least in the code you provide here. You only change the selected property values and update the panel.Xtreme Biker
I removed them, because component should allow that, right? Because I update entire datatable. I put them in p:inputSwitch tag, something like styleClass="#{offer.selected ? 'green' : 'red'}". But nothing.stakahop
Does this last code update the classes for the inputSwitch in the DOM? If it is, it might be a CSS problem (the style needs to be fixed). If not, then that is a JSF related problem (the component not being properly referenced or any validation error). If the second case, I guess your request hits the server and onSelectCod is being processed (as you state in your question), so then it should definitely be a problem with how you reference the panel component.Xtreme Biker

1 Answers

1
votes

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);
        }
    }
}