primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.55k stars 4.61k forks source link

Table - shiftKey multiple-selection when using checkbox #5496

Closed alecrt closed 2 years ago

alecrt commented 6 years ago

shiftKey multiple-selection seems not to work as expected :

<p-table [columns]="cols" [value]="cars" [(selection)]="selectedCars" dataKey="vin">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th style="width: 2.25em">
                <p-tableHeaderCheckbox></p-tableHeaderCheckbox>
            </th>
            <th *ngFor="let col of columns">
                {{col.header}}
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-rowData let-columns="columns" let-rowIndex="rowIndex">
        <tr [pSelectableRow]="rowData" [pSelectableRowIndex]="rowIndex">
            <td>
                <p-tableCheckbox [value]="rowData"></p-tableCheckbox>
            </td>
            <td *ngFor="let col of columns">
                {{rowData[col.field]}}
            </td>
        </tr>
    </ng-template>
</p-table>
jaredmartinez commented 3 years ago

I am looking for something similar to this. My users would like to be able to select multiple checkboxes with the shiftKey and everything between the indexes is automatically selected. Rows do not need to be selected with this, just the checkboxes.

This functionality is similar to how gmail works. Thanks!

jaredmartinez commented 3 years ago

@yigitfindikli any way we could prioritize this?

OmarEnriqueCocaBuitrago commented 3 years ago

@cagataycivici

I solved it like this :

do not forget to use the "let-rowIndex="rowIndex"" and "[pSelectableRowIndex]="rowIndex""

<ng-template pTemplate="body" let-user let-columns="columns" let-rowIndex="rowIndex">
    <tr [pSelectableRow]="user" [pContextMenuRow]="user" (dblclick)="editUser()" [pSelectableRowIndex]="rowIndex">
        <td *ngIf="userMgmtService.multiMode" style="width: 3em">
            <p-tableCheckbox #checkboxTableP [value]="user" [index]="rowIndex" (click)="checkboxTable(checkboxTableP, $event)"></p-tableCheckbox>
        </td>
    </tr>
</ng-template>

and in the component :

checkboxTable(tableCheckBox: TableCheckbox, event: MouseEvent){
    if(event.button == 0 && event.shiftKey){
        this.mainTable.selectRange(event, tableCheckBox.index);
    }
}
alinbujor commented 3 years ago

Hi Omar,

It somehow works but for me it works only when you click on a row and not on the checkbox. Clicking on the checkbox doesn't do anything. Is it the same for you? Am I missing something?

Thanks, Alin

OmarEnriqueCocaBuitrago commented 3 years ago

Hi @alinbujor ,

for me works in the checkbox, I have not implemented yet with the row. maybe you can post some of your code.

did you use the function in the <p-tableCheckbox> tag ?

jaredmartinez commented 3 years ago

Could you post a stackblitz @OmarEnriqueCocaBuitrago ? I seem to have the same issue. Appreciate you help!

OmarEnriqueCocaBuitrago commented 3 years ago

hi @jaredmartinez In my comment above you find all the code. I don't have much experience with Angular but this would be a solution while PrimeNG team fixes the bug.

jaredmartinez commented 3 years ago

@OmarEnriqueCocaBuitrago

https://stackblitz.com/edit/primeng-tabledoc-demo-wmitv8

What is missing to make this work? Applied your code to the primeng default example in the stackblitz above.

OmarEnriqueCocaBuitrago commented 3 years ago

you are missing the [selectionMode]="'multi'" in die <p-table> so should be like this: <p-table [selectionMode]="'multi'">

lukasmatta commented 3 years ago

I solved this problem with the following solution:

<p-tableCheckbox
    [value]="item"
    [index]="rowIndex"
    (click)="checkboxTable(rowIndex, $event)"
></p-tableCheckbox>
checkboxTable(index: number, event: MouseEvent) {
  if (this.table) {
    if (event.button === 0 && event.shiftKey) {
      this.table?.selectRange(event, index);
      (this.table.anchorRowIndex as any) = null;
    } else {
      this.table.anchorRowIndex = index;
    }
  }
}

The important part is setting the anchorRowIndex property. This solution is just a hack, in the future I expect PrimeNg team to fix Table class so it sets anchorRowIndex in the proper method.

jaredmartinez commented 3 years ago

@lukasmatta thank you for your solution! Works without having the 'multi' mode and row selection.

I took it a little further and added logic for de selection

checkboxTable(tableCheckBox: TableCheckbox, event: MouseEvent) {
    const isChecked = !!event.target.ariaChecked;
    if (event.button === 0 && event.shiftKey) {
      if (isChecked) {
        this.table.selectRange(event, tableCheckBox.index);
      } else {
        this.table.rangeRowIndex = tableCheckBox.index;
        this.table.clearSelectionRange(event);
        this.table.tableService.onSelectionChange();
      }
    }
    this.table.anchorRowIndex = tableCheckBox.index;
  }

Working example here:

https://stackblitz.com/edit/primeng-tabledoc-demo-wmitv8

OmarEnriqueCocaBuitrago commented 3 years ago

@lukasmatta great Job

I did the same with my table but I did not post it because I am having the problem with the counter of the user selected after you unselect them. PrimeNG does not reconize that the list have less user selected but the table shows that you have successfully unselected users.

Alt Text

are you having the same issue ?

ps: better if you use : tableCheckBox.checked instead of const isChecked = !!event.target.ariaChecked;

lukasmatta commented 3 years ago

@OmarEnriqueCocaBuitrago I think that @jaredmartinez improved my solution and added logic for proper deselection. Have you tried the solution he posted above?

mnhock commented 2 years ago

@cagataycivici There are any plans to support multiple selection with shiftkey in checkbox mode?

mertsincan commented 2 years ago

Hi,

So sorry for the delayed response! Improvements have been made to many components recently, both in terms of performance and enhancement. Therefore, this improvement may have been developed in another issue ticket without realizing it. You can check this in the documentation. If there is no improvement on this, can you reopen the issue so we can include it in our roadmap? Please don't forget to add your feedback as a comment after reopening the issue. These will be taken into account by us and will contribute to the development of this feature. Thanks a lot for your understanding!

Best Regards,

Rhobal commented 1 year ago

Behaviour is still the same on primeng 14.2.2 so issue is not closed

vlad-iml commented 1 year ago

I looked at the fix proposed by @OmarEnriqueCocaBuitrago, and for me the shift + click works by simply using [pSelectableRowIndex]="rowIndex", without having to add an additional method checkboxTable in the component. We're currently using PrimeNG v13.3. Hope this can help someone.

    <ng-template pTemplate="body" let-item let-rowIndex="rowIndex">
      <tr
        [pSelectableRow]="item"
        [pSelectableRowIndex]="rowIndex"
      >
fttx commented 8 months ago

But is this highlighting the whole row for you? I need it to work only by clicking the checkbox, like this:

image