Angular attr.data-target and attr.id not working - javascript

I am trying assign unique id to my bootstrap modal as it's being using ngFor. Following is my code.
<div class="container shadow lead-container" data-toggle="modal" [attr.data-target]="customId"> -------------------------> . Data-target is set to customId
<div class="row text-left">
----------------------> Other Content goes here
</div>
</div>
<!--Lead Popup-->
<div class="modal fade" [attr.id]="customId" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true"> -----------> [attr.id] is set to customid
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="container popup-container">
<div class="row text-left">
-------------------------------------> Modal Content Goes Here
</div>
</div>
</div>
</div>
Following is my component.ts:
import { Lead } from './../models/lead';
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-lead',
templateUrl: './lead.component.html',
styleUrls: ['./lead.component.css']
})
export class LeadComponent implements OnInit {
#Input() public lead: Lead;
#Input() public index;
public customId: string;
constructor() {
}
ngOnInit() {
this.customId = "custom".concat(this.index);
}
}
When i click on div. The modal doesnt popup for some reason. Any help would be much appreciated

add "#" to the id.
[attr.data-target]="'#'+customId"

Related

Angular 6 Passing data from parent to child Bootstrap Modal

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);
}

basic-dialog component is not working fine with async call

I have created an basic-dialog component to display popup on screen for confirmation. This component is not working with asynch call. I want to display popup after receiving service response. I am using Angular 6 and Bootstarap 3.3
Following is my basic component ts file:-
#Component({
selector: 'basic-dialog',
styleUrls: ['./dialog.component.scss'],
templateUrl: './dialog.component.html',
animations: [
trigger('dialogState', [
transition(':enter', [
style({ transform: 'translateY(-100%)' }),
animate('900ms ease-in', style({ transform: 'translateY(0%)' }))
]),
transition(':leave', [animate('100ms ease-in', style({ transform: 'translateY(-100%)' }))])
])
]
})
export class DialogComponent implements OnChanges, OnDestroy {
#Input() visible = false;
#Input() modalId = '';
#Input() styles: any;
constructor(
#Inject(DOCUMENT) private document: Document,
private renderer: Renderer2,
private element: ElementRef,
private changeDetectorRef: ChangeDetectorRef
) {}
ngOnChanges(): void {
if (this.visible) {
this.element.nativeElement.querySelector('.modal').id = this.modalId;
document.querySelector('body').appendChild(this.element.nativeElement);
this.changeDetectorRef.detectChanges();
}
}
ngOnDestroy(): void {
if (this.element.nativeElement.parentElement.tagName.toUpperCase() === 'body'.toUpperCase()) {
document.querySelector('body').removeChild(this.element.nativeElement);
if (document.querySelector('.modal-backdrop')) {
document.querySelector('body').removeChild(document.querySelector('.modal-backdrop'));
}
}
}
}
HTML file :-
<div class="modal fade" [id]="modalId" role="dialog" aria-label="close" style="display: none;">
<div class="modal-dialog" [ngStyle]="styles">
<div class="uil-dialog-card x-overflow-hidden">
<!-- <button *ngIf="closable" (click)="close()" aria-label="Close" type="button" class="close" data-dismiss="modal">
<img class="svg" src="../assets/theme/img/cross_icon.svg">
</button>-->
<div id="modal_content">
<ng-content></ng-content>
</div>
</div>
</div>
</div>
dashboard file ts file:-
ngOnInit(): void {
this.visible = false;
this.loginService.dashboardModuleChangeMsg.subscribe(data => {
this.displayModuleChangePopup(data);
});
}
/** To display Dialog box */
displayModuleChangePopup(data): void {
this.visible = true;
this.changeDetectorRef.detectChanges();
}
/** Event handler for continue button in Dialog box */
onSubmitHandler(): void {
// code
}
/** Event handler for cancel button in Dialog box */
onCancelHandler(): void {
// code
}
dashboard html file :-
<basic-dialog *ngIf="visible" [visible]="visible" [modalId]="MODULE_SWITCH_DIALOG" [styles]="{'max-width':'434px'}">
<div class="row">
<div class="uil-card-title-area" style="margin-bottom:20px">
<div class="uil-card-title">
Module Navigation
</div>
</div>
<div id="text_inputs_body">
You are trying to navigate to another module. Any unsaved data will be lost.
</div>
<div class="alignRight">
<button type="button" data-dismiss="modal" class="uil-btn-flat uil-flip-button" (click)="onCancelHandler(user)">Cancel</button>
<button type="button" data-dismiss="modal" class="uil-btn uil-tooltip" (click)="onSubmitHandler(user);">Continue</button>
</div>
</div>
</basic-dialog>
Popup is not getting displayed on first time, but when second time subscriber triggered popup is getting display.
If i run this popup without async call, it is working fine.

