1

I'm using Angular2 and Semantic UI and I want to create a multiple selection component with checkbox like this https://jsfiddle.net/jp8xj0wk/2/, but when I iterate with *ngFor the checkbox doesn't work, but if I insert manually checkbox items only these work fine.

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

declare var $: any;

@Component({
  selector: 'combo-multiple',
  template: `
  <div class="ui basic right labeled dropdown icon button">
    <i class="dropdown icon"></i>
    <span class="ui tiny header">Items</span>
    <div class="menu">
      <div class="ui icon search input">
        <i class="search icon"></i>
        <input type="text" name="search" placeholder="Search...">
      </div>
      <div class="scrolling menu">
        <!-- Checkbox inserted manually works fine -->
        <div class="ui checkbox item" data-value="item -1">
          <input type="checkbox" name="item-1">
          <label>item-1</label>
        </div>
        <div class="ui checkbox item" data-value="item 0">
          <input type="checkbox" name="item0">
          <label>item0</label>
        </div>
        <!-- End. Checkbox inserted manually works fine -->


        <!-- checkbox with ngFor doesn't work -->
        <div class="ui checkbox item" *ngFor="let item of items" [attr.data-value]="item">
          <input type="checkbox" name="{{item}}">
          <label>{{item}}</label>
        </div>
      </div>
    </div>
  `
})
export class ComboMultiple implements OnInit {
  items: string[];
  constructor() {}

  ngOnInit() {
    this.items = ["Item 1","Item 2","Item 3"];
    $('.ui.checkbox').checkbox();
    $('.ui.dropdown').dropdown({action:'nothing'});
  }
}

1 Answer 1

1

this a good usecase for component lifecycle hooks, I'm going to add a button to your component to illustrate the solution. This new button will add a new element to the array, nothing more.

here is a working plunker: https://plnkr.co/edit/K5MWKzfCFjGmeOzYYxIJ?p=preview

the main thing here, is you add the array on or before ngOnInit and you initialize the checkbox and the select in AfterViewChecked

this way, every time there is a change (such as adding a new element to array). When Angular is done rendering the view it calls AfterViewChecked, where we init the select and checkbox.

@Component({
  selector: 'combo-multiple',
  template: `
  <div class="ui basic right labeled dropdown icon button">
    <i class="dropdown icon"></i>
    <span class="ui tiny header">Items</span>
    <div class="menu">
      <div class="ui icon search input">
        <i class="search icon"></i>
        <input type="text" name="search" placeholder="Search...">
      </div>
      <div class="scrolling menu">
        <!-- Checkbox inserted manually works fine -->
        <div class="ui checkbox item" data-value="item -1">
          <input type="checkbox" name="item-1">
          <label>item-1</label>
        </div>
        <div class="ui checkbox item" data-value="item 0">
          <input type="checkbox" name="item0">
          <label>item0</label>
        </div>
        <!-- End. Checkbox inserted manually works fine -->


        <!-- checkbox with ngFor doesn't work -->
        <div class="ui checkbox item" *ngFor="let item of items" [attr.data-value]="item">
          <input type="checkbox" name="{{item}}">
          <label>{{item}}</label>
        </div>
      </div>
    </div>
  </div>
    <!-- NEW BUTTON -->
    <button (click)="addItem()">add new</button>
  `
})
export class ComboMultiple implements OnInit, AfterViewInit, AfterViewChecked {
  items: string[];
  constructor() {}

  ngOnInit(){
    // add those three items on initialization of component.
    this.items = ["Item 1","Item 2","Item 3"];
  }

  // when called, adds a new item to the array
  addItem(){
    this.items.push("new item")
  }

  // when called, will initialize all dropdown and all checkboxes.
  initializeDropdown(){
    $('.ui.checkbox').checkbox();
    $('.ui.dropdown').dropdown({action:'nothing'});
  }
  // Called after the ngAfterViewInit and every subsequent ngAfterContentChecked().
  ngAfterViewChecked() {
    this.initializeDropdown();
  }
}
Sign up to request clarification or add additional context in comments.

9 Comments

Hi, thanks for the help, but it doesn't work. I have the same result for ngOnInit and ngAfterViewInit.
ok, literally copy pasted your code to this plunkr: plnkr.co/edit/sW12Fn3FFCWmxYkznWAO?p=preview. works just fine..
Try to select some of the iteration items and you will see that won't work, those items are not clickable. Meanwhile i put some css in the checkbox width:100% and height: 100%;
ahh, I see it now
by the way, I added the style in your plunker and it works, but it would be great find some more elegant solution.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.