Search code examples
angularkendo-uiangular7

Angular Checkbox in *ngFor


I'm using KendoUI with Angular7 and am trying to get a dynamic list of checkboxes with bound check state. Here is the basic html for this list:

  <div *ngFor="let option of RoleOptions">
    <input type="checkbox" class="k-checkbox" [(ngModel)]="option.Selected" style="width: auto">
    <label class="dialogLabels k-checkbox-label">{{option.Role.Name}}</label>
  </div>

This displays just fine and I get a stacked list of checkboxes with the various names in the label, but I can't check anything. I also have some logic that pre-checks certain ones and I can set that at will and it properly reflects the check state of the boxes when it comes up, but still won't let me change it.

I also have this line above it:

<input type="checkbox" class="k-checkbox" [(ngModel)]="NewUserSendEmail" id="cbEmail" style="width: auto">
<label class="dialogLabels k-checkbox-label" for="cbEmail"> Email login data to the user</label>

That works fine, lets me bind, and lets me check, etc. I can only see 2 differences.

First, the ones in the ngfor don't have an id for the label to associate with or anything else to find. However, I didn't find anything that an id is required and there are many examples on the Kendo page that show examples of checkboxes without ids so I don't think that's the issue (but certainly could be wrong).

Second, they are in the ngFor loop. I don't know why this would mess it up but it's all I can think of. I googled around but couldn't find anything about an issue here or how to fix it.

Any ideas where I'm going wrong or what I'm not seeing? I did log the objects that it's binding to and the value is true/false (not null or undefined) so that shouldn't be an issue. Not sure where else to look...

EDIT

After a little more research, this is definitely something to do with the Kendo style. If I do it like this:

    <div *ngFor="let option of RoleOptions">
      <label class="dialogLabels">
        <input type="checkbox" [(ngModel)]="option.Selected" style="width: auto">
        {{option.Role.Name}}</label>
    </div>

It works, but obviously doesn't have the Kendo look. How can I get a dynamic list of checkboxes with the same look as the rest of the app?


Solution

  • Ok so I'm still not sure why this wasn't working the way I had it; regardless of what I did (even copying styles) it didn't seem to respond to the click and change the check state. However, after a little help from Telerik/Progress I found another way to do it that's working.

    The checkbox that is outside the *ngfor and is working uses the id attribute and the label's 'for' attribute to associate. I originally didn't see a way to do that with dynamically generated objects because the id can't be static or you have a bunch of items with the same id. I did try using a {{}} biding to make the id unique but it didn't work. However I found there is an [id] binding that does work. I then found the [htmlFor] binding for the label. Using these in combination seems to work properly.

    So my final code is:

    <div *ngFor="let option of RoleOptions">
        <input type="checkbox" class="k-checkbox" [(ngModel)]="option.Selected" style="width: auto" [id]="option.Role.Id">
        <label class="dialogLabels k-checkbox-label" [htmlFor]="option.Role.Id">{{option.Role.Name}}</label>
    </div>
    

    Hopefully it helps someone else. If anyone has any other ideas on why the first system wasn't working I would be interested to know...