Abilitare il drag&drop delle righe di una tabella in Angular

di Morgan Pizzini, in HTML5, Angular,

Le table sono lo strumento piú utile per la visualizzazione e il controllo dei dati. Tramite il solo HTML l'utente non ha la possibilitá di effettuare filtri e/o modifiche ai dati, ed è per questo motivo che, nel corso degli anni, sono state create innumerevoli librerie che permettono di filtrare, aggiornare, modificare, espandere le tabelle e, non da ultima, muovere le righe. In Angular questo è possibile direttamente tramite la libreria CDK e l'attributo cdkDrag.

Partendo da una normale tabella HTML, è necessario inserire gli attributi in modo tale che venga rilevata dal CDK e aggiungere le direttive cdkDrag e cdkDropListDropped, rispettivamente all'elemento a cui verrà data la possibilità di essere trascinato e all'evento di rilascio dell'elemento. Un esempio del codice necessario è visibile nel seguente snippet di codice.

<table cdk-table [dataSource]="dataSource" cdkDropList (cdkDropListDropped)="drop($event)">

  <ng-container cdkColumnDef="position">
    <th cdk-header-cell *cdkHeaderCellDef> Posizione </th>
    <td cdk-cell *cdkCellDef="let element"> {{element.position}} </td>
  </ng-container>

  <ng-container cdkColumnDef="name">
    <th cdk-header-cell *cdkHeaderCellDef> Nome </th>
    <td cdk-cell *cdkCellDef="let element"> {{element.name}} </td>
  </ng-container>

  <ng-container cdkColumnDef="translate">
    <th cdk-header-cell *cdkHeaderCellDef> Traduzione </th>
    <td cdk-cell *cdkCellDef="let element"> {{element.translate}} </td>
  </ng-container>

  <tr cdk-header-row *cdkHeaderRowDef="displayedColumns"></tr>
  <tr cdk-row *cdkRowDef="let row; columns: displayedColumns;" cdkDrag></tr>
</table>

In TypeScript dobbiamo solo preoccuparci di fornire una lista observable di oggetti e la funzione che gestisce il drop della riga.

import {DataSource} from '@angular/cdk/collections';
import {Component} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';

@Component({
  selector: 'my-app',
  styleUrls: ['app.component.scss'],
  templateUrl: 'app.component.html',
})
export class AppComponent {
  displayedColumns: string[] = ['position', 'name', 'translate'];
  source=  [
      {position: 1, name: 'Primo', translate: 'first'},
      {position: 2, name: 'Secondo', translate: 'second'},
      {position: 3, name: 'Terzo',translate: 'third'},
    ]
  dataSource = new BehaviorSubject<any[]>(this.source);
  
  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.source, event.previousIndex, event.currentIndex)
    this.dataSource.next([...this.source]);
  }
}

Se poi volessimo aggiungere ombreggiature e un feedback visivo fluido, possiamo creare codice CSS che va ad aggiungere stile agli elementi creati dal CDK.

.cdk-drag-preview {
  box-sizing: border-box;
  border-radius: 4px;
  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
              0 8px 10px 1px rgba(0, 0, 0, 0.14),
              0 3px 14px 2px rgba(0, 0, 0, 0.12);
}

.cdk-drag-placeholder {
  opacity: 0;
}

.cdk-drag-animating {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

tr:last-child {
  border: none;
}

table.cdk-drop-list-dragging tr:not(.cdk-drag-placeholder) {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi