Context
I'm writing a custom Angular component for a checkbox. The component renders a checkbox tag along with a label tag. The "id" attribute of the checkbox and the "for" attribute of the label are both set to the component's id
property (an @Input
to the component) to ensure that clicking the label will toggle the checkbox. A simplified version of the template looks like:
<div class="checkbox">
<input type="checkbox" [id]="id" />
<label [for]="id"><ng-content></ng-content></label>
</div>
Problem
When I set an "id" prop on my component (e.g. <my-checkbox id="hello">Check me</my-checkbox>
), an "id" attribute is automatically set on the component wrapper tag in the DOM. This results in duplicate ids in the DOM because I'm already setting an "id" attribute on the checkbox inside the component. This is invalid and breaks the browser's default toggle-by-clicking-the-label behavior. The DOM output is:
<my-checkbox id=“my-checkbox” ng-reflect-id=“my-checkbox” ng-reflect-checked="true">
<div ng-reflect-ng-class="[object Object]" class="checkbox">
<input class="checkbox__element" type="checkbox" name="fire_missiles" ng-reflect-id=“my-checkbox” id=“my-checkbox” value=“fire_missiles” ng-reflect-checked="true">
<label class="checkbox__label" ng-reflect-html-for=“my-checkbox” for=“my-checkbox”>
Fire missiles?
</label>
</div>
</my-checkbox>
Is there a way to either a) get rid of the garbage container tag or b) stop the automatic reflection of the "id" prop onto the container as an attribute?
NOTE: Using an attribute selector applied to something like a div doesn't help, it just moves the extra "id" from <my-checkbox />
to the div.
I would simply rename the checkbox's id (and hence the label's
for
attribute) so that it doesn't clash with the component's id, like so: