question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Datatable: Displayed row does not match actionlistener data after update + sort

See original GitHub issue

Describe the defect We use the client datatable widgetvar to clear or reapply the filter to the datatable on data update. After the migration to PF 10 (from 6.1) we are now experiencing wrong data in our row commandButtons.

Reproducer See primefaces-test-datatable-issue.zip or relevant snippets below

Environment:

  • PF Version: 10.0
  • JSF + version: e.g. Mojarra 2.2.20 or MyFaces 2.3.9
  • Affected browsers: e.g. Chrome, iOS, ALL

To Reproduce Steps to reproduce the behavior:

  1. Go to ‘http://localhost:8080/primefaces-test/
  2. Click on ‘Show ID’ in row with ID=2
  3. “ID = 2” is shown below of table
  4. Click “Reload Tabledata”
  5. Sort by column “Dummy”
  6. Click on “Show ID” in 3rd row (id 1, Falcon)
  7. “ID = 2” is shown below of table

Expected behavior The ID should match the ID shown in the first column of the table

Additional notes After the data update each sort does change the shown row order but it seems that the rows used for the actionlistener stay in the “old” order.

We get the same results, regardless if PF('carsTableWidget').filter(); or PF('carsTableWidget').clearFilters(); is used after update. It works without the javascript call - but then the displayed content does not match an entered filter.

Using a filter (e.g. enter something in the color filter, then clearing it) restores the row data and the actionlistener shows the correct data again

Example XHTML

<h:form id="frmTest">

        <p:commandButton value="Reload Tabledata"
                         actionListener="#{testView.loadCars}"
                         update="carstable, frmTest:iddisplay"
                         oncomplete="PF('carsTableWidget').filter();"/>

        <p:dataTable id="carstable"
                     widgetVar="carsTableWidget"
                     value="#{testView.cars}"
                     var="car"
                     rowKey="#{car.id}">
            <p:column headerText="ID"
                      filterBy="#{car.id}"
                      sortBy="#{car.id}">
                <h:outputText value="#{car.id}"/>
            </p:column>
            <p:column headerText="NAME"
                      filterBy="#{car.name}"
                      sortBy="#{car.name}">
                <h:outputText value="#{car.name}"/>
            </p:column>
            <p:column headerText="COLOR"
                      filterBy="#{car.color}"
                      sortBy="#{car.color}">
                <h:outputText value="#{car.color}"/>
            </p:column>
            <p:column headerText="DUMMY"
                      filterBy="#{car.dummy}"
                      sortBy="#{car.dummy}">
                <h:outputText value="#{car.dummy}"/>
            </p:column>
            <p:column headerText="ACTIONS">
                <p:commandButton value="Show ID" actionListener="#{testView.printId(car.id)}"
                                 update="frmTest:iddisplay"/>
            </p:column>

        </p:dataTable>


        <h:outputText id="iddisplay" value="ID = #{testView.integer}"/>


    </h:form>

Example Bean

package org.primefaces.test;

import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;

@Getter
@Setter
public class Car implements Serializable {
    private int id;
    private String name;
    private String color;
    private String dummy;

    public Car(int id, String name, String color, String dummy) {
        this.id = id;
        this.name = name;
        this.color = color;
        this.dummy = dummy;
    }

    public Car(){

    }
}
package org.primefaces.test;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import lombok.Data;

@Data
@Named
@ViewScoped
public class TestView implements Serializable {
    
    private String string;
    private Integer integer;
    private BigDecimal decimal;
    private LocalDateTime localDateTime;

    List<Car> cars;
    List<Car> selectedCars;
    List<Car> filteredCars;

    @PostConstruct  
    public void init() {
        string = "Welcome to PrimeFaces!!!";
        loadCars();
    }


    public void loadCars() {
        this.cars = new ArrayList<>();
        this.cars.add(new Car(0, "Baron", "red", "dummy4"));
        this.cars.add(new Car(1, "Falcon", "blue", "dummy3"));
        this.cars.add(new Car(2, "Hawk", "Grey", "dummy2"));
        this.cars.add(new Car(4, "Eagle", "Yellow", "dummy1"));
        integer = -1;
    }

    public void printId(int id){
        integer = id;
    }

}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
tandraschkocommented, Jul 19, 2021

i can run it but i also built PF local without jitpack but the bug is still existent

@Rapster any idea?

0reactions
iki-haconcommented, Jul 30, 2021

@tandraschko I have now analysed the source code of 10.0.0 and master quite a bit and it seems that a small little change fixes my issue. The question is if this has some side effects which I do not foresee?

My fix is: org.primefaces.component.datatable.feature.SortFeature.java

Add the following 2 lines to the end of

public void sort(FacesContext context, DataTable table) {
[...]
        // MONKEYPATCH to fix data model after update
        table.updateFilteredValue(context, list);
        table.setValue(value);
    }

If I put a patched SortFeature.java like this into the test project, I can not reproduce the issue any more. Any thoughts on this?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Datatable is not updated after actionListener - Stack Overflow
The filter() method is executed correctly and the list in the bean are correct (I search for 11 elements and I got it),...
Read more >
Rows not returned after column search — DataTables forums
Just want to show that the data is updated with the cell().data() and row().data() . However the table isn't updated with regards to...
Read more >
DataTable | PrimeFaces JavaScript API Docs
Adds the given sorting to the list of sort rows. Each sorting describes a column by which to sort. This data table may...
Read more >
Using datatables - The BalusC Code
When putting just a h:selectOneRadio component in a h:column column, the radio buttons gets rendered, but they are not grouped together. Each ...
Read more >
Get row data from an ActionListener
If you you have a command link or button in a row of a dataTable, there is an easy way to get to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found