Aller au contenu principal

19-1 Modal Bootstrap avec ng-bootstrap

Il serait bien de pouvoir utiliser une fenêtre modale Bootstrap plutôt que la fenêtre de confirmation du navigateur.

Pour utiliser les composants JS de Bootstrap en Angular, il existe une librairie appelée ng-bootstrap qui expose des composants pour la majeure partie des composants dynamiques de Bootstrap.

Vous avez déjà installé cette librairie dans le niveau sur Bootstrap! Si ce n'est pas le cas, retournez au niveau en question pour la procédure d'installation.

Créer un composant pour la fenêtre modale de confirmation

Nous utiliserons un composant pour la fenêtre modale. Elle pourra être réutilisée pour d'autres confirmations de suppression, sans avoir à dupliquer la logique et le HTML.

ng generate component shared/components/confirmation-modal
info

Comme ce composant est possiblement utilisé par l'entièreté de l'application, on le met dans le dossier shared

La fenêtre modale utilisera le gabarit par défaut de Bootstrap pour les modal et aura deux boutons, en plus d'accepter en entrée (Input) le message à afficher.

src/app/shared/components/confirmation-modal.ts
@Component({
selector: 'app-confirmation-modal',
imports: [],
template: `
<div class="modal-header">
<h4 class="modal-title">Confirmation</h4>
<button type="button" class="btn-close" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>{{messageConfirmation}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Confirmer</button>
<button type="button" class="btn btn-secondary">Annuler</button>
</div>
`,
styles: ``
})
export class ConfirmationModal {
@Input() messageConfirmation: string = "";
}
info

@Input() messageConfirmation: string est utilisé pour recevoir en entrée un message à afficher. Ce message est affiché dans le composant via {{messageConfirmation}}.

Ouvrir la fenêtre modale

On remplacera la confirmation navigateur (confirm) par la fenêtre modale Bootstrap. Pour ouvrir la fenêtre modale, il faut cependant utiliser le service NgbModal. C'est sur cet objet que nous aurons entre autres une fonction open() permettant d'ouvrir la fenêtre.

  1. Injecter NgbModal dans ProjetsListe

    src/app/features/projets/components/projets-liste.ts
    //...

    export class ProjetsListe {
    @Input() projets: Projet[] | null = null
    @Output() projetDeleted = new EventEmitter<number>

    constructor(private modalService: NgbModal) {}

    //...
  2. Ouvrir ConfirmationModalComponent. Pour ouvrir le modal, on utilise la fonction open() sur modalService (l'instance de NgbModal). Vous pouvez remplacer la liste de confirmation existante.

    src/app/features/projets/components/projets-liste.ts
    protected supprimerProjet(projetId: number) {
    const modal = this.modalService.open(ConfirmationModal)

    /*if(confirmation){
    this.projetDeleted.emit(projetId)
    }*/
    }
    attention

    Remarquez que les lignes pour lancer l'événement ont été mises en commentaire en attendant d'avoir un modal 100% fonctionnel.

    Maintenant, si vous appuyez sur le boutton Supprimer, la fenêtre devrait apparaitre!

    Imgur

    attention

    Nous n'avons pas implémenté les fonctions permettant de fermer la fenêtre. Vous devrez rafraichir la page pour réinitialiser le tout!

Implémenter les contrôles de fermeture

Pour fermer la fenêtre modale, c'est le composant ConfirmationModal qui est responsable de cette tâche.

Pour ce faire, on doit avoir une référence à la fenêtre active et cette référence est obtenue via le service NgbActiveModal.

On injectera ainsi le service dans ConfirmationModal via son constructeur.

  1. Injecter NgbActiveModal
    src/app/shared/components/confirmation-modal.ts
    export class ConfirmationModal {
    @Input() messageConfirmation: string = "";

    constructor(public activeModal: NgbActiveModal) {}
    }
  2. Implémenter les événements (click) sur les boutons de confirmation et fermeture
    src/app/components/confirmation-modal.component.ts
    @Component({
    selector: 'app-confirmation-modal',
    imports: [],
    template: `
    <div class="modal-header">
    <h4 class="modal-title">Confirmation</h4>
    <button type="button" class="btn-close" aria-label="Close" (click)="activeModal.dismiss(false)"></button>
    </div>
    <div class="modal-body">
    <p>{{messageConfirmation}}</p>
    </div>
    <div class="modal-footer">
    <button type="button" class="btn btn-primary" (click)="activeModal.close(true)">Confirmer</button>
    <button type="button" class="btn btn-secondary" (click)="activeModal.close(false)">Annuler</button>
    </div>
    `,
    styles: ``
    })
info
  • activeModal est la référence au service NgbActiveModal et réfère au modal actif
  • activeModal.close ferme la fenêtre
  • activeModal.close(true) ou activeModal.close(false) précise le retour qui sera envoyé lors de la fermeture de la fenêtre. Vous pouvez passer n'importe quelle valeur, de n'importe quel type. Ici, on utilise true ou false pour signifier si l'utilisateur a choisi de confirmer (true) ou d'annuler (false).

Vous pouvez réessayer dans le navigateur et devriez maintenant pouvoir fermer la fenêtre! 🎉

http://localhost:4200

Passer à la fenêtre le message à afficher

Lorsqu'on ouvre le modal, on peut passer à la fenêtre des valeurs, dont messageConfirmation de cette façon:

src/app/features/projets/components/projets-liste.ts
  protected supprimerProjet(projetId: number) {
const modal = this.modalService.open(ConfirmationModal)
modal.componentInstance.messageConfirmation = "Êtes-vous certain de vouloir supprimer ce projet?";

/*if(confirmation){
this.projetDeleted.emit(projetId)
}*/
}
info
  • modal.componentInstance donne accès à l'instance de la composante (ConfirmationModal)
  • messageConfirmation est le message à afficher, soit la propriété définie dans le composant de modal.
http://localhost:4200

Lire le retour de la fenêtre

On peut attendre le retour via await sur la fonction modal.result qui retourne une Promise contenant la valeur retournée par le modal (true ou false).

src/app/features/projets/components/projets-liste.ts
protected async supprimerProjet(projetId: number) {
const modal = this.modalService.open(ConfirmationModal)
modal.componentInstance.messageConfirmation = "Êtes-vous certain de vouloir supprimer ce projet?";
const result = await modal.result;

/*if(confirmation){
this.projetDeleted.emit(projetId)
}*/
}

Supprimer sur confirmation

On peut finalement supprimer si la confirmation est positive, c'est-à-dire que result est à true.

src/app/features/projets/components/projets-liste.ts
  protected async supprimerProjet(projetId: number) {
const modal = this.modalService.open(ConfirmationModal)
modal.componentInstance.messageConfirmation = "Êtes-vous certain de vouloir supprimer ce projet?";
const result = await modal.result;

if(result){
this.projetDeleted.emit(projetId)
}
}
http://localhost:4200

party

Level Up