I have an Angular 8 project that is using bootstrap. I am trying to show the modal dialog inside my component using the $('myModal').modal('show') inside my component's Typescript file.
Here's my component's file:
import {Component, OnInit} from '#angular/core';
import {Router} from '#angular/router';
// import * as $ from 'jquery';
import * as bootstrap from 'bootstrap';
#Component({
selector: 'app-xyz',
templateUrl: './xyz.component.html',
styleUrls: ['./xyz.css']
})
export class XyzComponent implements OnInit {
constructor(private router: Router) {
}
ngOnInit() {
}
submit() {
$('#confirm').modal('show');
}
}
Upon invoking the submit() funciton on click I get the following error: ERROR TypeError: $(...).modal is not a function
I installed bootstrap and jquery using npm install bootstrap --save and npm install jquery --save.
I even installed ngx-bootstrap.
However, when I uncomment the line importing jQuery I get a different error: ERROR TypeError: jquery__WEBPACK_IMPORTED_MODULE_3__(...).modal is not a function
Check your angular.json file to make sure that the Jquery js file is included in your scripts array.
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
]
Then in your component TS file declare var $ instead of trying to import it:
declare var $: any;
That should allow you to trigger the modal via
$('#confirm').modal();
Also make sure that the HTML is correct. Example Modal:
<div class="modal fade" id="confirm" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="noDataModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header" style="background-color:lightgrey">
<h5 class="modal-title" id="noDataModalLongTitle">No Data</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<i class="fas fa-check fa-4x mb-3 animated rotateIn"></i>
No Data Found. Please expand your search criteria and try again.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Ok</button>
</div>
</div>
</div>
</div>
Hope this helps!
Related
being a newbie to the angular 6 I am having a issue in passing data from one component to another component.
Actually i am opening child component bootstrap modal from parent modal and want to pass string parameter to child modal component and also want to call function as soon as modal opens and functions returns a array which is shown in table only.
Parent Component HTML
<div class="parent-comp">
<div id="ext-modal" class="modal fade" role="dialog">
<!-- Modal content Starts-->
<app-f-ext [Id]="Id"></app-f-ext>
<!-- Modal content Ends-->
</div>
</div>
Child component TS
import { Component, Input } from '#angular/core';
#Component({
selector: 'app-premium-extension',
templateUrl: './premium-extension.component.html',
styleUrls: ['./premium-extension.component.css']
})
export class ExtensionComponent implements OnInit {
#Input() Id: string;
constructor() {
}
ngOnInit() {
}
callThisFunctionOnOpeningModal(){
console.log(Id)
}
}
Child component HTML
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Ext {{Id}}</h4>
</div>
<div class="modal-body">
</div>
</div>
</div>
Parent Component TS
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'ap-detail',
templateUrl: './p-details.component.html',
styleUrls: ['./p-details.component.css']
})
export class PDetailsComponent implements OnInit {
Id: string;
constructor(){
this.Id = "test";
}
}
When i open the modal it shows in the modal header but how to on call function on modal loads and passing the Id in that function.
Please don't down mark the question as i am in really big issue with this. Thanks in advance for the help.
You have to use the right selector to call your child component. So replace:
<!-- Modal content Starts-->
<app-f-ext [Id]="Id"></app-f-ext>
<!-- Modal content Ends-->
By:
<!-- Modal content Starts-->
<app-premium-extension [Id]="Id"></app-premium-extension>
<!-- Modal content Ends-->
And make sure to declare and initialize the Id var in your parent.component.ts file
You can then have access to the Id property in the ngOnInit function:
ngOnInit() {
console.log(Id);
}
Similar questions have been asked before but I can't seem to apply their solution to this specific use case.
I'm trying to increase the width of my modal window, the most common solutions are to encase the content in a <div class="modal-dialog"></div> However, when I try this solution the modal becomes completely unresponsive, the formatting gets strange and the buttons stop working.
I used this ng-bootstrap guide for making the component and my desired end-result is a 90% width modal window in which I can place other components based on situation.
Here is the containing component code:
<p>You can pass an existing component as content of the modal window. In this case remember to add content component
as an <code>entryComponents</code> section of your <code>NgModule</code>.</p>
<button class="btn btn-lg btn-outline-primary" (click)="openModal()">Launch demo modal</button>
Here is the containing component.ts:
import { Component, OnInit } from '#angular/core';
import {NgbModal, NgbActiveModal} from '#ng-bootstrap/ng-bootstrap';
import {ModalInvoicePopupComponent} from '../modal-invoice-popup/modal-invoice-popup.component';
#Component({
selector: 'app-about-us',
templateUrl: './about-us.component.html',
styleUrls: ['./about-us.component.css']
})
export class AboutUsComponent implements OnInit {
constructor(private modalService: NgbModal) {}
openModal() {
const modalRef = this.modalService.open(ModalInvoicePopupComponent);
}
ngOnInit() {
}
}
Here is the modal-component html:
<div class="modal-header">
<h4 class="modal-title">myModal title</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>myModal body</p>
<p>Size differences when a large string is inserted, test of scaling</p>
<p>Importing an existing app into the modal, what happens then?</p>
<app-invoices></app-invoices>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
If I try to encase the modal-component inside a modal-dialog div it just breaks, and starts looking like this:
And becomes completely unresponsive.
Is there a good way to increase the size of a modal popup when used as a component in Angular?
Change your function like below :
openModal() {
const modalRef = this.modalService.open(ModalInvoicePopupComponent, {
width: '78vw'
});
}
It will give the width of modal 78vw and you can change it according to your mobile devices.
You have used NgbModal, in that case for defining the size of modal you can go for NgbModalOptions.
There you can define the size of the modal while opening it, say
this.modalService.open(content,{
size: 'xl'
});
refer https://ng-bootstrap.github.io/#/components/modal/api for detailed information.
I am trying to create a cancel function that cancels a specific viewing based on its id. I have a viewings model that I retrieve from firebase as an observable, I then input it into a child div. The problem being that when I click cancel, it always cancels the first viewing on the page, not the specific one that I click.
The strange thing is, that I created a new component on the same level as my modal component, Input the data in the exact same way, and that works perfectly. It only seems to be with the modal that It does not work.
<div class="col-md-3 buttons" [hidden]='!hidden' [#sliderDiv]="out">
<button class="button button-primary button-sm button-green text-center" (click)="updateViewingStatus()">Update Time</button>
<button data-toggle="modal" data-target="#cancelModal" class="button button-primary button-sm button-previous text-center">Cancel Viewing</button>
</div >
<viewings-cancel-modal [viewings]="viewings"></viewings-cancel-modal>
<testing-cancel [viewings]="viewings"></testing-cancel>
</div>
this is where I input viewings property into the child components. Both identical.
this is my test logic (using just a button) that works perfectly:
export class TestingCancelComponent implements OnInit {
#Input() viewings: TenantViewingModel;
private viewingsId;
constructor(private _viewings: ViewingsService) { }
ngOnInit() {
this.viewingsId = this.viewings.viewings_id;
console.log(this.viewings.viewings_id)
}
updateViewingStatus() {
this._viewings.updateViewingStatus(this.viewingsId);
}
}
And this is my modal logic (that doesnt work) :
export class PropertyViewingsCancelModalComponent implements OnInit {
#Input() viewings: TenantViewingModel;
private viewingsId;
constructor(private _viewings: ViewingsService) { }
ngOnInit() {
this.viewingsId = this.viewings.viewings_id;
// console.log(this.viewings.viewings_id)
}
updateViewingStatus() {
this._viewings.updateViewingStatus(this.viewingsId);
}
}
Which again are identical. The html for the working button is as follows:
<button (click)="updateViewingStatus()"></button>
and the non-working modal:
<div class="modal" id="cancelModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="text-center modal_title"> Are you sure you want to </div>
<h1 class="text-center" id="exampleModalLongTitle">Cancel Viewing? {{viewingsId}}</h1>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button>
</div>
<div class="modal-body">
<div class="container">
<img src="/assets/img/site/cancel.svg" alt="" style="height: auto; width: 100%; padding: 25px">
<div class="row">
<div class="col-md-6">
<button data-dismiss="modal" class="button button-primary button-xs button-previous text-center" (click)="updateViewingStatus()">confirm</button>
</div>
<div class="col-md-6 text-right">
<button data-dismiss="modal" (click)="logViewings()" class="button button-primary button-xs button-blue text-center">back</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
So just as a re-cap:
The button test works perfectly, removing the specific viewing that I want to remove or cancel. But with the modal, it only removes the first viewing on the page, even though the logic is identical, and I pass the data through to each child component in the exact same way.
Here some working example let's try this,
Html File,
<!--Pass your id as argument to your method.-->
<button (click)="onCancel(id)" class="button button-primary button-sm button-previous text-center">Cancel Viewing</button>
<!--This button has been hiden element is used to call your method -->
<button type="button" class="hideElement" data-toggle="modal" data-target="#cancelModal" #cancelModal></button>
<viewings-cancel-modal [viewings]="viewings"></viewings-cancel-modal>
Typescript File,
import { ElementRef, ViewChild } from '#angular/core';
#ViewChild('cancelModal') private cancelModal: ElementRef;
public onCancel(id:number) {
//set some global variable has been id value
localstorage.setItem("Id",id); //here set value as local storage.
this.viewings.viewings_id=id;
this.cancelModal.nativeElement.click(); //then here iam doing call that modal
}
Modal typescript File,
export class PropertyViewingsCancelModalComponent implements OnInit {
#Input() viewings: TenantViewingModel;
private viewingsId;
constructor(private _viewings: ViewingsService) { }
ngOnInit() {
//this.viewingsId = this.viewings.viewings_id;
this.viewingsId = localstorage.getItem("Id"); //here iam getting id value in localstorage
console.log("View Id",this.viewingsId) //here you getting your id you can proceed your process in modal button click time.
}
updateViewingStatus() {
this._viewings.updateViewingStatus(this.viewingsId);
}
}
It is a simple logic you have to implement your convenient. I hope it's helpful to solve your problem.
Thanks,
Muthukumar
import { Component, TemplateRef } from '#angular/core';
import { BsModalService } from 'ngx-bootstrap/modal';
import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';
#Component({
selector: 'demo-modal-service-static',
templateUrl: './service-template.html'
})
export class DemoModalServiceStaticComponent {
public modalRef: BsModalRef;
constructor(private modalService: BsModalService) {}
public openModal(template: TemplateRef<any>) {
this.modalRef = this.modalService.show(template);
}
}
Create template modal
<template #template>
<div class="modal-header">
<h4 class="modal-title pull-left">Modal</h4>
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
This is a modal.
</div>
</template>
http://valor-software.com/ngx-bootstrap/#/modals#directive-section
Hi, as seen above, creating modal with template will destro the template when, it is hidden. However; I don't want to be hidden. That is because, I use the modal for selecting some property multiple times from a list. Thus, every time, I have to load the modal. That causes a performance issue. Thus, Is there any way to stop it removing the modal from the dom.
We are currently stuck using bootstrap 2.3.2, and are looking to replace our current dialogs with bootstrap's modals.
I've located all the views where modals need to be instantiated and attempted 2 ways to call them without success.
With JS:
Html:
<a title='New Group' class='btn btn-fancy' id="btn-new-group" data-bind="visible: Value() == 'CanCreateNewGroup', click: corp.page.CreateGroupDialog.show">New Group<i class="fa fa-fw fa-lg fa-users"></i></a>
JS:
define([
'app-utils',
'jquery',
'bootstrap'
], function (utils) {
var CreateGroupDialog = function () {
};
CreateGroupDialog.prototype = $.extend(true, CreateGroupDialog.prototype, {
show: function (model) {
var dialog = $('#testing-bootstrap').modal({
toggle: true,
show: true,
keyboard: true
});
}
});
return CreateGroupDialog;
});
Without JS:
Html:
<a data-target="#testing-bootstrap" data-toggle="modal" class="btn btn-simple show_tooltip" title="Create Group"><i class="fa fa-fw fa-plus-circle"></i><span>Create Group</span></a>
The reason why I have to come here is that I get NO console errors, NO clue. The JS in my example is being hit, bootstrap is included and I've stepped through bootstrap code and it is loading my modal's html, but it is not coming up on the screen in EITHER way, with no console errors.
Actual modal markup (from bootstrap's example)
<div id="testing-bootstrap" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Modal header</h3>
</div>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary">Save changes</button>
</div>
</div>
Thanks, everyone.
I'm not totally sure how the binding is working in your example - it appears to use the Knockout data-bind attribute, but the rest is jQuery. I'm guessing that your CreateGroupDialog is not being correctly bound to the modal HTML - especially since you are using require.js. If the HTML without JS does not work either, there could be something else wrong, but I would modify your constructor code to bind to your <a> that should trigger the modal.
var CreateGroupDialog = function () {
$( 'a[title="Create Group"]' ).click( $.proxy( this.show, this ) );
};
Then instantiate it:
var modal = new CreateGroupDialog;
The suspected html in the description area of this question was part of an HTML partial which was being called in an area of the application that was not going to be visible then.
If you are using html partials then look into their visibility before doubting the bootstrap modals. That was my problem.