I'm getting the following error when trying to close my modal:
cannot read property nativeElement of undefined
The element has been rendered by time i'm trying to close it so I'm not sure what else it could be.
Modal code:
<div class="modal" id="myModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
</div>
<div class="modal-body">
<button type="button" class="btn btn-primary" (click)="close()">Close</button>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</div>
</div>
Typescript:
import { Component, OnInit, ElementRef, ViewChild } from '#angular/core';
#Component({
selector: 'app-main',
templateUrl: './main.component.html',
styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit {
constructor() { }
#ViewChild('myModal') closeModal: ElementRef;
ngOnInit() {
}
close() {
this.closeModal.nativeElement.click();
}
}
ViewChild uses a template reference variable, not the id, to refer to the element. You should set the variable myModal on the target element in the template markup:
<div class="modal" #myModal ...>
so that you can refer to that element with ViewChild:
#ViewChild('myModal') closeModal: ElementRef;
Related
<img id="1" data-toggle="modal" data-target="#myModal" data-dismiss="modal" src='assets/barrel.jpg' alt='Text dollar code part one.' />
<div id="myModal" class="modal fade" *ngIf="isModalShowing">
<div class=" modal-lg center">
<div class="modal-header">
<button type="button" class="close" (click)="toggleModal()">×</button>
<div class="modal-content">
<div class="modal-body">
<img id="1" src="assets/barrel.jpg" class="img-responsive">
<img id="2" src="assets/car.jpg" class="img-responsive">
</div>
</div>
</div>
</div>
</div>
Above is my html, nothing happens when I click on the image that I am using as my modal trigger. This started when I add the ngIf="isModalShowing" function. Below is my typescript.
import { Component, OnInit, ViewChild } from '#angular/core';
import { NgModule } from '#angular/core';
#Component({
selector: 'app-portfolio',
templateUrl: './portfolio.component.html',
styleUrls: ['./portfolio.component.scss']
})
export class PortfolioComponent implements OnInit {
constructor() { }
public ngOnInit() {
}
isModalShowing: boolean;
toggleModal() {
this.isModalShowing = !this.isModalShowing;
}
}
This might help you as you are using pure bootstrap.
pay attention to [ngClass] in app.component.html file
I added modal-backdrop class to the class list that gives a visual indication of an active modal.
https://stackblitz.com/edit/angular-jggbzx
Or else use ng-bootstrap that has better ways of doing this
Documentation
https://ng-bootstrap.github.io/#/components/modal/examples
Running Example
https://stackblitz.com/edit/angular-dwqv1u
I try to modify a part of HTML in a component as we do with JS "innerHTML" in a angular app. I'm a beginner with angular, maybe I missed something important.
Actually look like that (typescript, html (from the same component)):
import { Component, OnInit, Input } from '#angular/core';
import { GraphService } from '../services/graph.service';
#Component({
selector: 'app-graph-content',
templateUrl: './graph-content.component.html',
styleUrls: ['./graph-content.component.scss']
})
export class GraphContentComponent implements OnInit {
#Input() graphName: string;
#Input() index: number;
#Input() id: number;
#Input() graphContent: any;
graphI:string;
constructor(private graphService:GraphService) { }
testF(){
var inputGraph = this.graphService.refreshGraph(this.graphContent);
//inputGraph should go in DOM and look like : "<div class=\"progress-fill\" style=\"background-color: black;\"><span>XX%</span></div>"
}
ngOnInit() {
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div class="list-group-item list-group-item-action flex-column align-items-start list-group-flush">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"> {{ graphName }}</h5>
</div>
<div class="horizontal" style="height: 100px;">
<div class="progress-track" style="display: flex; flex-wrap: nowrap; justify-content: flex-start;" id="graphInput">
<!--here comes the content-->
</div>
<button (click)="testF()">react</button>
</div>
So inputGraph must go in graphInput div. Is there a simple way to do it, would it be better to create a component for this part?
You can use the property binding for innerHTML like [innerHTML].
<div [innerHTML]="htmlstring">
and in your component.ts file
this.htmlstring = `<p> Hello</p>`
¿What kind of data came from this.graphService.refreshGraph(this.graphContent)?
¿It´s JSON data?
Maybe you could make a component named app-input-graph, with an #Input inputGraph and this html code:
<div class="progress-fill" style="background-color: black;">
<span>{{inputGraph}}</span>
</div>
And in app-graph-content:
<app-input-graph [inputGraph]="inputGraph"><app-input-graph>
enter image description here
html code
<div id="myModal" class="modal">
<div class="modal-content">
<div class="modal-header" style="text-align: center;">
<span class="close">×</span>
<h2>Register Account</h2>
</div>
<div class="modal-body">
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
Employer
</div>
<div class="su-body" style="background-color:#3B5998;">
Candidate
</div>
</div>
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
Login with Faceboo
</div>
<div class="su-body" style="background-color:#3B5998;">
Login With Google
</div>
</div>
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
Login With Linkedin
</div>
<div class="su-body" style="background-color:#3B5998;">
Login With Twitter
</div>
</div>
</div>
<div class="modal-footer">
<div class="signup-body">
<!-- <button>Sign up</button> -->
<div class="su-body" style="background-color:#3B5998;">
Sign up
</div>
</div>
<p>Already have ab account</p>Login
</div>
</div>
</div>
I want to create a registration page has given below in angular 6. But my question is when user can register two ways (either employer or candidate ) so how can i send Api particular field data. please help me.
Please check below solution might be it can help you to observe Registration Type:
Registered Event in Html:
<div class="signup-body">
<div class="su-body" style="background-color:#3B5998;">
<a href="#" target="_blank" (onclick)="changeReg('Employer')" >Employer</a>
</div>
<div class="su-body" style="background-color:#3B5998;">
<a href="#" target="_blank" (onclick)="changeReg('Candidate')" >Candidate</a>
</div>
</div>
Create a data sharing service
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class DataService {
private regSource = new BehaviorSubject('Employer'); //Default registration type
currentReg = this.regSource.asObservable();
constructor() { }
changeRegType(regTyp: string) {
this.regSource.next(regTyp)
}
}
Set New Registration type within Supplied Html component:
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-registration',
styleUrls: ['./registration-selection.component.css']
})
export class RegistrationSelectionComponent implements OnInit {
constructor(private data: DataService) { }
changeReg(regType:String) {
this.data.changeRegType(regType);
}
}
Get default/new registration type in signup component:
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-signup',
template: `
{{message}}
`,
styleUrls: ['./signup.component.css']
})
export class SignUpCmponent implements OnInit {
regType:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentReg.subscribe(reg => this.regType = reg)
}
}
I have 3 components in angular 2 application.The class="container-fluid content" is css class in app.component.html. This class="container-fluid content" is default css for other components. Now I want to set background-color:blue in the detail component. I tried to set in detail.component.ts like this styles:['.container-fluid content{background-color: blue;}'] It did not work. If I set in app.component.html like this <div class="container-fluid content" style="background-color: blue;"> It applies to both the components. How to override this class="container-fluid content" in detail component?
//my project structure
app
- app.component.html
-app.component.ts
- welcome
-welcome.component.html
-welcome.component.ts
- detail
-detail.component.html
-detail.component.ts
//app.component.html
<div class="container-fluid content">
<router-outlet></router-outlet>
</div>
<app-footer></app-footer>
</div>
//welcome.component.html
<h1>welcome page heading</h1>
<div fxLayout="row" fxLayoutWrap style="padding-bottom: 25px;
padding-top: 25px; margin: auto;justify-content: center" >
<md-card>
<md-card-content>
<h1></h1>
<h2></h2>
<h2>
</h2>
</md-card-content>
</md-card>
</div>
//detail.component.html
<h1>Details page heading</h1>
<div fxLayout="row" fxLayoutWrap style="padding-bottom: 25px;
padding-top: 25px; margin: auto;justify-content: center" >
<md-card>
<md-card-content>
<h1></h1>
<h2></h2>
<h2>
</h2>
</md-card-content>
</md-card>
</div>
//detail.component.ts
import { OnInit, Component } from '#angular/core';
import { DetailService } from '../detail/detail.service';
import { HostBinding} from '#angular/core';
#Component({
providers: [DetailService ]
templateUrl: './detail.component.html',
styles: ['h3 {margin:5px}']
})
export class DetailComponent implements OnInit {
#HostBinding('class.blueClass') blue: boolean = false;
constructor( private _detailService: DetailService ) { }
ngOnInit() {
this.blue = true;
}
}
In child component, you can add this param to #Component.
// child-component.component.ts
#Component({
selector: 'child-component',
templateUrl: 'child-component.component.html',
styleUrls: ['child-component.component.css']
encapsulation: ViewEncapsulation.None
})
// child-component.component.css
.container-fluid content{background-color: blue;}
You can ref this side for more infomartion :
https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html
Have you tried with the hostbinding and adding a new class there?
#HostBinding('class.blueClass') blue: boolean = false;
And in the second component just switch that on onInit?
ngOnInit() {
this.blue = true;
}
The other way could be in the component definition, you can add the following line :
host: {'class': 'blueClass'}
and you do the rest of the css work in css instead.
I'm trying to trigger the state of the sidenav (opened and closed). I have this:
<div class="viewport">
<md-toolbar color="primary">
<button *ngIf="!isNavbarOpen" md-icon-button (click)="sidenav.open()"><md-icon>menu</md-icon></button>
<button *ngIf="isNavbarOpen" md-icon-button (click)="sidenav.close()"><md-icon>close</md-icon></button>
<span class="toolbar-title">Title</span>
</md-toolbar>
<md-sidenav-layout>
<md-sidenav align="start" mode="over" #sidenav>
Sidenav
</md-sidenav>
</md-sidenav-layout>
</div>
How can I use the #sidenav from my TypeScript file to change the isNavbarOpen field whenever the sidenav state changes?
or
How could I override the sidenav.open() method?
Here is a better approach so you can use all the properties and subscribe to all the events. Don't pass it to the open()/close() function.
<div class="viewport">
<md-toolbar color="primary">
<button *ngIf="!isNavbarOpen" md-icon-button (click)="open()"><md-icon>menu</md-icon></button>
<button *ngIf="isNavbarOpen" md-icon-button (click)="close()"><md-icon>close</md-icon></button>
<span class="toolbar-title">Title</span>
</md-toolbar>
<md-sidenav-layout>
<md-sidenav align="start" mode="over" #sidenav>
Sidenav
</md-sidenav>
</md-sidenav-layout>
</div>
Instead references it by using "ViewChild" and MdSidenav:
import { Component, ViewChild, OnInit } from '#angular/core';
import { MdSidenav } from '#angular/material';
#Component({
....
})
export class AppComponent implements OnInit {
public isNavbarOpen: boolean;
// This gets a reference to the #sidenav
#ViewChild('sidenav') sidenav: MdSidenav;
ngOnInit() {
// Subscribe to the onCloseStart event
this.sidenav.onCloseStart.subscribe(() => {
this.isNavbarOpen = true;
});
}
open() {
this.sideNav.open();
}
}