Search code examples
javascriptangularangular2-formsangular2-components

Binding for attribute Angular 2 doesn't update associated input with bound id


I have a checkbox within my component with bindings like so:

<input type="checkbox" [name]="name" [id]="id" /><label [htmlFor]="id"></label>

When the component loads I can inspect the element and find that the values passed to those inputs are bound, but when I click the label the checkbox doesn't get checked.

I've also tried it like so:

<input type="checkbox" [attr.name]="name" [attr.id]="id" /><label [attr.for]="id"></label>
<input type="checkbox" name="{{name}}" id="{{id}} /><label [attr.for]="id"></label>

And combinations thereof. They all produce the same effect, data is bound, checkbox not checked.

Here is my component:

import { Component } from '@angular/core';

@Component({
  inputs: ['name', 'id'],
  selector: 'my-checkbox',
  templateUrl: 'app/form/input/checkbox.component.html'
})

export class CheckboxComponent {}

And the html where it's used:

<my-checkbox name="test-name" id="test-id"></my-checkbox>

Solution

  • When you are using id as input name, you get your component as dom-element with this id. It adds same id to the checkbox, and for of the label. But when you have multiple elements with same id, label refers to first of them. In your case it refers you component instead of input.

    Just rename input parameter.

    By the way, it would've be right to declare corresponding field in ts class.

    http://plnkr.co/edit/JazXV3Oi91hSBTdVlBHh?p=preview

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'my-app',
      template: `
          <my-checkbox-broken id="test-id-1"></my-checkbox-broken><br>
          <my-checkbox-broken [id]="'test-id-2'"></my-checkbox-broken> can work too<br>
          <my-checkbox-working chkId="test-id-3"></my-checkbox-working><br>
          <output></output>
      `
    })
    export class AppComponent {
    }
    
    @Component({
      inputs: ['id'],
      selector: 'my-checkbox-broken',
      template: '<input type="checkbox" [id]="id" /><label [htmlFor]="id">Broken :(</label>'
    })
    export class CheckboxComponent_Broken {
      id: string;
    }
    
    @Component({
      inputs: ['chkId'],
      selector: 'my-checkbox-working',
      template: '<input type="checkbox" [id]="chkId" /><label [htmlFor]="chkId">Working!</label>'
    })
    export class CheckboxComponent_Working {
      chkId: string;
    }
    
    document.addEventListener('click', ({ target: { htmlFor: id } }) => {
      if (id) {
        document.querySelector('output').textContent = id + " is " + document.getElementById(id).tagName;
      }
    })