I was trying to use MatDialog to open a dialog with information in it. I followed a tutorial and in the component, I put a button that would call a "openDialog()" method and in the typescript I added the method along with changing the contructor. After changing the constructor, the page became completely blank, not showing a thing.
Here is the typescript with the changed constructor and method. (This is in the same component as the button in the html)
export class InfoComponent implements OnInit {
constructor(private dialog: MatDialog) {}
openDialog() {
this.dialog.open(BenefitsPopupComponent);
}
ngOnInit(): void {
}
}
Here is the basic button html
<button (click)="openDialog()">test</button>
and here is the component html that it will open
<h2 mat-dialog-title> test </h2>
the typescript on the component that is being opened is empty
I've tried various tutorials and such but keep getting the same results. I believe it has to do with the constructor but im not entirely sure. Thanks for the help!
this is my first time answering a question so I will try my best.
I'm not really sure if you mean that you want the popup to open a seperate component but I would rather do it as follows:
My Appomponent.ts looks like this:
export class AppComponent implements OnInit {
constructor(private dialog: MatDialog) { }
#ViewChild('myDialog', {static: false}) myDialog!: TemplateRef<any>;
openDialog() {
this.dialog.open(this.myDialog);
}
ngOnInit(): void {
}
doSomeAction() {
console.log('log something')
this.dialog.closeAll()
}
}
And then my html code looks like this:
<button (click)="openDialog()">test</button>
<ng-template #myDialog>
<h2 matDialogTitle>Test</h2>
<mat-dialog-content>
<p>Add some text here
</p>
</mat-dialog-content>
<mat-dialog-actions align="end">
<button mat-button matDialogClose>Cancel</button>
<button mat-button (click)="doSomeAction()">Do Something</button>
</mat-dialog-actions>
</ng-template>
This is just the way I would approach it, not sure if this actually helps you or not.
Related
I use angular at the frontend and .net core at the backend. I have a trivial problem and figure it with a video below. I spend hours and hours and still couldn't solve the problem.
I simply fetch data from my web api. And use *ngFor for display the data. But the problem is data is not shown before click any dropdown button.
Btw, dropdown button does not have any click event. It's simple language selector.
When I click language selector dropdown button, it expands and at the same time my data display on the screen.
I get my data ngOnInit. I check the data on debug mode and it's ok. I really spend hours and hours...still couldn't find any solution.
My html code :
<div class="container">
<div *ngFor="let d of devices"> --> I put here breakpoint and it run when I click dropdown btn
<span>{{d.name}}</span>
</div>
</div>
My .ts code:
import { ChangeDetectorRef, Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { ToastrService } from 'ngx-toastr';
import { Observable } from 'rxjs';
import { Pagination } from '../../../_helpers/Pagination';
import { deviceListModel, NewDeviceModel } from '../../admin-panel.model';
import { AdminPanelService } from '../../admin-panel.service';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
devices : Array<deviceListModel>; ---> I also try with public deviceList : deviceListModel[]; nothing change
constructor(private service : PanelService, private router : Router) { }
ngOnInit(): void {
this.getDeviceList();
}
getDeviceList() {
this.service.getDeviceList().subscribe(res => {
this.devices = res;
})
} ---> This part works fine. Data comes true from the backend before click the dropdown button.(I checked in debug mode with breakpoints)
}
Visiulize my problem with below link;
https://media.giphy.com/media/jYGHN1Ndxyeqhtn0ZR/giphy.gif
fullscreen with low res : https://giphy.com/gifs/jYGHN1Ndxyeqhtn0ZR/fullscreen
Edit :
When I try just display one of the data like devices[0].name;
<div>
<span> {{devices[0}.name}} </span>
</div>
I get data on page but with an error in console.
The error comes three times and the error is ;
core.js:4352 ERROR TypeError: Cannot read property '0' of undefined
Try putting the this.devices = res; into the NgZone
constructor(..., private _ngZone: NgZone)
this._ngZone.run(() => { this.devices = res; });
Can you try to put an *ngIf in the container? Like so:
<div class="container" *ngIf="devices?.length">
<div *ngFor="let d of devices">
<span>{{d.name}}</span>
</div>
</div>
In this case, the template will only be rendered when the backend call has completed successfully (and has results).
I am trying to add a basic modal dialog to pop up when I click on an image. My code is as follows:
HTML
<mat-card id="CARDBOX">
<img class="logo" src="path/image.jpg" alt="image" height=25px (click)="openDialog()"/>
</mat-card>
TS
#Component({
selector: 'app-cardbox',
templateUrl: './cardbox.component.html',
styleUrls: ['./cardbox.component.scss']
})
export class CardboxComponent implements OnInit {
constructor(private dialog: MatDialog) { }
ngOnInit(): void {}
openDialog() {
this.dialog.open(CardBoxComponent);
}
}
When I add anything to the constructor, everything on the page is deleting, nothing shows up at all. I just want an easy way to add a pop up dialog without making a new component. What am I doing wrong and is there a way to do this?
Please try using it with other options as 2nd parameter.
this.dialog.open(UserProfileComponent, {
height: '400px',
width: '600px',
});
I am trying to add a basic MatDialog to my project. In the project I have 2 components, a header for the page and another called "CardBox", which basically just holds cardboxes of links to different websites.
When you click on the "i" icon, I would like to open a dialog box with more information.
See image below.
Initially, my understanding was that I just add a MatDialog field in the constructor of Cardbox component. Like so:
cardboxes.component.html
<mat-card id="CARDBOX">
<img class="info" src="path/image.jpg" alt="image" height=25px (click)="openDialog()"/>
</mat-card>
cardboxes.component.ts
#Component({
selector: 'app-cardbox',
templateUrl: './cardbox.component.html',
styleUrls: ['./cardbox.component.scss']
})
export class CardboxComponent implements OnInit {
constructor(private dialog: MatDialog) { }
ngOnInit(): void {}
openDialog() {
this.dialog.open(CardBoxComponent);
}
}
(I'm aware that this is calling its own component, and would just open the same thing again. I am just trying to get it to work first.)
app.component.html
<div id="bg">
<app-header></app-header>
<br>
<app-cardbox></app-cardbox>
</div>
However, in doing so, it removes EVERYTHING from the page except the background, including the header component. This is what it looks like when the program is run when there is SOMETHING in the constructor of Cardbox.
As you can see, having something in the constructor gets rid of everything on the page, which does not make sense to me as it removes the header, which is a completely separate component from the cardbox. I have tried everything to make it work but still it is not working.
Why is touching the constructor makes the entire project blank? Is there something I forgot to add to another file? And how can I add a MatDialog popup feature to the project in a way that works?
TLDR: When I put anything in the constructor of one of my components, the entire page disappears. How do I resolve this?
Still seeking answer to this :(
You are using it wrong.
I am surprised your app compiles when doing this.dialog.open(CardBoxComponent)
What you need to do is, first create your dialog component.
To make things simple you can create it in the same file as you CardBox component, but make sure you put it outside CardBox class:
cardboxes.component.ts
#Component({
selector: 'dialog-overview-example-dialog',
templateUrl: 'dialog-overview-example-dialog.html',
})
export class DialogOverviewExampleDialog {
constructor(
public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
// data is gonna be the data you pass to dialog when you open it from CardBox
#Inject(MAT_DIALOG_DATA) public data: DialogData) {}
onNoClick(): void {
this.dialogRef.close();
}
}
then you create a template for the dialog component:
dialog-overview-example-dialog.html
<h1 mat-dialog-title>more info</h1>
<div mat-dialog-content>
<p>{{data.info}}</p>
</div>
finally you add openDialog(myInfo) function to your ts file, inside CardBox component:
cardboxes.component.ts
openDialog(myInfo): void {
const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
width: '250px',
// data you pass to your dialog
data: {info: myInfo}
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
this.animal = result;
});
}
and add it to your template too:
cardboxes.component.ts
<mat-card id="CARDBOX">
<img class="info" src="path/image.jpg" alt="image" height=25px (click)="openDialog('info about first site')"/>
</mat-card>
in this example I pass the info as a text, but it can be an object too.
Here is a demo to make things easier for you: link
I am trying to close modal from home component.my close button is in home component.If i click close button i want to close modal.If i click close button from home component how to set visible value is false from home component. How can i use service for that? or any other way is there? How do it?
dialog.component.html
<div [#dialog] *ngIf="visible" class="dialog">
<ng-content></ng-content>
<button *ngIf="closable" (click)="close()" aria-label="Close" class="dialog__close-btn">X</button>
<app-home></app-home>
</div>
<div *ngIf="visible" class="overlay" (click)="close()"></div>
home.component.ts:
<button (click)="showDialog = !showDialog" class="btn">Close</button>
Demo: https://stackblitz.com/edit/angular-7zdnwy?file=src%2Fapp%2Fdialog%2Fdialog.component.html
I followed this approach from Angular Documentation and it works ok.
You Parent is Dialog and child is app-home. So emitter is defined in child class like this
export class HomeComponent implements OnInit {
#Output() close = new EventEmitter<boolean>();
...
// <button (click)="onClose()" in html
onClose() {
this.close.emit(true)
}
}
and listen for the event in parent dialog class like this
// html
<app-home (close)="onCloseClick($event)"></app-home>
// Class code
export class DialogComponent implements OnInit {
...
onCloseClick(close: Boolean) {
if(close){
this.close()
}
}
...
}
Hope it helps.
I have an angular (4) based web app, with an #angular/material based card view. Embedded in the content of the card view is a sub-component, which just displays an svg as an <object>.
Here is what that card looks like:
<md-card (click)="onSelect(line)">
<md-card-content (click)="onSelect(line)">
<app-line-overview [line]="line"></app-line-overview>
</md-card-content>
<md-card-footer>
<h2>{{line.name}}</h2>
<h3>OEE: {{line.oee}}</h3>
</md-card-footer>
</md-card>
The issue is that the (click) event doesn't work if I click on the svg image (presumably because it is on top of the card view?), but if I click around the svg, the event fires.
I tried the adding md-card { z-index: 999 } to the css, but it makes no difference. How can I ensure that clicking anywhere within the card fires the event regardless of what is inside it?
Maybe writing a directive with a listener on clicks would help :
#Directive({
selector: '[clickInside]'
})
export class ClickInsideDirective {
constructor(private elementRef: ElementRef) {
}
#Output()
public clickInside = new EventEmitter<Event>();
#HostListener('click', ['$event', '$event.target'])
public onClick(event: MouseEvent, targetElement: HTMLElement): void {
if (!targetElement) {
return;
}
const clickedInside = this.elementRef.nativeElement.contains(targetElement);
if (clickedInside) {
this.clickOutside.emit(event);
}
}
...
}
usage
<md-card (clickInside)="onSelect(line)">