How to use code to open a modal in Angular 2?
Solution 1
This is one way I found. You can add a hidden button:
<button id="openModalButton" [hidden]="true" data-toggle="modal" data-target="#myModal">Open Modal</button>
Then use the code to "click" the button to open the modal:
document.getElementById("openModalButton").click();
This way can keep the bootstrap style of the modal and the fade in animation.
Solution 2
Include jQuery as usual inside script tags in index.html.
After all the imports but before declaring @Component, add:
declare var $: any;
Now you are free to use jQuery anywhere in your Angular 2 TypeScript code:
$("#myModal").modal('show');
Reference: https://stackoverflow.com/a/38246116/2473022
Solution 3
Easy way to achieve this in angular 2 or 4 (Assuming that you are using bootstrap 4)
Component.html
<button type="button" (click)="openModel()">Open Modal</button>
<div #myModel class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title ">Title</h5>
<button type="button" class="close" (click)="closeModel()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
</div>
</div>
</div>
Component.ts
import {Component, OnInit, ViewChild} from '@angular/core';
@ViewChild('myModal') myModal;
openModel() {
this.myModal.nativeElement.className = 'modal fade show';
}
closeModel() {
this.myModal.nativeElement.className = 'modal hide';
}
Solution 4
The below answer is in reference to the latest ng-bootstrap
Install
npm install --save @ng-bootstrap/ng-bootstrap
app.module.ts
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
@NgModule({
declarations: [
...
],
imports: [
...
NgbModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Component Controller
import { TemplateRef, ViewChild } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-app-registration',
templateUrl: './app-registration.component.html',
styleUrls: ['./app-registration.component.css']
})
export class AppRegistrationComponent implements OnInit {
@ViewChild('editModal') editModal : TemplateRef<any>; // Note: TemplateRef
constructor(private modalService: NgbModal) { }
openModal(){
this.modalService.open(this.editModal);
}
}
Component HTML
<ng-template #editModal let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Edit Form</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="dateOfBirth">Date of birth</label>
<div class="input-group">
<input id="dateOfBirth" class="form-control" placeholder="yyyy-mm-dd" name="dp" ngbDatepicker #dp="ngbDatepicker">
<div class="input-group-append">
<button class="btn btn-outline-secondary calendar" (click)="dp.toggle()" type="button"></button>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="modal.close()">Save</button>
</div>
</ng-template>
Solution 5
Best way I have found. Put #lgModal
or some other variable name in your modal.
In your view:
<div bsModal #lgModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" (click)="lgModal.hide()" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Large modal</h4>
</div>
<div class="modal-body">
...
</div>
</div>
</div>
</div>
In your component
import {Component, ViewChild, AfterViewInit} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';
// todo: change to ng2-bootstrap
import {MODAL_DIRECTIVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap';
import {ModalDirective} from 'ng2-bootstrap/ng2-bootstrap';
@Component({
selector: 'modal-demo',
directives: [MODAL_DIRECTIVES, CORE_DIRECTIVES],
viewProviders:[BS_VIEW_PROVIDERS],
templateUrl: '/app/components/modals/modalDemo.component.html'
})
export class ModalDemoComponent implements AfterViewInit{
@ViewChild('childModal') public childModal: ModalDirective;
@ViewChild('lgModal') public lgModal: ModalDirective;
public showChildModal():void {
this.childModal.show();
}
public hideChildModal():void {
this.childModal.hide();
}
ngAfterViewInit() {
this.lgModal.show();
}
}
Comments
-
Hongbo Miao almost 2 years
Usually we use
data-target="#myModal"
in the<button>
to open a modal. Right now I need use codes to control when to open the modal.If I use
[hidden]
or*ngIf
to show it, I need removeclass="modal fade"
, otherwise, the modal will never show. Like this:<div [hidden]="hideModal" id="myModal">
However, in this case, after removing
class="modal fade"
, the modal won't fade in and has no shade in the background. And what's worse, it will show at the screen bottom instead of screen center.Is there a way to keep
class="modal fade"
and use code to open it?<button type="button" data-toggle="modal" data-target="#myModal">Open Modal</button> <div id="myModal" class="modal fade"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-body"> <p>Some text in the modal.</p> </div> </div> </div> </div>
-
Judson Terrell almost 8 yearsThis does not work at compile time and not with typescript. Its sort of hackish
-
yonexbat almost 7 yearsI do it this way. Bootstrap 3 depends somewhat on jquery.
-
gogognome over 6 yearsThe link
http://valor-software.com/ng2-bootstrap/#/modals
results in a 404 today... -
Hongbo Miao over 6 years@gogognome thanks, I just removed that link, because nowadays there are many packages available if the person choose to use a package.
-
MaxAxeHax over 6 yearsCould you please specify where in your solution you assumed usage of Bootstrap 4 instead of 3? I am using version 3 and this worked for me anyway, so I think I missed some detail and would like to learn more :)
-
Umang Patwa about 6 years@MaxAxeHax I use word "Assuming using bootstarp 4", Just in case previous or upcoming version of bootstrap class for hide and show is change then you just need to replace that class in openModel and closeModel function.
-
Manu Chadha almost 6 yearscould you please take a look at this stackblitz.com/edit/angular-xesgxe I want to show a modal when
input
is clicked. But the compiler can't findthis.el.modal
orthis.el.nativeElement.modal()
-
Manu Chadha almost 6 yearsgot it working using
$().modal
. It is in one of the answers below -
Kamil Kiełczewski almost 6 yearsIn method
ngAfterViewInit
and methodsopen/close
I in fact use it. However in this answer goal was to provide working "modal" component (with example usage) - however it was 2 years ago so may be now it is outdated. -
Manu Chadha almost 6 yearsYes, I see it now. I am concerned about mixing jquery and angular code but this one is the only one I could get working. If you happen to find a soln. which is more Angular, please do update. So would I.
-
Manu Chadha almost 6 yearsCould you please help me understand why this line is important
declare var $: any;
. I expected that because I have already includedjquery
in my project, I should be able to use$
anywhere. Also, your comment thatbecouse this override jQuery which was changed by bootstrap
. Does Bootstrap's come with its own implementation ofJQuery
? -
Manu Chadha almost 6 yearsI suppose I found the answer. By doing
declare var $:any
, we declare a variable that exists somewhere in the JS - found it from some other question in SO -
Kamil Kiełczewski almost 6 years@ManuChadha I ask more general similar question: stackoverflow.com/questions/50516233/…
-
Tomasz O. over 5 yearsDoesn't work for me. Neither the snippet nor code based on it.
-
deanwilliammills over 5 yearsThe best answer without installing a third party package. jQuery should be installed when using Bootstrap, so might as well use it in the controller and this way is also in the Bootstrap docs. Thanks
-
Nabin Kumar Khatiwada about 5 yearsThank you alot. Coolest solution. I don't use 3rd party bootstrap in angular. I just copy links from official site. I don't like too much of code jungle and i open popup only after data is loaded from backend.This is exactly what i was looking for.
-
Aspiring Dev over 4 yearsWorked for me. Thanks!
-
Hamid Hoseini about 4 yearsVery nice! I didn't note
TemplateRef<any>; // Note: TemplateRef
but it was important. Thanks, Arjun -
Torsten Barthel over 3 yearsNice solution! Even if not the Angular way :)
-
Fatih Doğan almost 3 yearsDoesn't work. Neither the snippet nor code based on i