Friday 3 November 2017

Multiselect checkbox dropdown component using Angular

Here I am going to explain about creating a simple multi select checkbox dropdown component using angular. This component can reuse by adding anywhere in the application. Let check with working example.


<multi-selector-dropdown
 [list]="list"
 (shareCheckedList)="shareCheckedList($event)" 
 (shareIndividualCheckedList)="shareIndividualCheckedList($event)">
</multi-selector-dropdown>

Above one is our component representation. Here list is nothing but the data that required to show in the drop down. shareCheckedList will provide the checked list information in the parent controller and shareIndividualCheckedList will provide individual status of selected item.

Let us create a component there we will be adding our drop down component.


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

@Component({
  selector: 'app-root',
  template: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
 
  list : any[];
  
  constructor(){
    this.list = 
      [
        {name :'India',checked : false},
        {name :'US',checked : false},
        {name :'China',checked : false},
        {name :'France',checked : false}
      ]
  }
}

and html


<multi-selector-dropdown
 [list]="list"
 (shareCheckedList)="shareCheckedList($event)" 
 (shareIndividualCheckedList)="shareIndividualCheckedList($event)">
</multi-selector-dropdown>

Above list will be using for creating our drop down. Now check multi drop down checkbox component.

Multi drop down checkbox component


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

@Component({
    selector :'multi-selector-dropdown',
    templateUrl :'./multiSelectDropdown.html',
    styleUrls : ['./app.component.css']
})

export class MultiSelectDropdown{
    @Input() list:any[]; 
    
    @Output() shareCheckedList = new EventEmitter();
    @Output() shareIndividualCheckedList = new EventEmitter();
    
    
    checkedList : any[];
    currentSelected : {};
    
    constructor(){
        this.checkedList = [];
    }
    getSelectedValue(status:Boolean,value:String){
        if(status){
          this.checkedList.push(value);  
        }else{
            var index = this.checkedList.indexOf(value);
            this.checkedList.splice(index,1);
        }
        
        this.currentSelected = {checked : status,name:value};

        //share checked list
        this.shareCheckedlist();
        
        //share individual selected item
        this.shareIndividualStatus();
    }
    shareCheckedlist(){
         this.shareCheckedList.emit(this.checkedList);
    }
    shareIndividualStatus(){
        this.shareIndividualCheckedList.emit(this.currentSelected);
    }
}

./multiSelectDropdown.html


<div>
    <h3>Multi select dropdown</h3>
    <div (mouseleave)="showDropDown = false">
        <button class="drop-toggle btn flat" (click)="showDropDown=!showDropDown">
            <span *ngIf="checkedList.length<=0">Select</span>
            <span *ngIf="checkedList.length>0">{{checkedList.join(', ')}}</span>
            <i class="fa fa-angle-down"></i>
        </button>
        <div class="drop-show" *ngIf="showDropDown">
            <label *ngFor="let a of list">
                <input type="checkbox" [(ngModel)]="a.checked" 
                    (change)="getSelectedValue(a.checked,a.name)" />
                <span>{{a.name}}</span>
            </label>
        </div>
    </div>
</div>

Here we have used EventEmitter, @input and @output method to share and receive the data. You can read this article for know more about sharing data between components.

Updated parent component


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

@Component({
  selector: 'app-root',
  template: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
 
  list : any[];
  
  constructor(){
    this.list = 
      [
        {name :'India',checked : false},
        {name :'US',checked : false},
        {name :'China',checked : false},
        {name :'France',checked : false}
      ]
  }
  shareCheckedList(item:any[]){
    console.log(item);
  }
  shareIndividualCheckedList(item:{}){
    console.log(item);
  }
}

We just updated our parent component to receive the data from drop down component.

In case anyone interested in css for the above drop down, here it is,

CSS


/***
    css for multi select drop down
**/
.drop-toggle{
    background-color: #fff;
    border: none;
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
    cursor: hand;
    border: 1px solid #ccc;
    width: 233px;
    text-align: left;
}
.drop-toggle i{
    float:right;
}
.drop-show {
    padding: 4px;
    width: 222px;
    background-color: #FFF;
    border: 1px solid #BABABA;
    position: absolute;
    z-index: 100;
    -webkit-box-shadow: 0 6px 10px rgba(0,0,0,.15);
    -moz-box-shadow: 0 6px 10px rgba(0,0,0,.15);
    box-shadow: 0 6px 10px rgba(0,0,0,.15);
    margin-left: 1px;
}
.drop-show label{
    display:block;
    font-size:15px;
    cursor: pointer;
}
.drop-show label input{
    vertical-align: top;
}
.drop-show label span{
    display:inline-block;
}

Demo

We are done, don’t forget to import the dependencies in your module. In this article we have discussed about creating a multi select checkbox drop down component using Angular, which can reuse any where in your module.

Related Info

1. How to show a date is today or yesterday or last week etc using pipe - Angular

2. Disable submit button until all mandatory fields are filled - Angular

3. Angular client side pagination.

4. Angular show more/less pagination

7 comments :

  1. Thanks a ton! Works like a charm :)

    ReplyDelete
  2. This was one of the best documented, functional pieces of Angular code that I have been able to find. My only questions is, if I want to feed the drop down with data from my back-end database through the API, can you help modify this for that use case?

    ReplyDelete
    Replies
    1. You can bind your backend data to this.list, if the API calls are done in the parent component, then input the value to this component.
      7 method to share data - http://www.angulartutorial.net/2017/12/share-data-between-angular-components.html

      http://www.angulartutorial.net/2017/11/http-calls-in-angular-with-simple.html

      Delete
  3. it is showing error of showDropDown property and not working.

    ReplyDelete
    Replies
    1. You'd need to add it to this variable as a boolean type typescript file associated to the html.

      Delete
  4. very nice work, thanks it works perfectly ;)

    ReplyDelete
  5. I spent so much time trying to get s plugin for multi select dropdown, and when I was about give up I came across this page. It worked like charm and I was even able to modify it for my purpose with no trouble at all. I can't be more thankful for it! I greatly appreciate your work. Thanks a lot!!!

    ReplyDelete