Hôm nay, mình sẽ hướng dẫn các bạn cách tạo popup modal mà không sử dụng Bootstrap hay bất kỳ npm dependency nào. Các bước thực hiện rất đơn giản, các bạn có thể dễ dàng kế thừa và túy biến theo ý của bạn.
src/app/_component/modal.component.ts:
Và tiếp theo, ta cần triển khai modal service, ta tạo file service với code sau:
Lưu ý: Như các bạn thấy, mình đã sử dụng thư mục _component cho component, thư mục _services để chứa các file service, bạn có thể chọn theo lựa chọn của bạn cho đường dẫn hoặc tên thư mục nhưng hãy đảm bảo đúng các đường dẫn import trong các file code.
Bây giờ, ta sẽ sử dụng thành quả modal vừa tạo, cụ thể ta tạo một about page với button dùng để mở modal, cụ thể với code sau đây:
Bây giờ, ta cần tạo các phương thức và các nút để mở nó. Bạn cần đảm bảo rằng hàm có tham số này sẽ được ánh xạ để modal nào bật lên sẽ được mở. Tại đây, bạn có thể thấy nút modal1 sẽ được nhấp với phương thức modal1. Tương tự như vậy, bạn có thể tạo nhiều nút và nhiều chế độ hơn theo bất kỳ tên nào hoặc như modal2, modal3.
Cuối cùng, ta cần config bên trong file app.module.ts như sau:
Và đó cũng là bước cuối cùng trong bài hướng dẫn của chúng ta.
Khi triển khai web app, các bạn chắc hẳn sẽ cần dùng đến Modal trong Bootstrap, nó được sử dụng để hiển thị một dialog (hộp thoại) hay popup (cửa sổ hiện lên) trên website. Nhưng trong vài trường hợp, bạn không muốn phụ thuộc vào Bootstrap mà muốn tự chủ toàn bộ, và đây là giải pháp chắc hẳn sẽ có ích với bạn.
Hướng dẫn tạo Modal trong Angular
Đầu tiên, ta sẽ triển khai modal component:
src/app/_component/modal.component.html:
<div class="modal-popup">
<div class="modal-popup-body">
<ng-content></ng-content>
</div>
</div>
<div class="modal-popup-background"></div>
import { Component, ElementRef, Input, OnInit, OnDestroy } from '@angular/core';
import { ModalService } from '../_services/modal.service';
@Component({
selector: 'modal-popup',
templateUrl: './modal.component.html'
})
export class ModalComponent implements OnInit, OnDestroy {
@Input() id: string;
private element: any;
constructor(private modalService: ModalService, private el: ElementRef) {
this.element = el.nativeElement;
}
ngOnInit(): void {
let modal = this;
// ensure id attribute exists
if (!this.id) {
console.error('modal must have an id');
return;
}
// move element to bottom of page (just before </body>) so it can be displayed above everything else
document.body.appendChild(this.element);
// close modal on background click
this.element.addEventListener('click', function (e: any) {
if (e.target.className === 'modal-popup') {
modal.close();
}
});
// add self (this modal instance) to the modal service so it's accessible from controllers
this.modalService.add(this);
}
// remove self from modal service when directive is destroyed
ngOnDestroy(): void {
this.modalService.remove(this.id);
this.element.remove();
}
// open modal
open(): void {
this.element.style.display = 'block';
document.body.classList.add('modal-popup-open');
console.log('modal open called');
}
// close modal
close(): void {
this.element.style.display = 'none';
document.body.classList.remove('modal-popup-open');
console.log('modal close called');
}
}
src/app/_services/modal.service.ts:
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class ModalService {
private modals: any[] = [];
add(modal: any) {
// add modal to array of active modals
this.modals.push(modal);
}
remove(id: string) {
// remove modal from array of active modals
this.modals = this.modals.filter(x => x.id !== id);
}
open(id: string) {
// open modal specified by id
let modal: any = this.modals.filter(x => x.id === id)[0];
modal.open();
}
close(id: string) {
// close modal specified by id
let modal: any = this.modals.filter(x => x.id === id)[0];
modal.close();
}
}
Khi có đã có component và service, ta cần tiến hành thêm style cho nó, như bạn được biết, khi một modal được mở lên, các thành phần khác hoàn toàn nằm bên dưới và được bao trùm lên một background tối màu. Cụ thể ta có code sau bên trong file style.scss:
modal-popup {
display: none;
.modal-popup {
/* modal container fixed across whole screen */
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
max-width:400px;
min-width:300px;
width:50%;
margin:auto;
min-height:300px;
/* z-index must be higher than .modal-popup-background */
z-index: 1000;
/* enables scrolling for tall modals */
overflow: auto;
.modal-popup-body {
padding: 20px;
background: #fff;
/* margin exposes part of the modal background */
margin: 40px;
}
}
.modal-popup-background {
/* modal background fixed across whole screen */
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* semi-transparent black */
background-color: #000;
opacity: 0.75;
z-index: 900;
}
}
body.modal-popup-open {
/* body overflow is hidden to hide main scrollbar when modal window is open */
overflow: hidden;
}
src/app/about/about.component.html:
<p>about works!</p>
<div>
<button (click)="openModal('modal1')">Open Modal 1</button>
</div>
<modal-popup id="modal1">
<h1>A Custom Modal!</h1>
<p>This is dummy text</p>
<button (click)="closeModal('modal1');">Close</button>
</modal-popup>
src/app/about/about.component.ts:
import { Component, OnInit } from '@angular/core';
import { ModalService } from '../_services/modal.service';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {
constructor(private modalService: ModalService) {
}
ngOnInit() {
}
openModal(id: string) {
this.modalService.open(id);
}
closeModal(id: string) {
this.modalService.close(id);
}
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { ModalComponent } from './_components/modal.component';
@NgModule({
declarations: [
AppComponent,
AboutComponent,
ModalComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Lời kết
Như mục tiêu đề ra, ta hoàn toàn không sử dụng Bootstrap, và như thế bạn có thể dễ dàng customize theo ý bạn, với các bước thực hiện rất đơn giản và nhanh chóng.
Mong bài viết hữu ích đến các bạn.
Hieu Ho.
Tags:
Angular
Quá hữu ích
Trả lờiXóaoke anh zai
Xóa