I have the following code. According to my requirement,
If I press tab from keyboard, then <div> element should be focused and (click) event should work - it is working fine currently
but if I click the same <div> element with mouse click, then this <div> element should not be focused and (click) event should work - here <div> element is focussing on first click only with the current code, don't know why ?
I am not sure what I am doing wrong here, Please help me to fix this issue. Thanks in advance.
Stackblitz
html:
<button>First</button> <br/>
<div tabindex="0" (click)="func();" (keyup.enter)="func();" appDivfocusout>Check Focus Out on Click</div> <br/>
<button>Second</button>
component.ts:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
func(){
console.log("test message");
}
}
directive.ts:
import { Directive, ElementRef, Renderer2, HostListener } from '#angular/core';
#Directive({
selector: '[appDivfocusout]'
})
export class DivfocusoutDirective {
constructor(private el: ElementRef, private renderer: Renderer2) { }
#HostListener('click',['$event'])
onClick(e){
this.el.nativeElement.style.outline = 'none';
}
}
Related
When I click on the Test, the click function should be called.
But nothing is triggered.
HTML componrnt:
<div class="row m-0 justify-content-between" *ngFor="let i of
k[currentk]?.details | keys">
<div (click)="test(i.name)">{{i.name}}</div>
</div>
ts component:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
constructor() {}
ngOnInit() {}
test(name){
alert('Hello world');
}
}
You're already doing it right. You don't need the *ngFor loop in your div tag. SImply remove it and your code shall work.
I searched on Google how to do what I want to do and tried some things but nothing works and I found a lot of AngularJS tutorial but not Angular6.. so I hope u will be able to help me.
I want to make a fade when my array's values change (on click) so I downloaded ng-animate but it doesn't give me the behaviour I'm looking for.
Currently, I've got two components so the first:
HTML:
<div style="text-align: center; margin: 20px 0">
<div class="buttonSelector" *ngFor="let select of buttonSelector" (click)="getSelectArray(select.title)"
[ngClass]="{'selected': select.title === selectedArray.title.toUpperCase() }">
<p>{{ select.title }}</p>
</div>
</div>
<app-infoapp [selectedArray]="selectedArray"></app-infoapp>
There, I change my selectedArray by sending a variable to getSelectArray() then I send it to my 'app-infoapp' component.
On my 'app-infoapp' component, we can find this:
import {Component, Input, OnInit} from '#angular/core';
import { trigger, transition, useAnimation } from '#angular/animations';
import {bounce, fadeIn} from 'ng-animate';
#Component({
selector: 'app-infoapp',
templateUrl: './infoapp.component.html',
styleUrls: ['./infoapp.component.css'],
animations: [
trigger('fade', [transition('* => *', useAnimation(fadeIn, {delay: 0.2}))])
]
})
export class InfoappComponent implements OnInit {
#Input() selectedArray;
fade: any;
constructor() {
}
}
So now when I refresh my page, the component is fading so that's cool but when I change my array by clicking on the button so another array is sent to my 'app-infoapp' component, it doesn't animate another time.
I hope I was clear and that u will be able to help me.
If you need more informations or if I wasn't clear tell me, I'll answer as fast as possible.
Thanks.
I tried the same example which i suggested to you (kdechant.com/blog/angular-animations-fade-in-and-fade-out) with your sample code and it is working:
Import BrowserAnimationsModule in the application module (app.module.ts):
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
#NgModule({
declarations: [...],
imports: [BrowserAnimationsModule],
bootstrap: [AppComponent]
})
export class AppModule { }
parent.component.html
<div style="text-align: center; margin: 20px 0">
<div *ngFor="let select of buttonSelector" (click)="getSelectArray(select.title)">
<p>{{ select.title }}</p>
</div>
</div>
<app-infoapp [selectedArray]="selectedArray"></app-infoapp>
parent.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
public buttonSelector = [];
public selectedArray = [];
constructor() { }
ngOnInit() {
this.buttonSelector = [{title: 'save'}, {title: 'add'}, {title: 'edit'}, {title: 'delete'}];
}
getSelectArray(title: string) {
this.selectedArray.push({title:title});
}
}
info-app.component.html
<div class="info" *ngFor="let selected of selectedArray" [#simpleFadeAnimation]="'in'">
{{ selected.title }}
</div>
info-app.component.ts
import {Component, Input, OnInit} from '#angular/core';
import { trigger, transition, state, style, animate } from '#angular/animations';
#Component({
selector: 'app-infoapp',
templateUrl: './info-app.component.html',
styleUrls: ['./info-app.component.css'],
animations: [
trigger('simpleFadeAnimation', [
state('in', style({opacity: 1})),
transition(':enter', [
style({opacity: 0}),
animate(600 )
]),
transition(':leave',
animate(600, style({opacity: 0})))
])
]
})
export class InfoAppComponent implements OnInit {
#Input() selectedArray = [];
constructor() {}
ngOnInit() {}
}
So assuming that I have an Angular 4 component like this:
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
})
export class HomeComponent implements OnInit {
printThisValue = 'customAttr';
constructor(){}
}
How to I print the value inside an HTML tag just like this code seen below:
<div class="myStyle" {{ printThisValue }} ></div>
The HTML code above seems to not work. I'm aware that you are able to print the value like this:
<div class="myStyle">{{ printThisValue }}</div>
// or like this
<div class="myStyle {{ printThisValue }}"></div>
But how do I go about this?
There may be a better / easier way to do this, but you can create a directive that takes the name of the attribute and then sets it on the element.
import { Directive, Input, ElementRef, AfterViewInit } from '#angular/core';
#Directive({
selector: '[customAttr]'
})
export class CustomDirective implements AfterViewInit {
#Input() customAttr;
constructor(private elRef: ElementRef) {}
ngAfterViewInit() {
this.elRef.nativeElement.setAttribute(this.customAttr, true);
}
}
Then you can use it like: <div class="myStyle" [customAttr]="printThisValue"> and it will be emitted with <div class="myStyle" customAttr>.
Check which one can be your solution
Case 1 : Conditional attribute
<div class="myStyle" [attr.attr_name]="condition"></div>
Case 2 : Customized (dynamic) attribute name
HTML (Template)
<div #elem1>
{{ attachAttr }} Hi
</div>
TypeScript of a Sample Component
import { Component, ViewChildren, QueryList, AfterViewInit } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
myAttr = "custom_attr"; // Customize attribute name
attachAttr: any;
#ViewChildren('elem1') elem;
ngAfterViewInit() {
this.elem['first'].nativeElement.setAttribute(this.myAttr,"");
}
}
Output will be
<div custom_attr> Hi </div>
test.component.html
<input type="text" name="fname" [(ngModel)]="user">
<button
class="btn btn-primary">Update Server</button>
test.component.ts
import { Component, OnInit } from '#angular/core';
import { Input } from '#angular/core';
#Component({
selector: 'app-testcomp',
styleUrls: ['./testcomp.component.css']
})
export class TestcompComponent implements OnInit {
constructor() { }
#Input() user:any;
ngOnInit() {
}
}
In the app.component.html
<app-testcomp [user]="ide"></app-testcomp>
<button
(click)="onserclicked()">Clicked</button>
In its ts file
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
ide:any;
onserclicked()
{
alert(this.ide)
}
}
On clicking the button in the app.component.html...it is showing undefined rather than the value which was entered in the text box in the user-component
Comment is right, but u can use other stuff to achieve it.
Delete this input that actually don't needed, leave just
user:any;
Name your component like
<app-testcomp #testcomp></app-testcomp>
<button (click)="onserclicked(testcomp.user)">Clicked</button>
and then all will work.
You need to use the decorator #Output :
app.component.html :
<app-testcomp [user]="ide" (userClick)="onserclicked($event)"></app-testcomp>
<button
(click)="onserclicked()">Clicked</button>
test.component.html
<input type="text" name="fname" [(ngModel)]="user">
<button
class="btn btn-primary" (click)="onChange()">Update Server</button>
test.component.ts
import { Component, OnInit } from '#angular/core';
import { Input } from '#angular/core';
#Component({
selector: 'app-testcomp',
styleUrls: ['./testcomp.component.css']
})
export class TestcompComponent implements OnInit {
constructor() { }
#Input() user:any;
#Output()
userClick: EventEmitter<any> = new EventEmitter<any>();
public onChange(){
this.change.emit();
}
ngOnInit() {
}
}
You could try this. It's working, I guess.
You could this tutorial by Todd Motto to understand all of component events
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