javascriptangulardrag-and-dropprimenggrouped-table

Data is not corrected after reordering if there are groupRowsBy?


I created a table with groupRowsBy and can reorder rows, but the result does not change after dragging and dropping the rows. Please help me with this case.

 this.data = [
  {
    id: 1,
    groupOrder: 1,
    group_by: { name: 'Manager', id: 1 },
    name: 'Manager 1',
    title: '1.1 Manager 1',
  },
  {
    id: 2,
    code: 1.2,
    groupOrder: 1,
    group_by: { name: 'Manager', id: 1 },
    name: 'Manager 2 ',
    title: '1.2 Manager 2',
  },
  {
    id: 7,
    groupOrder: 2,
    group_by: { name: 'Support', id: 2 },
    name: 'Support',
    title: '2.1 Support',
  },
];

Row Group Subheader enter link description here

Reorder enter link description here

This my code enter link description here


Solution

  • I am guessing the problem you are facing is that on drag and drop the datasource (this.data) is not updated. We need to do this programatically using the table row re-order event.


    When you drag and drop, instead of listening to the drag event, you can listen for the prime-ng table event onRowReorder.

    <div class="card">
      <!-- remove groupRowsBy="group_by.id" will corrcet data afert drop ??? -->
      <p-table
        [value]="data"
        sortMode="single"
        [scrollable]="true"
        rowGroupMode="subheader"
        groupRowsBy="group_by.id"
        (onRowReorder)="onRowReorder($event)"
      >
      ...
    

    This provides you two details dragIndex and dropIndex .We can use these two details and swap the array elements, I have used the move element to another position in array answer below:

    Move an array element from one array position to another

    onRowReorder(data: any) {
      console.log(data);
      array_move(this.data, data.dragIndex, data.dropIndex);
    }
    

    Full Code:

    TS:

    import { Component, OnInit } from '@angular/core';
    import { ImportsModule } from './imports';
    import { CommonModule } from '@angular/common';
    
    function array_move(arr, old_index, new_index) {
      if (new_index >= arr.length) {
        var k = new_index - arr.length + 1;
        while (k--) {
          arr.push(undefined);
        }
      }
      arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
      return arr; // for testing
    }
    
    @Component({
      selector: 'table-subheader-grouping-demo',
      templateUrl: 'table-subheader-grouping-demo.html',
      standalone: true,
      imports: [ImportsModule, CommonModule],
    })
    export class TableSubheaderGroupingDemo implements OnInit {
      data: any[] = [];
    
      constructor() {}
    
      ngOnInit() {
        this.data = [
          {
            id: 1,
            groupOrder: 1,
            group_by: { name: 'Manager', id: 1 },
            name: 'Manager 1',
            title: '1.1 Manager 1',
          },
          {
            id: 2,
            code: 1.2,
            groupOrder: 1,
            group_by: { name: 'Manager', id: 1 },
            name: 'Manager 2 ',
            title: '1.2 Manager 2',
          },
          {
            id: 7,
            groupOrder: 2,
            group_by: { name: 'Support', id: 2 },
            name: 'Support',
            title: '2.1 Support',
          },
        ];
      }
    
      rowTrackBy(_, item: any) {
        return item.id;
      }
    
      onRowReorder(data: any) {
        array_move(this.data, data.dragIndex, data.dropIndex);
      }
    }
    

    HTML:

    <div class="card">
      <!-- remove groupRowsBy="group_by.id" will corrcet data afert drop ??? -->
      <p-table
        [value]="data"
        sortMode="single"
        [scrollable]="true"
        rowGroupMode="subheader"
        groupRowsBy="group_by.id"
        (onRowReorder)="onRowReorder($event)"
      >
        <ng-template pTemplate="header">
          <tr>
            <th>#</th>
            <th>item</th>
          </tr>
        </ng-template>
    
        <ng-template pTemplate="groupheader" let-item>
          <tr pRowGroupHeader>
            <td colspan="100" class="font-weight-bold">{{ item.group_by.name }}</td>
          </tr>
        </ng-template>
    
        <ng-template pTemplate="body" let-item let-rowIndex="rowIndex">
          <tr pDraggable="item" [pReorderableRow]="rowIndex">
            <td>
              <span class="pi pi-bars" pReorderableRowHandle></span>
            </td>
            <td>{{ item.code }} {{ item.name }}</td>
          </tr>
        </ng-template>
      </p-table>
    </div>
    <pre>{{data | json}}</pre>
    

    Stackblitz Demo