I have a text field in an ponent, that when in focus, needs to populate a hidden field outside of the ponent that is nearest to it.
At the moment I can get the field in focus, but what I need to do now is populate the hidden field.
Here is what I have so far:
HTML:
<h2>Test</h2>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
App-Focus:
<p>
focus works!
<input id="inputId" type="text" name="" value="">
</p>
Component:
ngAfterViewInit(){
setTimeout(()=>{
let dummyEl = this.elRef.nativeElement.querySelectorAll("#inputId")
for(let i = 0; i < dummyEl.length; i++){
let el = dummyEl[i]
// if (document.activeElement === el){ stops working if I use this
console.log(document.activeElement === el)
console.log(el.closest("#h0"))//always returns null
// }
}
}, 3000)
}
I have a text field in an ponent, that when in focus, needs to populate a hidden field outside of the ponent that is nearest to it.
At the moment I can get the field in focus, but what I need to do now is populate the hidden field.
Here is what I have so far:
HTML:
<h2>Test</h2>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
<input type="hidden" id="h0" name="" value="">
<app-focus></app-focus>
App-Focus:
<p>
focus works!
<input id="inputId" type="text" name="" value="">
</p>
Component:
ngAfterViewInit(){
setTimeout(()=>{
let dummyEl = this.elRef.nativeElement.querySelectorAll("#inputId")
for(let i = 0; i < dummyEl.length; i++){
let el = dummyEl[i]
// if (document.activeElement === el){ stops working if I use this
console.log(document.activeElement === el)
console.log(el.closest("#h0"))//always returns null
// }
}
}, 3000)
}
Share
Improve this question
asked Apr 7, 2018 at 13:58
RasMasonRasMason
2,2125 gold badges36 silver badges60 bronze badges
1
- Is it just for demonstration reasons or do all your input fields have the same id 'h0'? If so, this could be the reason why the result is null as there is no unique field to return. – user6749601 Commented Apr 7, 2018 at 15:38
2 Answers
Reset to default 4closest
searches direct descendants but not siblings of the descendants e.g.
<div>
<input id="#h0">
<app-root>
<p>
<input id="#inputId">
</p>
</app-root>
</div>
In this HTML, calling closest
from the #inputId
element will only find the div
, not the input
because it is not a direct descendant - it is a child of div
.
You need to modify your html so app-root
and #h0
are wrapped by a div
. You can then find the closest div and select the child of that element e.g.
ngAfterViewInit() {
setTimeout(() => {
let dummyEl = this.elRef.nativeElement.querySelectorAll('#inputId');
for(let i = 0; i < dummyEl.length; i++) {
let el = dummyEl[i];
let div = el.closest('div');
if(div !== null) {
console.log(div.querySelector('#h0'));
}
}
}, 3000);
}
}
Also you id
's must be unique so using #h0
for each input is invalid HTML. You might be better using a class if you want to find the elements with the same "tag" e.g.
<input class="h0" ... >
If you need to pass data from the AppFocusComponent
, you could use Angular Event Emitters. The example in the documentation emits null
in the $event
but other data, both primitive and Objects, can be passed as well.
Here is a link to an example on Stack Blitz
app-focus.ponent.ts
First, set up an EventEmitter
in the AppFocusComponent
. The data can be emitted in an Angular Lifecycle Hook. Or can be bound to a User Input Event.
import { AfterViewInit, Component, EventEmitter, Input, Output } from
'@angular/core';
@Component({
selector: 'app-focus',
templateUrl: './app-focus.ponent.html'
})
export class AppFocusComponent implements AfterViewInit {
@Input() data: any = null;
@Output() focus = new EventEmitter();
ngAfterViewInit() {
setTimeout(()=>{
this.focus.emit(this.data);
}, 3000)
}
onFocus(event: Event) {
console.log(event);
this.focus.emit(this.data);
}
}
app-focus.ponent.html
Next, bind the focus
event on the input to the onFocus()
method in the ponent. Here, ngModel
is used to bind the data that is emitted when the onFocus($event)
method fires. This can either be from user input, or the data can be passed in via an @Input()
. I wasn't sure where the data is ing from, so there a couple of approaches in the example.
<p>
<input type="text" (focus)="onFocus()" [(ngModel)]="data">
</p>
app.ponent.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.ponent.html',
styleUrls: [ './app.ponent.css' ]
})
export class AppComponent {
h0Value: string = '';
h1Value: string = '';
h2Value: string = '';
h3Value: string = '';
// an alternate way to set the value instead of setting it in the template
setH1Value(event: any) {
this.h1Value = event;
}
}
app.ponent.html
Lastly, bind the [value]
of the <input>
s to their respective properties and have the AppComponent
listen to the (focus)
event from the AppFocusComponent
. The data that es from the AppFocusComponent
can be assigned directly in the template. (focus)="h0Value = $event"
. Or it can be wrapped in a method on the ponent while passing the $event
through. (focus)="setH1Value($event)"
. If the data is being initialized via data from an API or some other source, it can be passed in via the @Input
. data="h2 data"
.
The labels here are used for demonstration purposes so the data that's emitted by the AppFocusComponent
can be viewed in the UI.
<h2>Test</h2>
<label>{{ h0Value }}</label>
<input type="hidden" id="h0" name="" [value]="h0Value">
<app-focus (focus)="h0Value = $event"></app-focus>
<label>{{ h1Value }}</label>
<input type="hidden" id="h1" name="" [value]="h1Value">
<app-focus (focus)="setH1Value($event)"></app-focus>
<label>{{ h2Value }}</label>
<input type="hidden" id="h2" name="" [value]="h2Value">
<app-focus data="h2 data" (focus)="h2Value = $event"></app-focus>
<label>{{ h3Value }}</label>
<input type="hidden" id="h3" name="" [value]="h3Value">
<app-focus (focus)="h3Value = $event"></app-focus>