How to add autofocus on first input element in loop? - javascript

So im doing loop and display inputs and i want on click on select to add focus on first input element. Any suggestion how can i select that first element and add him autofoccus?

Here is how to do. Write a directive :
import {Directive, Renderer, ElementRef, OnInit, AfterViewInit, Input} from '#angular/core';
#Directive({
moduleId: module.id,
selector: '[focusOnInit]'
})
export class FocusOnInitDirective implements OnInit, AfterViewInit {
#Input() focusOnInit ;
static instances: FocusOnInitDirective[] = [];
constructor(public renderer: Renderer, public elementRef: ElementRef) {
}
ngOnInit(): void {
FocusOnInitDirective.instances.push(this)
}
ngAfterViewInit(): void {
setTimeout(() => {
FocusOnInitDirective.instances.splice(FocusOnInitDirective.instances.indexOf(this), 1);
});
if (FocusOnInitDirective.instances.every((i) => i.focusOnInit===0)) {
this.renderer.invokeElementMethod(
this.elementRef.nativeElement, 'focus', []);
}
}
}
in your component:
import { Component } from '#angular/core';
#Component({
moduleId: module.id,
selector: 'app',
template: `
<div *ngFor="let input of [1,2,3,4]; let i=index">
<input type="text" [focusOnInit] = i >
</div>
`
})
export class AppComponent {
}
The corresponding plunker, adapted from this

Related

Angular eventemitter not working when emitting the event from directive

appcomp.html
`<app-child (callemit) = parentFunc($event)> </app-child>`
appcomp.ts
`
import { Component, OnInit, EventEmitter } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.comp.html'
})
export class AppComponent {
ngOnInit() {}
parentFunc(event){
console.log(event)
}
}
`
childcomp.html
childcomp.ts
`
#Component({
selector: 'app-child',
templateUrl: './app.child.component.html'
})
`
mydirective.ts
`
import { Directive, ElementRef, Input, Output, HostListener, EventEmitter } from '#angular/core';
#Directive({
selector: '[myDirective]'
})
export class myAppDirective {
constructor() {}
#Input ('myDirective') val: string;
#Output() callEmit = new EventEmitter();
#HostListener('click')
onClick() {
event.preventDefault();
this.callEmit.emit({event , val});
}
}
`
In the above code i am trying to call parentFunc from appcomp using eventemitter and not able to get this work. Please let me know what is wrong here.
I think you most call callEmit on child component
childcomp.html
and in child Component emit the CallEmit Which called from appComp
childcomp.ts
#Output() callEmit = new EventEmitter();
childFunc(){
this.callEmit.emit();
}
and finally use
appCom.html
`<app-child (callemit) = parentFunc($event)> </app-child>`
appcom.ts
parentFunc(event){
console.log(event)
}
https://stackblitz.com/edit/angular-exxhms
Try it on component

Access child host elements nativeElement properties from host element in angular 4

I want to the elementReference of mat-card from parent component i.e AppComponent. I have written a directive and attached it to the host component. If I try to access elem.nativeElement.childNodes[0] , it gives undefined. How to access mat-card element reference from the parent component.
Here's the demo.
Thanks
Here's my directive
import { Directive, ElementRef, Renderer2 } from '#angular/core';
#Directive({ selector: '[displayStyle]' })
export class DisplayStyleDirective {
constructor(elem: ElementRef, renderer: Renderer2) {
console.log(elem.nativeElement.childNodes[0])
}
}
In console i get undefined .
App.Component.html
<div>
<h3>Recognized Images</h3>
<div>
<card-overview-example displayStyle *ngFor="let user of existingUserInfo" [User]="user"></card-overview-example>
</div>
</div>
App.component.ts
import {
Component,
OnInit,
AfterViewInit,
ElementRef,
Renderer2,
ViewChild
} from "#angular/core";
#Component({
selector: "app-root",
templateUrl: "./app.component.html",
})
export class AppComponent implements OnInit,AfterViewInit {
constructor(private elementRef: ElementRef,
private renderer: Renderer2) { }
ngOnInit() { }
existingUserInfo:Array<userDetails> = [
{userID:"121",filename:"https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Angular_full_color_logo.svg/250px-Angular_full_color_logo.svg.png"},
{userID:"122",filename:"https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Angular_full_color_logo.svg/250px-Angular_full_color_logo.svg.png"},
{userID:"123",filename:"https://upload.wikimedia.org/wikipedia/commons/thumb/c/cf/Angular_full_color_logo.svg/250px-Angular_full_color_logo.svg.png"}
]
ngAfterViewInit() {
}
}
export interface userDetails {
userID: string;
filename: string;
}
Card-overview-example.html
<mat-card class="example-card">
<img [src]="userDetails.filename" alt="Photo of {{userDetails.userID}}">
<p >{{userDetails.userID}}</p>
</mat-card>
card-overview-example.ts
import {Component,Input} from '#angular/core';
/**
* #title Basic cards
*/
#Component({
selector: 'card-overview-example',
templateUrl: 'card-overview-example.html'
})
export class CardOverviewExample {
#Input("User") userDetails: userDetails;
}
export interface userDetails {
userID: string;
filename: string;
}
Here's the demo.
Try elem.nativeElement.children[0] instead of elem.nativeElement.childNodes[0]

