What steps are involved in building a modal pop-up in Angular without using any pre-existing libraries

I am looking to create a modal popup when a button is clicked. I want to achieve this without relying on any additional dependencies. The method I have used below successfully creates a fully functional modal, but I am unsure if this is the best way to do it in Angular. Any suggestions would be appreciated.

HTML

<button class="hl-sort" (click)="openSortingModal()">
Sort
</button>
<div class="modal-container" *ngIf="modalContent">
  <h1>i am modal content</h1>
  <button (click)="closeModal()">Close</button>
</div>

components.ts

modalContent = false;
openSortingModal(){
  this.modalContent = true;
  console.log('clicked')
}
closeModal(){
 this.modalContent = false;
}

Answer №1

If you prefer not to introduce additional dependencies, my recommendation is to develop a reusable component with HTML and CSS:

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-modal',
  template: `
    <div #myModal class="container">
    <div class="content">
      <p>Some content here...</p>
      <button (click)="close()">Close</button>
    </div>
    </div>
  `,
  styleUrls: ['./modal.component.css']
})
export class ModalComponent {

  @ViewChild('myModal', {static: false}) modal: ElementRef;

  open() {
    this.modal.nativeElement.style.display = 'block';
  }

  close() {
    this.modal.nativeElement.style.display = 'none';
  }
}

You can then use this component within your container:

import { Component, ViewChild } from '@angular/core';
import { ModalComponent } from './modal/modal.component';

@Component({
  selector: 'my-app',
  template: `
    <app-modal #modal></app-modal>
    <p>
    Open a Pure HTML + CSS with Angular
    </p>
    <button (click)="openModal()">Open Modal</button>
  `,
  styleUrls: []
})
export class AppComponent  {

  @ViewChild('modal', {static: false}) modal: ModalComponent

  openModal() {
    this.modal.open();
  }
}

Check out a live example here: https://stackblitz.com/edit/angular-modal-html-css

I hope this solution works for you!

Answer №2

Save yourself the trouble of reinventing the wheel by taking advantage of this

Answer №3

If you're looking to come up with a new approach, remember to close the modal when clicking outside of it.

Building on Luixaviles's solution, the modal component could look something like this:

<div #myModal class="container" (click)="tryClose()">
  <div #content class="content">
    <ng-content></ng-content>
  </div>
</div>

In this setup, the "tryClose" function is triggered when you click on the "myModal" div, checking if the click was not within the "content" section.

  tryClose() {
    const clickTarget = event.target as HTMLElement;
    if (!(this.content.nativeElement as HTMLElement).contains(clickTarget))
      this.close();
  }

By using <ng-content>, you can manage the content in the app.component like so:

<app-modal #modal>
    <p>Some content here...</p>
    <button (click)="modal.close()">Close</button>
</app-modal>
<p>
   Open a Modal Using Pure HTML + CSS with Angular
</p>
<button (click)="modal.open()">Open Modal</button>

The functionality in the modal component itself is straightforward:

export class ModalComponent {
  @ViewChild("myModal", { static: false }) modal: ElementRef;
  @ViewChild("content", { static: false }) content: ElementRef;

  open() {
    this.modal.nativeElement.style.display = "block";
  }

  close() {
    this.modal.nativeElement.style.display = "none";
  }
}

Take a look at Luixaviles's modified version on StackBlitz

Update: Adding a simple stopPropagation makes the process smoother.

   <div #myModal class="container" (click)="close()">
      <div (click)="$event.stopPropagation()" class="content">
        <ng-content></ng-content>
      </div>
    </div>

Answer №4

Developing your own component instead of relying on a third-party option is highly recommended. It's essential to ensure that your popup can be reused and tailored to specific needs.

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

Input field modified upon focus

I am currently using selectize js in my section to create a select box. My goal is to make the input editable after selecting an option when it is focused on. Check out the live demo: live demo HTML <label>Single selection <select id=" ...

"Troubleshooting: Difficulty with hover function in jqgrid not functioning on colored rows

My JQGrid setup includes the following: <table id="grid"></table> var data = [[48803, "DSK1", "", "02200220", "OPEN"], [48769, "APPR", "", "77733337", "ENTERED"]]; $("#grid").jqGrid({ datatype: "local", height: 250, colNa ...

In Chrome, the computed style of background-position is returned as 0% 0%

Let's say I have an element and I am interested in finding out its background-position: To achieve this, I use the following code snippet: window.getComputedStyle(element).getPropertyValue('background-position') If the value of background ...

Enhancing PHP Markdown to Support Custom CSS Classes

Markdown is a tool I use frequently in my PHP projects, but sometimes I find its output to be too simplistic. I wish I had more control over the layout and design of my content. For example, when inserting an image: <p> <img src="path/to/image. ...

Received an error stating, "0 arguments were provided when expecting 1-3" while attempting to run the ng build --prod command

I'm currently developing a navigation panel that displays hierarchy and child items when parent items are clicked: <div *ngFor="let t of temp(math.ceil(rr2.children.length/3)).fill(); let ei = index"> <!-- <div *ng ...

Whenever I attempt to bring in AngularFireModule, an error promptly appears

I am experiencing some errors when trying to import AngularFireModule and initialize the app with environment.firebaseConfig. I have tried to solve the problem but without success. Can anyone provide guidance on what steps I should take? @NgModule({ decl ...

The scrolling content is positioned beneath the primary header and navigation bar

I'm currently in the process of designing a website where, upon clicking a navigation button, part of the page scrolls while the top header & nav bar remain fixed. Although I've managed to get the scrolling functionality to work and keep the top ...

What is the best approach to repurpose a component when small adjustments are needed?

Can a customized slider component be created in React that can be reused with slight variations? For example, having the second one include a 13% field. View image description here ...

Is there a method to measure the time it takes to download a script apart from its actual execution time

I am looking to track timing variables for my primary JavaScript load. One approach could be: <script> performance.mark('script-start') </script> <script src="something.js"></script> Later in something.js, inc ...

CSS properties are ineffective in scaling the image strip

I have a large image strip measuring 130560 x 1080. My goal is to load it into an image tag and use the parent div as a viewport, showing only one section of the image at a time. However, I'm encountering a problem when specifying the height and widt ...

extracting characters in php

Here's the HTML code I'm working with: <p style="color:red;font-size:12px;">This budget-friendly car offers great value, complete with air conditioning making it perfect for couples and small families. There is a ?500 excess, but it can be ...

What is the best way to position the bottom block?

I'm trying to create a template that looks like the image below: https://i.sstatic.net/m6q0s.png I managed to position the top square correctly, but I'm having trouble aligning the bottom one - I can't seem to move it to the bottom left co ...

Reacting to multiple checkboxes in a check handling system

In my latest project, I have designed a component that utilizes multiple checkboxes generated within a .map function. While testing the functionality, it came to my attention that users could select more than one checkbox at a time. This is not ideal as th ...

Adjusting Picture Sizes to Fit the Dimensions of a Photo Frame

Currently, I am in the process of developing a website that incorporates two distinct image types: Portrait photos https://i.sstatic.net/rmIXQ.jpg Landscape photos https://i.sstatic.net/Z7mr3.jpg As you can see, there are two different categories of ...

Design all buttons, except for the two specific buttons

.button , button{ border:solid black 2px !important; } Using this code, I have added a border to all buttons. But now, I need to exclude the buttons "searchsubmit" and "single_add_to_cart_button" from having a border. How can I achieve that? ...

Navigating to the Login page in Angular 13

<app-navbar></app-navbar> <div class = "app-body"> <div class="app-sidebar"> <app-sidebar></app-sidebar> </div> <div class="app-feed"> <router-outlet name="main& ...

Enhance your social interactions by incorporating a custom interaction field using Google Analytics

At times, I have two share buttons in the user interface of my application (depending on the state). These buttons can share the same data but are located in different parts of the UI. The goal is to analyze from which button (part of UI) the share action ...

Angular4's integration with AngularFireAuth for Google authentication is causing users to be redirected back to the source page before they can successfully

Previously, this feature was functioning perfectly. However, the current issue is that the browser is redirecting to a long URL and then quickly returning to the original source URL. This prevents users from logging into their Google accounts. authentica ...

Steps for including a path to a base64 encoded image

I am currently facing a challenge in embedding images into my emails where I need to encode them using an online tool. The issue I am encountering is that the email template I am using has a dynamic URL, with ${loginurl}/images as the path to my image. H ...

Styling in Next.js with conditions

I am attempting to create a scenario where a link becomes active if the pathname matches its href value. function Component() { const pathname = usePathname(); return ( <div className="links"> <Link href="/"> ...