Dialog cancellazione-evento

Dialog cancellazione-evento

In questo articolo vedremo come aggiungere alla nostra applicazione la funzionalità di Cancellazione di un evento dalla lista. Per farlo affronteremo un nuovo argomento, le Dialog, o finestre di dialogo. Si tratta di quelle piccole finestra (spesso modali) che per la loro semplicità sono spesso preferibili a un vero e proprio Component. Nel nostro caso la Dialog serve semplicemente a porre all’utente la domanda “vuoi davvero cancellare questo evento? ” e catturarne la risposta.

MODIFICA DEL FILE app.module.ts

Per poter utilizzare una Dialog nel progetto, dobbiamo aggiungerla nelle declarations e negli entryComponents dell’app.module. Per usare i servizi della Material Dialog dobbiamo poi importarne il modulo.

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { AppComponent } from "./app.component";
import { AppRoutingModule } from "./app-routing.module";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import {
  MatInputModule,
  MatPaginatorModule,
  MatProgressSpinnerModule,
  MatSortModule,
  MatTableModule,
  MatIconModule,
  MatButtonModule,
  MatCardModule,
  MatFormFieldModule
} from "@angular/material";
import { MatSelectModule } from "@angular/material/select";
import { MatDialogModule } from "@angular/material";

import { ListaEventiComponent } from "./components/lista-eventi/lista-eventi.component";
import { DettaglioEventoComponent } from "./components/dettaglio-evento/dettaglio-evento.component";
import { DialogCancellazioneEvento } from "./components/dettaglio-evento/dialog-cancellazione-evento";

@NgModule({
  declarations: [
    AppComponent,
    ListaEventiComponent,
    DettaglioEventoComponent,
    DialogCancellazioneEvento
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatInputModule,
    MatTableModule,
    MatPaginatorModule,
    MatSelectModule,
    MatSortModule,
    MatProgressSpinnerModule,
    MatIconModule,
    MatButtonModule,
    MatCardModule,
    MatFormFieldModule,
    MatDialogModule
  ],
  providers: [],
  entryComponents: [DialogCancellazioneEvento],
  bootstrap: [AppComponent]
})
export class AppModule {}

CREAZIONE DEL FILE dialog-cancellazione-evento.html

Nella directory dettaglio-evento creiamo il file  html  corrispondente alla dialog che vogliamo far apparire e  copiamoci il seguente codice:

<div>
  
  <h1 mat-dialog-title>Cancellazione dell'evento {{data.eventNameToDelete}}</h1>
  <div mat-dialog-content>
    <p>Ne sei sicuro?</p>
  </div>

  <button mat-button (click)="onNoClick()">No</button>
  <button mat-button cdkFocusInitial (click)="onYesClick()">
    Si, sono certo!
  </button>

</div>

CREAZIONE DEL FILE dialog-cancellazione-evento.ts

Ancora nella directory dettaglio-evento/ dobbiamo creare il file  con la logica di controllo della Dialog. Copiamoci  il seguente contenuto:

import { Component, EventEmitter, Output, OnInit } from "@angular/core";
import { Inject } from "@angular/core";
import {
  MatDialogRef,
  MAT_DIALOG_DATA
} from "@angular/material/dialog";

export interface DialogData {
  eventNameToDelete: string;
}

@Component({
  selector: "dialog-cancellazione-evento",
  templateUrl: "dialog-cancellazione-evento.html"
})
export class DialogCancellazioneEvento {
 
  constructor(
    public dialogRefMatDialogRef<DialogCancellazioneEvento>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData
  ) {}

  onNoClick(): void {
    this.dialogRef.close(false);
  }

  onYesClick(): void {
    this.dialogRef.close(true);
  }
 
}

MODIFICA DEL FILE dettaglio-evento-component.html

Creiamo un bottone nel nostro componente di dettaglio cui possiamo associare la grafica e l’invocazione di un metodo di cancellazione.

<div class="inner-single">
  <div class="container mat-elevation-z8">
    <div class="button-row">
      <a mat-flat-button color="primary" [routerLink]="['/']"
        ><mat-icon>list</mat-icon></a
      >
    </div>

    <mat-card class="example-card">
      <mat-card-header>
        <mat-card-title
          ><h2>{{ singoloEvento.name }}</h2></mat-card-title
        >
        <mat-card-subtitle
          >Inizio {{ singoloEvento.startdate }}</mat-card-subtitle
        >
        <mat-card-subtitle>Fine {{ singoloEvento.stopdate }}</mat-card-subtitle>
      </mat-card-header>

      <mat-card-content>
        <dl>
          <dt>Balli:</dt>
          <dd>{{ singoloEvento.styles }}</dd>
          <dt>Luogo:</dt>
          <dd>{{ singoloEvento.country }} / {{ singoloEvento.town }}</dd>
          <dt>Link:</dt>
          <dd>
            <a href="{{ singoloEvento.site2 }}" target="_blank">{{
              singoloEvento.site2
            }}</a>
          </dd>
        </dl>
      </mat-card-content>

      <mat-card-actions>
        <a mat-flat-button color="primary"><mat-icon>edit</mat-icon></a>
        <a mat-flat-button color="warn" (click)="openDialog()"
          ><mat-icon>delete</mat-icon></a
        >
      </mat-card-actions>
    </mat-card>
  </div>
