What is the best way to recycle a single modal in Ionic?

Apologies for the vague title, but I'm facing an issue with creating a single modal to display data from multiple clickable elements, rather than having separate modals for each element. For example, when I click on item 1, its data should be shown in the modal, and then when I click on item 2, the same modal should dynamically display its data. I tried modifying the modal trigger ID to a class, but that didn't work. Can anyone provide guidance or suggestions on how to achieve this functionality?

Thank you in advance!

list-details.component.html

<ion-list>
     <ng-container *ngFor="let item of myList">
      <ion-item detail="true">
        <ion-button id="open-modal" expand="block" (click)="getItem(item)">
          <ion-label>
            <h2 class="headline">{{item.beer}}</h2>
            <h3 class="sub-headline">{{item.name}}</h3>
            <p>{{item.notes}}</p>
            <p>{{item.price | currency}}</p>
            <app-rating [rating]="item.rating"></app-rating>
          </ion-label>
        </ion-button>
      </ion-item>
      </ng-container>
    </ion-list>
    
    <ion-modal trigger="open-modal" (willDismiss)="onWillDismiss($event)">
      <ng-template>
        <ion-header>
          <ion-toolbar>
            <ion-buttons slot="start">
              <ion-button (click)="cancel()">Cancel</ion-button>
            </ion-buttons>
            <ion-title>{{user.name}}</ion-title>
            <ion-buttons slot="end">
              <ion-button (click)="confirm()" [strong]="true">Confirm</ion-button>
            </ion-buttons>
          </ion-toolbar>
        </ion-header>
        <ion-content class="ion-padding">
          <ion-item>
            <ion-label position="stacked">Enter your name</ion-label>
            <ion-input type="text" placeholder="Your name" [(ngModel)]="name"></ion-input>
          </ion-item>
        </ion-content>
      </ng-template>
    </ion-modal>

list-details.component.ts

    export class ListDetailsComponent implements OnInit {
  @ViewChild(IonModal) modal: IonModal;
  
  message = 'This modal example uses triggers to automatically open a modal when the button is clicked.';
  name: string;
  user: any;

  constructor() { }

  ngOnInit() {
  }

  

  getItem(item: any){
    this.user = item;
  }
  cancel() {
    this.modal.dismiss(null, 'cancel');
  }

  confirm() {
    this.modal.dismiss(this.name, 'confirm');
  }

  onWillDismiss(event: Event) {
    const ev = event as CustomEvent<OverlayEventDetail<string>>;
    if (ev.detail.role === 'confirm') {
      this.message = `Hello, ${ev.detail.data}!`;
    }
  }

}

Answer №1

The modalController in Ionic allows developers to programmatically present an ion-modal. This gives developers complete control over when a modal is presented and dismissed.

app.component.html

<ion-app>
  <ion-content>
    <hello name="{{ name }}"></hello>
    <p>Example of Dynamic Data with Ionic Modal</p>;

    <ng-container *ngFor="let data of listData">
      <ion-item href="#" (click)="openIonModal(data)">
        <ion-label>{{ data.name }}</ion-label>
      </ion-item>
    </ng-container>
  </ion-content>
</ion-app>

app.component.ts


import { Component, VERSION } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { CustomModalComponent } from '../custom-modal/custom-modal.component';

export interface ListData {
  id: number;
  name: string;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  name = 'Ionic 6.2 Angular ' + VERSION.major;

  listData: ListData[] = [
    {
      id: 1,
      name: 'Test 1',
    },
    {
      id: 2,
      name: 'Test 2',
    },
    {
      id: 3,
      name: 'Test 3',
    },
  ];

  modelData: any;

  constructor(private _modalController: ModalController) {}

  ionViewDidEnter() {}

  async openIonModal(data: ListData) {
    const modal = await this._modalController.create({
      component: CustomModalComponent,
      componentProps: {
        modelTitle: data.name,
      },
    });
    modal.onDidDismiss().then((modelData) => {
      if (modelData !== null) {
        this.modelData = modelData.data;
        console.log('Modal Data : ' + modelData.data);
      }
    });
    return await modal.present();
  }
}

custom-modal.component.ts


