0

I'm learning Angular and have a small test component (Angular 9 - fresh install using CLI).

I have two inputs and am trying to associate each label to its input by putting the id in the 'for' attribute (I know you could also wrap the field in the label). This works for the first input; clicking on the label will set focus to the input. However, clicking on the second label will also set focus to the first input. It doesn't matter if I swap the position of the inputs, the behavior is the same.

Why would this be? Is there a better way to do this in general? I feel like I'm missing something.

restool.component.html

<div>
    <label [for]="origin">Origin</label>
    <input [formControl]="origin" [attr.id]="origin">
</div>
<div>
    <label [for]="destination">Destination</label>
    <input [formControl]="destination" [attr.id]="destination">
</div>

restool.component.ts

import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-restool',
  templateUrl: './restool.component.html',
  styleUrls: ['./restool.component.css']
})
export class RestoolComponent implements OnInit {

  origin = new FormControl('');
  destination = new FormControl('');

  constructor() {

   }

  ngOnInit(): void {
  }

}
Roobot
  • 860
  • 1
  • 10
  • 20

1 Answers1

1

Try using stock HTML, it could be that destination and origin are object types.

<div>
    <label for="origin">Origin</label>
    <input [formControl]="origin" id="origin">
</div>
<div>
    <label for="destination">Destination</label>
    <input [formControl]="destination" id="destination">
</div>
AliF50
  • 16,947
  • 1
  • 21
  • 37
  • That does work for this simple scenario. But most examples I see have this done dynamically. If I built components this way wouldn't I be leaking IDs into the global scope that could potentially conflict with other components? I thought this was one of the good things about Angular components - that they were very self-contained. – Roobot Feb 26 '20 at 18:12
  • Well, there are always ways in getting around your concern. For instance, if you plan on reusing this component over and over, you can take `@Input() originId` (do the same for destinationId) and pass in a unique id here every time (related to an id from an API or the index of the loop). If you're not planning on reusing this component over and over, you can change the id to `RestoolComponentDestination` and `RestToolComponentOrigin` if you're scared you're going to have `origin` and `destination` as an ID in a different component (very slim chance of this happening as well). – AliF50 Feb 26 '20 at 18:18
  • It just seems odd that to have unique IDs, I have to either force the parent to pass in something unique (and even if it's unique there, what about elsewhere?), or guess at an ID that will be unique for the whole HTML doc. I found talk about this here (https://github.com/angular/angular/issues/5145) and here (https://stackoverflow.com/questions/60114682/how-to-access-components-unique-encapsulation-id-in-angular-9). Maybe the idea is to avoid using IDs, but sometimes you have to (aria attributes for accessibility). I'll accept this but I'm still wondering about the best way to handles IDs. – Roobot Feb 26 '20 at 19:29