</div>

MODIFICA DEL FILE dettaglio-evento-component.ts

Al bottone di cancellazione evento si è associato un metodo. Dobbiamo scriverne l’implementazione.

import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { ExternalDataService } from "../../services/external-data.service";
 
import { DialogCancellazioneEvento } from "./dialog-cancellazione-evento";

import {
  MatDialog,
  MatDialogRef,
  MAT_DIALOG_DATA
} from "@angular/material/dialog";
 

@Component({
  selector: "app-dettaglio-evento",
  templateUrl: "./dettaglio-evento.component.html",
  styleUrls: ["./dettaglio-evento.component.css"]
})
export class DettaglioEventoComponent implements OnInit {
  singoloEvento = null;

  constructor(
    private route: ActivatedRoute,
    private externalDataService: ExternalDataService,
    public dialog: MatDialog
  ) {}

  ngOnInit() {
    this.singoloEvento = this.externalDataService.getEvento(
      this.route.snapshot.params["id"]
    );
  }

  openDialog(): void {
    const dialogRef = this.dialog.open(DialogCancellazioneEvento, {
      data: { eventNameToDelete: "NOME EVENTO" }
    });
  }
 
}

Rilanciamo la nostra app con ng serve e verifichiamo che nella videata “dettaglio evento” se clicchiamo sul bottone rosso con l’icona del cestino si apra la Dialog.

Ora che abbiamo imparato gestire apertura e chiusura di una Dialog, vediamo come il Component dettaglio-evento può sfruttarla appieno e fare le seguenti operazioni:

  1. passaggio alla Dialog del nome dell’evento
  2. gestire il parametro di uscita dalla Dialog che riporta quale dei due bottoni è stato cliccato
  3. utilizzo di un metodo preposto del servizio ExternalData per cancellare dalla lista degli eventi quello desiderato
  4. ridirezione alla videata principale

MODIFICA DEL FILE dettaglio-evento.component.ts

import { Component, OnInit } from "@angular/core";

import { ActivatedRoute, Router } from "@angular/router";
import { ExternalDataService } from "../../services/external-data.service";
import { DialogCancellazioneEvento } from "./dialog-cancellazione-evento";

import {
  MatDialog,
  MatDialogRef,
  MAT_DIALOG_DATA
} from "@angular/material/dialog";

@Component({
  selector: "app-dettaglio-evento",
  templateUrl: "./dettaglio-evento.component.html",
  styleUrls: ["./dettaglio-evento.component.css"]
})
export class DettaglioEventoComponent implements OnInit {
  singoloEvento = null;

  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private externalDataService: ExternalDataService,
    public dialog: MatDialog
  ) {}

  ngOnInit() {
    this.singoloEvento = this.externalDataService.getEvento(
      this.route.snapshot.params["id"]
    );
  }

  openDialog(): void {
    const dialogRef = this.dialog.open(DialogCancellazioneEvento, {
      data: { eventNameToDelete: this.singoloEvento.name }
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result) {
        this.deleteEvent(this.singoloEvento.id);
      }
    });
  }

  deleteEvent(id) {
    this.externalDataService.deleteEvento(id);
    this.router.navigate(["/lista-eventi"]);
  }
 
}

MODIFICA DEL FILE external-data.service.ts

Ecco come il nostro servizio appronta provvisoriamente la cancellazione di un elemento dalla lista eventi.

import { Injectable } from "@angular/core";

const dati_Lista_Eventi = [
  {
    id: 13,
    name: "Swing Fastival",
    country: " United Kingdom",
    town: " Torquay, Devon ",
    site2: "http://www.swingfastival.co.uk",
    styles: " Balboa, Shag",
    startdate: "2019-11-08",
    stopdate: "2019-11-10"
  }, ... etc etc ...
];

@Injectable({
  providedIn: "root"
})
export class ExternalDataService {
  constructor() {}

  getEventi() {
    return dati_Lista_Eventi;
  }

  getEvento(id: number) {
    for (var i in dati_Lista_Eventi) {
      if (dati_Lista_Eventi[i].id == id) {
        return dati_Lista_Eventi[+i];
      }
    }
    return null;
  }

  deleteEvento(id: number) {
    var pos: number = -1;
    for (var i in dati_Lista_Eventi) {
      if (dati_Lista_Eventi[i].id === id) {
        pos = +i;
      }
    }
    if (pos !== -1) {
      dati_Lista_Eventi.splice(pos, 1);
    }
  }
  
}

Le modifiche inerenti la cancella zione di un evento swing dalla nostra lista sono terminate. Dalla pagina dei dettagli del singolo evento, cliccando sul bottone “cancella” si apre una Dialog che ci chiede la conferma dell’operazione. Se facciamo clic confermando la scelta, l’elemento viene cancellato e si torna alla videata principale.

No Comments

Sorry, the comment form is closed at this time.