import { Component, Input, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';

@Component({
  selector: 'app-custom-modal',
  templateUrl: './custom-modal.component.html',
  styleUrls: ['./custom-modal.component.css'],
})
export class CustomModalComponent implements OnInit {
  @Input() modelTitle: string;

  constructor(private _modalController: ModalController) {}

  ngOnInit() {}

  async closeModel() {
    const close: string = 'Modal Removed';
    await this._modalController.dismiss(close);
  }
}

custom-modal.component.html

<ion-header>
  <ion-toolbar>
    <ion-title>Ionic Modal Popup Example</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
  <ion-grid>
    <ion-row>
      <ion-col text-center> Model Title : {{ modelTitle }} </ion-col>
    </ion-row>
    <ion-row>
      <ion-col text-center>
        <ion-button (click)="closeModel()">Close</ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

Access the working example here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Angular 2, how to filter a single column based on multiple values?

If I have an array of objects as shown below [ {name: 'aaa', type: 'A'}, {name: 'bbb', type: 'B'}, {name: 'ccc', type: 'A'} .... ] I want to build a filter in Angular that displays ...

Updating the date format of [(ngModel)] with the ngx-datepicker library

One of the challenges I'm facing is dealing with a web form that captures date of birth. To accomplish this, I'm utilizing the ngx-bootstrap version 2.0.2 datepicker module. The issue I encounter lies in the fact that my API only accepts date val ...

Angular 4 incorporates ES2017 features such as string.prototype.padStart to enhance functionality

I am currently working with Angular 4 and developing a string pipe to add zeros for padding. However, both Angular and VS Code are displaying errors stating that the prototype "padStart" does not exist. What steps can I take to enable this support in m ...

Safari (mac) experiencing issues with loading material icons properly on initial attempt

Upon my initial visit to the website, I noticed that the font appeared distorted. https://i.sstatic.net/BtUxI.png However, when I right-clicked and chose "reload page", the fonts were displayed correctly. https://i.sstatic.net/3XUcA.png This issue seem ...

Typescript: How can we determine the data type of React Router Link?

Trying to pass Link from react-router-dom as props and needing to specify it in the interface. While hovering over the Link element, the type displayed is: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>> ...

Is there a way for the parent class to access the child class in Angular 2?

Seeking guidance on accessing a child class from a parent class in my Angular 2 application with Typescript. The structure of the parent and child classes are as follows: The parent class, AllDataPageComponent: @Component({ selector: 'all-data-p ...

Tips for specifying the return type of app.mount()

Can I specify the return value type of app.mount()? I have a component and I want to create Multiple application instances. However, when I try to use the return value of mount() to update variables associated with the component, TypeScript shows an error ...

Trouble loading Styled Components in React Typescript with Webpack configuration

Hey there! I'm diving into the world of styled components for the first time, and I'm a bit lost on where I might have slipped up. I've got my webpack all sorted out and my .babelrc file in place. As I was going through the Styled Component ...

Building an Elegant Tab Menu with Ionic 2 Components

Just diving into the world of Ionic 2 and Angular 2. I'm attempting to include a tab menu component in some of my pages, but struggling. Here's the code for the menu.component.ts file: import { Component, OnInit } from '@angular/core' ...

Angular form field not connected to data source

Here is a form I'm working with: <form #appForm> <div...> <select id="transversal" name="transversal" [ngModel]="app.transversal" type="select" required #transversal="ngModel"> < ...

Automated Import Feature in Visual Studio Code

I'm currently transitioning from Webstorm to Visual Studio Code due to the poor performance of Webstorm. However, I'm facing issues with Visual Studio Code not being very efficient at detecting and importing the dependencies I need. I find mysel ...

Using Angular to transfer a function to a directive

Looking to pass the (scroll) method to a directive, I initially had it declared like this: <div class="table-responsive" pyb-fixed-table #container> After modifying it to include the method reference: <div class="table-responsive" (scroll)="onS ...

The plugin "proposal-numeric-separator" was not found. Please make sure that there is a corresponding entry for it in the ./available-plugins.js file

{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "myProjects", "projects": { "uniqueApp": { "projectType": "web-app", "schematics": {}, "root": "", "sourceRoot": "src", ...

Encountering an issue while trying to load a file from an API due to difficulties in parsing it to

When trying to load an xlsx file from an API, I encountered an error because Angular automatically tries to parse the body as JSON. To resolve this issue, I found that specifying the response type directly in the request works: this.http.get(this.url + " ...

The page has been updated following a refresh

I'm currently working on developing an Instagram-inspired platform using Angular 6, but I've run into a puzzling issue. When I refresh the page in my home component, everything reloads correctly and displays all my posts as expected. However, if ...

What are the tips for using ts-node in the presence of errors?

While developing, I have encountered some issues with ts-node. When I need to test something, commenting out code is my usual approach. However, when using ts-node, I keep getting this error message: 'foo' is declared but its value is never rea ...

Tips for Providing a Generic Type to a Component Imported Using Next.js Dynamic

There is no issue with this code snippet: import DatasheetContainer from '@/uikit/detailed-view/DatasheetContainer'; const DetailedView = () => { return ( <Page> <PageBody direction="row" bgColor="white&qu ...

Angular's error notification system seems to be lacking in providing accurate

I'm experiencing an issue with my angular app where errors are not displayed properly. Instead of showing errors in the component and line number, they always appear in main.js. This is different from how errors are displayed in my other angular appli ...

Automated tasks running on Firebase Cloud Functions with cron scheduling

There are two cloud functions in use: The first cloud function is used to set or update an existing scheduled job The second one is for canceling an existing scheduled job The management of scheduling jobs is done using import * as schedule from &ap ...

Angular - Error: Cannot find module 'fs'

I've encountered an issue while trying to incorporate Node's fs module into my Angular application. It seems that the problem lies in the fact that Angular doesn't operate within a node environment. I'm wondering if there's a way ...