ExpressionChangedAfterItHasBeenCheckedError . Angular 2(5) *ngIf

I'm using a service to pass data between child and parent with the purpose being to update the parent ui with child specific info depending on what child is loaded.
Service:
import { Subject } from "rxjs/Subject";
export class ChildDataService {
private childDetails = new Subject<{}>();
childLoaded$ = this.childDetails.asObservable();
changedComponentName(option: {}){
this.childDetails.next(option);
}
}
Parent Component:
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { ChildDataService } from "../core/helpers/child-data.service";
import { Subscription } from "rxjs/Subscription";
#Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ParentComponent implements OnInit {
childDetails: {title?: string};
private subscription:Subscription;
constructor( private childDataService: ChildDataService) {
this.childDataService.childLoaded$.subscribe(
newChildDetails => {
console.log(newChildDetails);
this.childDetails = newChildDetails
});
}
}
Example Child Component:
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { ChildDataService } from "../../core/helpers/child-data.service";
#Component({
selector: 'app-child-dashboard',
templateUrl: './child-dashboard.component.html',
styleUrls: ['./child-dashboard.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ChildDashboardComponent implements OnInit {
constructor(private childDataService: ChildDataService) { }
public ngOnInit() {
this.childDataService.changedComponentName({
title: 'Dashboard'
});
}
}
Parent HTML:
<div class="subheader">
<h1>{{ childDetails?.title }}</h1>
<button *ngIf="childDetails?.title == 'Dashboard'">dashboard</button>
<button *ngIf="childDetails?.title == 'SecondChild'">Second Child</button>
</div>
With this setup I am getting the error "ExpressionChangedAfterItHasBeenCheckedError" when i click on a routerLink, now if i click on the same link a second time, the error persists but the correct button becomes visible. Spent all weekend getting nowhere with this, so any help would be greatly appreciated.
public ngOnInit() {
setTimeout(() => {
this.childDataService.changedComponentName({
title: 'Dashboard'
}), {});
}
it should work.
async ngOnInit() {
await this.childDataService.changedComponentName({
title: 'Dashboard'
});
}

How to inject document.body in Angular 2

I want to add some text in showlist.component.html. My code is given below, I am not aware how to use document.body in Angular 2.
import { Component, OnInit } from '#angular/core';
import { DOCUMENT } from '#angular/platform-browser';
#Component({
selector: 'app-showlist',
templateUrl: './showlist.component.html',
styleUrls: ['./showlist.component.css']
})
export class ShowlistComponent implements OnInit {
public myname = "saurabh";
constructor() { }
ngOnInit() {
//this.myname.appendTo(document.body);
document.body(this.myname);
//document.write(this.myname);
}
}
you do the following to access the document.body
import { Component, OnInit, Inject } from '#angular/core';
import { DOCUMENT } from '#angular/common';
#Component({
selector: 'app-showlist',
templateUrl: './showlist.component.html',
styleUrls: ['./showlist.component.css']
})
export class ShowlistComponent implements OnInit {
public myname = "saurabh";
constructor(#Inject(DOCUMENT) private document: Document) {}
ngOnInit() {
this.document.body.innerHTML = this.myname;
}
}

angular 2 output and eventemitter doesn't emit

i'm learning angular 2, and i follow this tutorial: https://egghead.io/lessons/angular-2-angular-2-building-a-toggle-button-component
but the whole part of the output and eventemitter doesn't work.
i do not get any errors and i can't figure out why it doesn't work.
this is my code for the togglelink component:
import { Component, OnInit, Input, Output, EventEmitter } from '#angular/core';
#Component({
moduleId: module.id,
selector: 'app-togglelink',
templateUrl: 'togglelink.component.html',
styleUrls: ['togglelink.component.css']
})
export class TogglelinkComponent implements OnInit {
#Input() state:boolean = true;
#Output() onChange = new EventEmitter();
onClick(){
this.state = !this.state;
this.onChange.emit(this.state);
}
constructor() {}
ngOnInit() {
}
}
and this is the code for the firstpage component that uses the togglelink component:
import { Component, OnInit } from '#angular/core';
import {TogglelinkComponent} from '../togglelink/togglelink.component';
#Component({
moduleId: module.id,
selector: 'app-firstpage',
templateUrl: 'firstpage.component.html',
styleUrls: ['firstpage.component.css'],
directives: [TogglelinkComponent]
})
export class FirstpageComponent implements OnInit {
thetogglestate:boolean = false;
firsttitle = "the first title";
constructor() {}
ngOnInit() {
}
}
and this is the code for the template of the firstpage component:
{{thetogglestate ? 'On' : 'Off'}}
</p>
<h2 *ngIf="thetogglestate">
{{firsttitle}}
</h2>
<p>
firstpage works!
</p>
when i change manually thetogglestate it does work, so i understand that the issue is with the output and the eventemitter part.
any idea why?
best regards
In the firstpage.component.html template, you need to register some processing for this event to toggle the value of the thetogglestate variable.
Something like that:
<app-togglelink (onChange)="thetogglestate = !thetogglestate"></app-togglelink>

Categories