Inputting data into a modal from a parent component Angular 5

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

Angular: bootstrap backdrop is displayed when it shouldn't be

So I'm doing error handling on my app and I want to pop up a bootstrap modal whenever I have an error.
At first I want my backdrop and error modal to have display 'none'. When there is an error I would like the backdrop + error modal to pop-up. I am able to hide the modal when I load the webpage, but unfortunately the backdrop isn't hidden (there is a dark grey background and I can't even click it to make it disappear. Can someone see why? Modal and backdrop elements both have the same '[ngStyle]="{'display': display}"' that is linked to the error component property.
error.component.ts
import {Component, OnInit} from "#angular/core";
import {ErrorService} from "./error.service";
#Component({
selector: 'app-error',
templateUrl: './error.component.html',
styles: [`
.backdrop {
background-color: rgba(0, 0, 0, 0.6);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
}
`]
})
export class ErrorComponent implements OnInit {
error: Error;
displayed = 'none'
constructor(private errorService: ErrorService) {
}
onErrorHandled() {
this.display = 'none'
}
ngOnInit() {
this.errorService.errorOccurred.subscribe(
(error: Error) => {
this.error = error;
this.display = 'block';
}
);
}
}
error.component.html
<div class="backdrop" [ngStyle]="{'display': display}"></div>
<div class="modal" tabindex="-1" role="dialog" [ngStyle]="{'display': display}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" aria-label="Close" (click)="onErrorHandled()"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">{{ error?.title }}</h4>
</div>
<div class="modal-body">
<p>{{ error?.message }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" (click)="onErrorHandled()">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
Maybe is because you have 2 variables "displayed" and "display"
Use the native Bootstrap 4 class d-none for hiding things. IF you are using Bootstrap 4 that is.
No need for custom css.

Modal event before hide

I have a problem. I need to show toastr informing that changes are not saved when someone wants to hide modal. I need to trigger toastr before modal hide, and when the user tries again to dismiss modal allow this. I tried something like this:
declare let jQuery: any;
declare let $: any;
declare let toastr: any;
#Component({
selector: 'app-trigger',
templateUrl: './trigger.component.html',
styleUrls: ['./trigger.component.scss']
})
export class TriggerComponent implements OnInit {
name: string
private canHideModal = true;
constructor() {
}
ngOnInit(){
const self = this;
$('#triggerModal').on('hide.bs.modal', () => {
if (self.canHideModal) {
//hide modal here <---------
} else {
toastr['warning']('You have unsaved changes');
self.canHideModal = true;
return false
}
});
}
fireModal(changes : {action:string, name:string}){
changes.action = 'show';
changes.name = 'test';
this.name = changes.name
$('#triggerModal').modal(changes.action);
}
}
and it works fine for first time, after this hide event seems to be overwriten and function $('#triggerModal').on('hide.bs.modal', () => { doesn't trigger anymore.
HTML:
<div class="modal fade" id="triggerModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-lg px-4" role="document">
<!--Content-->
<div class="modal-content">
<!--Header-->
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<!--Body-->
<div class="modal-body mb-0">
<!--Grid row-->
<div class="row d-flex justify-content-center mb-4">
<!--Grid column-->
<div class="col-md-6">
<!--Name-->
<div class="md-form">
<input type="text" id="triggerStartName" (input)="canHideModal = false" class="form-control" #triggerName [value]="name">
<label for="triggerStartName" [ngClass]="{ 'active': name }">Trigger name</label>
</div>
</div>
<!--Grid column-->
</div>
<!--Grid row-->
</div>
<!--Footer-->
<div class="modal-footer justify-content-center">
<button type="button" class="btn btn-primary waves-effect waves-light" data-dismiss="modal">Close</button>
</div>
</div>
<!--/.Content-->
</div>
</div>
You can do it with the ng-bootstrap Modal component, by assigning a method to its beforeDismiss option, as illustrated in this plunker:
import {Component} from '#angular/core';
import {NgbModal, ModalDismissReasons} from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'ngbd-modal-basic',
templateUrl: 'src/modal-basic.html'
})
export class NgbdModalBasic {
closeResult: string;
private canHideModal = false;
constructor(private modalService: NgbModal) {}
open(content) {
this.canHideModal = false;
const options : NgbModalOptions = {
beforeDismiss: () => {
if (this.canHideModal) {
return true;
} else {
alert('You have unsaved changes');
this.canHideModal = true;
return false;
}
}
};
this.modalService.open(content, options).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
...
}

Categories

Resources