0
votes

I'm facing a strange behavior in my jsf datatable component and couldn't figure out what`s going on. This is the scenario: I have a datatable with a remove button on each row. When I click on the button of the last row, it is correctly deleted. When I click on the button in the row before the last row, it deletes the row itself and also the next row. No row above it is affected.

My environment: Eclipse Neon + Tomcat 8 + Primefaces 6.0

I'm running the project from inside Eclipse.

The datasource of the p:dataTable is being modified by data selected from a p:autoComplete component.

In debbuging mode I could check that the remove method is being called multiple times with different parameters each time. Bellow is a part of the code.

It seems (looking at the browser developer tool) that the Ajax is calling the server method just once, so the multiple execution is happening at the server side.

I've already googled for similar issues in links like Link 1 and Link 2.

The page.xhtml:

<p:autoComplete id="ddl" dropdown="false"
                value="#{bean.chosenItem}" var="item"
                itemLabel="#{item.name}" itemValue="#{item}"
                converter="convertItem"
                emptyMessage="No item found" queryDelay="1000"
                minQueryLength="3" autocomplete="off"
                completeMethod="#{bean.findItemsCompleteText}"
                forceSelection="true" placeholder="Type item name"
                cache="true" widgetVar="dllWGV">
    <p:ajax event="itemSelect"
            listener="#{bean.addToDataTable}"
            update="dtb ddl" />
</p:autoComplete>

<p:dataTable id="dtb"
             value="#{bean.chosenItems}" var="rowItem"
             sortBy="#{rowItem.name}" scrollable="true" scrollHeight="90"
             scrollWidth="337" tableStyle="#{bean.dtbStyle}"
             widgetVar="dtbWGV">
      <p:column style="border: none; padding-left: 2px;">
          <p:commandButton actionListener="#{bean.removeFromDataTable(rowItem)}"
                         update="dtb"
                         style="margin-right: 2px;" icon="fa fa-trash" />
          <h:outputText value="#{rowItem.name}" />
      </p:column>

      <p:column style="border: none; width: 28%;">
          <p:spinner suffix="%" min="0" max="100" stepFactor="0.25"
                     value="#{rowItem.dAux}" size="5" />
      </p:column>
</p:dataTable>

The managed bean (ViewScoped):

private ItemClass chosenItem;
private List<ItemClass> chosenItems;
private String dtbStyle;

//getters and setters with no logic inside
//beyond getting and setting the properties

@PostConstruct
public void init(){
    if (chosenItems == null) {
        chosenItems = new ArrayList<ItemClass>();
    }
    setDtbStyle("visibility: hidden; width: 320px;");
}

//each time, during the multiple executions,
//the parameter localItem has a different value
public void removeFromDataTable(ItemClass localItem) {
    this.chosenItems.remove(localItem);
    if(chosenItems.size() == 0) {
        setDtbStyle("visibility: hidden; width: 320px;");
    }
}

public void addToDataTable(SelectEvent event) {
    this.chosenItems.add(this.chosenItem);
    setDtbStyle("visibility: visible; width: 320px;");
    this.chosenItem = null;
}

Thanks for any clue about what could be happening.

Juliano

1

1 Answers

1
votes

After reading here and here, I tried put process="@this" on the remove p:commandButton in the p:dataTable. It has made the trick, but I don`t know excactly how. I've understood that @this tells the server to process just the methods in the actionLinstener of the p:commandButton, ignoring any other actions in other components of the page. Well, the fact that this modification has worked points that the problem is in the overall logic of my page. Actually, I don't know where exactly my mistake is, but as the page is pretty heavy, I'm almost sure there really is a silly mistake of mine somewhere in it.

[1]:Clicking p:commandButton causes the value of p:selectOneMenu being set twice
[2]:Understanding process and update attributes of PrimeFaces

The page.xhtml was modified to:

<p:dataTable id="dtb"
             value="#{bean.chosenItems}" var="rowItem"
             sortBy="#{rowItem.name}" scrollable="true" scrollHeight="90"
             scrollWidth="337" tableStyle="#{bean.dtbStyle}"
             widgetVar="dtbWGV">
      <p:column style="border: none; padding-left: 2px;">
          <p:commandButton actionListener="#{bean.removeFromDataTable(rowItem)}"
                           update="dtb" 
                           process="@this" <!--solution: adding this attribute-->
                           style="margin-right: 2px;" icon="fa fa-trash" />
          <h:outputText value="#{rowItem.name}" />
      </p:column>

      <p:column style="border: none; width: 28%;">
          <p:spinner suffix="%" min="0" max="100" stepFactor="0.25"
                     value="#{rowItem.dAux}" size="5" />
      </p:column>
</p:dataTable>