Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selection lost after Pagination and searching in multiselect mode. #935

Open
rizvi-ongraph opened this issue Jan 23, 2019 · 8 comments
Open

Comments

@rizvi-ongraph
Copy link

When I use selectMode "multi", after selection one or more rows when I change the page or filter any data, the previous selections are lost and all rows are unselected now.

@HansDampf789
Copy link

I can confirm this behavior. There are already some issues open concerning this problem...
#568
#235

@caioladislau
Copy link

I can confirm this too.

@t0nyak
Copy link

t0nyak commented Apr 10, 2019

I also can confirm this behavior and I'd like also to add another situation where this behaviour appears. I'll summarize. As far as I can see, there are three situations where selection is lost:

  1. After pagination
  2. After searching/filtering
  3. After sorting a column

I'd like also to make a suggestion, since I think it would solve all these situations and it would be really simple solution, but I haven't been able to find it in the documentation.

It would be enough adding to the list of Component Outputs/Events:

  • (sortColumn)
  • (filterColumn)
  • (pageChange)

And later emitting them when any of the actions is performed.

This is a 6 line change which would solve these 3 cases and both of the related open issues #568 and #235. I'm not able to work on this right now, but if you're ok and also the team, I'll implement it tomorrow and send a PR to have this solve and working for other people.

@t0nyak
Copy link

t0nyak commented Apr 10, 2019

Actually, I've just found that here src/ng2-smart-table/ng2-smart-table.component.ts:174-188 the 3 of these methods are calling resetAllSelectors() specifically, so I think there should be some reason to do it.

Hope some of the dev team is able to explain this better

@t0nyak
Copy link

t0nyak commented Apr 15, 2019

Hi Guys!

I'm glad to tell you that I've found a solution. It's a bit more complicated than the one I commented some days ago but it works perfect for me and it makes sense, actually.

I've used a ViewChild object in my component, being an instance of Ng2SmartTableComponent, like this:

@ViewChild(Ng2SmartTableComponent) myTable: Ng2SmartTableComponent;

After this, I've an Observable for sorting event (although it could be also page change/filtering) and I can redraw the selection using the table's grid and its methods selectRow() and multipleSelectRow(), like this:

switch (changes.action) {
        // Do the same whenever is needed in case of filtering/page changing
        case 'sort':
          this.myTable.grid.getRows().forEach(row => {
            if (this.currentSelected.find(elem => elem.id === row.getData().id)) {
              this.myTable.grid.multipleSelectRow(row);
            }
          });
      }

Hope this helps y'all.

@steverogers180
Copy link

May be the issue is solved as commented here. Using custom render component for checkbox and it is working.

@ccruza
Copy link

ccruza commented Feb 14, 2020

Hello there. I guess I found a solution:

HTML:

<ng2-smart-table [settings]="settings" [source]="source" **(userRowSelect)="onUserRowSelect($event)"** #table>
            </ng2-smart-table>

Component (TS):


// Implements **AfterViewChecked** 
export class ExtRegistroOrdenCompraComponent implements OnInit, AfterViewChecked {

// Constructor
 constructor(....
        private cdr: ChangeDetectorRef, ...
    ) {}

// Needed variables
@ViewChild('table') table: Ng2SmartTableComponent;
selectedItems: any[] = [];


// Implementation of method..
ngAfterViewChecked(): void {
        this.syncTable();
    }

// This method is doing the magic. please be careful that Order_No, Line_No, Release_No and Receipt_No are my key values so replace it for yours.

syncTable(): void {

        this.table.grid.getRows().forEach((row) => {

            if (this.selectedItems.find(r => r.Order_No == row.getData().Order_No && r.Line_No == row.getData().Line_No &&
                r.Release_No == row.getData().Release_No && r.Receipt_No == row.getData().Receipt_No)) {
                row.isSelected = true;
            }
        });

        this.cdr.detectChanges();
    }


// This is a method that is called when user click on select
// for some reason event.selected contains only the rows for the current page (of pagination) so for example if I have selected 2 rows on page 1 and then I go to page 2 and select 1 more row, the previous 2 rows of page 1 get cleared.. but... I'm saving the previous 2 rows in an array and then concat with the "new" rows being selected.. then just remove the duplicates and when "syncTable()" is triggered the values return to be selected.

public onUserRowSelect(event) {
        let UtilArray = [];

        this.selectedItems = this.selectedItems.**concat**(event.selected);

        this.selectedItems.forEach((item, index) => {
            if (UtilArray.findIndex(i => i.Order_No == item.Order_No && i.Line_No == item.Line_No &&
                i.Release_No == item.Release_No && i.Receipt_No == item.Receipt_No) === -1) {
                UtilArray.push(item)
            }
        });
        this.selectedItems = UtilArray;

    }

Hope you can achieve this! Greetings from Lima, Perú 👍

@shubanker
Copy link

shubanker commented Mar 11, 2020

Hello there. I guess I found a solution:

HTML:

<ng2-smart-table [settings]="settings" [source]="source" **(userRowSelect)="onUserRowSelect($event)"** #table>
            </ng2-smart-table>

Component (TS):


// Implements **AfterViewChecked** 
export class ExtRegistroOrdenCompraComponent implements OnInit, AfterViewChecked {

// Constructor
 constructor(....
        private cdr: ChangeDetectorRef, ...
    ) {}

// Needed variables
@ViewChild('table') table: Ng2SmartTableComponent;
selectedItems: any[] = [];


// Implementation of method..
ngAfterViewChecked(): void {
        this.syncTable();
    }

// This method is doing the magic. please be careful that Order_No, Line_No, Release_No and Receipt_No are my key values so replace it for yours.

syncTable(): void {

        this.table.grid.getRows().forEach((row) => {

            if (this.selectedItems.find(r => r.Order_No == row.getData().Order_No && r.Line_No == row.getData().Line_No &&
                r.Release_No == row.getData().Release_No && r.Receipt_No == row.getData().Receipt_No)) {
                row.isSelected = true;
            }
        });

        this.cdr.detectChanges();
    }


// This is a method that is called when user click on select
// for some reason event.selected contains only the rows for the current page (of pagination) so for example if I have selected 2 rows on page 1 and then I go to page 2 and select 1 more row, the previous 2 rows of page 1 get cleared.. but... I'm saving the previous 2 rows in an array and then concat with the "new" rows being selected.. then just remove the duplicates and when "syncTable()" is triggered the values return to be selected.

public onUserRowSelect(event) {
        let UtilArray = [];

        this.selectedItems = this.selectedItems.**concat**(event.selected);

        this.selectedItems.forEach((item, index) => {
            if (UtilArray.findIndex(i => i.Order_No == item.Order_No && i.Line_No == item.Line_No &&
                i.Release_No == item.Release_No && i.Receipt_No == item.Receipt_No) === -1) {
                UtilArray.push(item)
            }
        });
        this.selectedItems = UtilArray;

    }

Hope you can achieve this! Greetings from Lima, Perú 👍

You forgot to handle unchecking the checkbox.

public onUserRowSelect(event) {
    
    if (event.data === null) {
      //Select all/none
      this.selectedItems = event.selected.length ? this.selectedItems.concat(event.selected):[];
    } else {
      if (event.isSelected) {
        this.selectedItems = this.selectedItems .concat(event.selected);
      } else {
        const index = this.selectedItems .indexOf(event.data);
        if (index !== -1) {
          this.selectedItems .splice(index, 1);
        }
      }
    }
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants