Multiselect Dropdown With Checkbox Angular

Multiselect Dropdown With Checkbox Angular
Project: AngularJS Multi Select Dropdown
Author: darquiza
Edit Online: View on CodePen
License: MIT

Create a powerful multiselect dropdown with checkboxes using AngularJS. This code snippet demonstrates how to implement a versatile multiselect dropdown in AngularJS. With this feature-rich dropdown, users can select multiple options from different categories.

The dropdown dynamically updates the selected options and provides a user-friendly interface. The code utilizes AngularJS controllers, scope variables, and functions to manage the dropdown state and handle user interactions. Enhance your AngularJS applications with this flexible and interactive multiselect dropdown component.

How to Create Multiselect Dropdown With Checkbox Angular

Create the HTML structure for multiselect dropdown as follows:

<section ng-app="myApp" ng-controller="myCtrl">
  <div class="container bg-midnight-100">
    <div class="card">
      <div class="card__header">
        <h2 class="card__title" ng-bind="message"></h2>
      </div>
      <div class="card__body">
        <div class="dropdown">
          <div class="dropdown__label">
            <label title="{{dLabel.opt1}}">
              <input type="checkbox" ng-model="option1">
              <span>{{options.opt1.name}}</span>
              <svg ng-hide="option1" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
                <path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
              </svg>
              <svg ng-show="option1" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
              </svg>
            </label>
          </div>
          <div class="dropdown__menu" ng-show="option1">
            <input type="text" class="dropdown__search" placeholder="Search..." ng-model="searchBox.name">
            <div class="dropdown__select-all">
            <label for="select-all-checkbox1">Select All</label>
            <input ng-model="options.opt1.selected"
                   ng-change="checkAllFn('opt1')"
                   type="checkbox"
                   id="select-all-checkbox1"
                   class="dropdown__checkbox"
            />
          </div>
            <ul class="dropdown__list">
              <li class="dropdown__item" ng-repeat="(key, item) in options.opt1.data | filter: searchBox">
                <input ng-model="item.selected" 
                       type="checkbox" 
                       id="item-{{'opt1' + key}}-checkbox" 
                       class="dropdown__checkbox"
                       ng-change="isItemCheckFn('opt1')"
                       value="{{item.value}}"
                />
                <label for="item-{{'opt1' + key}}-checkbox">{{item.name}}</label>
              </li>
            </ul>
          </div>
        </div>
        <div class="dropdown">
          <div class="dropdown__label">
            <label title="{{dLabel.opt2}}">
              <input type="checkbox" ng-model="option2">
              <span>{{options.opt2.name}}</span>
              <svg ng-hide="option2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
                <path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
              </svg>
              <svg ng-show="option2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
              </svg>
            </label>
          </div>
          <div class="dropdown__menu" ng-show="option2">
            <input type="text" class="dropdown__search" placeholder="Search..." ng-model="searchBox2.name">
            <div class="dropdown__select-all">
            <label for="select-all-checkbox2">Select All</label>
            <input ng-model="options.opt2.selected"
                   ng-change="checkAllFn('opt2')"
                   type="checkbox"
                   id="select-all-checkbox2"
                   class="dropdown__checkbox"
            />
          </div>
            <ul class="dropdown__list">
              <li class="dropdown__item" ng-repeat="(key, item) in options.opt2.data | filter: searchBox2">
                <input ng-model="item.selected" 
                       type="checkbox" 
                       id="item-{{'opt2' + key}}-checkbox" 
                       class="dropdown__checkbox"
                       ng-change="isItemCheckFn('opt2')"
                       value="{{item.value}}"
                />
                <label for="item-{{'opt2' + key}}-checkbox">{{item.name}}</label>
              </li>
            </ul>
          </div>
        </div>
        <div class="dropdown">
          <div class="dropdown__label">
            <label title="{{dLabel.opt3}}">
              <input type="checkbox" ng-model="option3">
              <span>{{options.opt3.name}}</span>
              <svg ng-hide="option3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="w-6 h-6">
                <path strokeLinecap="round" strokeLinejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
              </svg>
              <svg ng-show="option3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
              </svg>
            </label>
          </div>
          <div class="dropdown__menu" ng-show="option3">
            <input type="text" class="dropdown__search" placeholder="Search..." ng-model="searchBox3.name">
            <div class="dropdown__select-all">
            <label for="select-all-checkbox">Select All</label>
            <input ng-model="options.opt3.selected"
                   ng-change="checkAllFn('opt3')"
                   type="checkbox"
                   id="select-all-checkbox3"
                   class="dropdown__checkbox"
            />
          </div>
            <ul class="dropdown__list">
              <li class="dropdown__item" ng-repeat="(key, item) in options.opt3.data | filter: searchBox3">
                <input ng-model="item.selected" 
                       type="checkbox" 
                       id="item-{{'opt3' + key}}-checkbox" 
                       class="dropdown__checkbox"
                       ng-change="isItemCheckFn('opt3')"
                       value="{{item.value}}"
                />
                <label for="item-{{'opt3' + key}}-checkbox">{{item.name}}</label>
              </li>
            </ul>
          </div>
        </div>
      </div>
      <div class="card__footer">
        <p class="card__meta">Posted by John Doe</p>
        <a href="" class="button button__grey" ng-click="getSelected()">Submit</a>
      </div>
    </div>
  </div>
</section>

After that, style the dropdown interface using the following CSS styles:

.cd__main{
   background: #283848 !important;
   min-height: 500px;
}
.bg-midnight-100 {
  background-color: #283848;
}

.bg-midnight-200 {
  background-color: #233240;
}

.bg-midnight-300 {
  background-color: #1f2b38;
}

.bg-midnight-400 {
  background-color: #1a2530;
}

.bg-midnight-500 {
  background-color: #161f28;
}

.bg-midnight-600 {
  background-color: #121920;
}

.bg-midnight-700 {
  background-color: #0d1318;
}

.bg-midnight-800 {
  background-color: #090c10;
}

.bg-midnight-900 {
  background-color: #040608;
}

.container {
  height: 100%;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.card {
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 5px;
  box-shadow: 5px 5px 3px #95a5a6;
  margin-bottom: 20px;
  min-width: 300px;
}
.card__header {
  padding: 20px;
  border-bottom: 1px solid #ccc;
}
.card__title {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
}
.card__body {
  padding: 20px;
}
.card__text {
  margin: 0 0 10px;
  font-size: 16px;
  line-height: 1.5;
}
.card__link {
  display: inline-block;
  color: #007bff;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.2s ease-in-out;
}
.card__link:hover {
  color: #0056b3;
}
.card__footer {
  padding: 20px;
  border-top: 1px solid #ccc;
  display: flex;
  align-items: center;
}
.card__footer :last-child {
  margin-left: auto;
}
.card__meta {
  margin: 0;
  font-size: 14px;
  color: #999;
}

.dropdown {
  position: relative;
  display: inline-block;
  width: 150px;
}
.dropdown__select-all {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #ccc;
}
.dropdown__menu {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  background-color: #fff;
  border: 1px solid #ccc;
  z-index: 1;
  display: block;
}
.dropdown__menu--open {
  display: block;
}
.dropdown__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.dropdown__item {
  display: flex;
  align-items: center;
  padding: 10px;
}
.dropdown__checkbox {
  margin-right: 10px;
}
.dropdown__search {
  box-sizing: border-box;
  width: 100%;
  border: none;
  border-bottom: 1px solid lightgrey;
  padding: 0.625rem;
}
.dropdown__label label {
  padding: 0.5rem;
  border: 1px solid black;
  border-radius: 4px;
  margin-bottom: 0.5rem;
  display: flex;
  gap: 0.5rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dropdown__label input {
  display: none;
  visibility: hidden;
}
.dropdown__label svg {
  margin-left: auto;
  width: 1rem;
}
.dropdown:hover .dropdown__menu {
  display: block;
}

.button {
  padding: 0.5rem;
  border: 1px solid #eeeeee;
  color: #111111;
  border-radius: 0.5rem;
}
.button__grey {
  text-decoration: none;
  background-color: #d2d7d3;
}

Now, load the AngularJS by adding the following CDN link before closing the body tag:

<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.3/angular.min.js'></script>

Finally, add the following JavaScript function to activate the multiselect dropdowns:

var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $httpParamSerializer) {
  $scope.message = "AngularJS Multi Select Dropdown";
  
  $scope.options = {
    opt1: {
      name: 'Animals',
      selected: false,
      data: [
        { value: 100, selected: false, name: "Lion" },
        { value: 101, selected: false, name: "Tiger" },
        { value: 102, selected: false, name: "Bear" },
        { value: 103, selected: false, name: "Rhinoceros" }
      ]
    },
    opt2: {
      name: 'Types',
      selected: false,
      data: [
        { value: 200, selected: false, name: "Mammals" },
        { value: 201, selected: false, name: "Birds" },
        { value: 203, selected: false, name: "Reptiles" },
        { value: 204, selected: false, name: "Amphibians" }
      ]
    },
    opt3: {
      name: 'Skills',
      selected: false,
      data: [
        { value: 300, selected: false, name: "Camouflage" },
        { value: 301, selected: false, name: "Hunting" },
        { value: 303, selected: false, name: "Tool Use" },
        { value: 304, selected: false, name: "Echolocation" }
      ]
    }
  };
  
  $scope.optionsCopy = angular.copy($scope.options);
  
  $scope.dLabel = {};
  
  $scope.checkAllFn = function(opt) {
    let labels = [];
    $scope.options[opt].name = $scope.options[opt].selected ? 'All' : $scope.optionsCopy[opt].name;
    angular.forEach($scope.options[opt].data, function(item) {
      item.selected = $scope.options[opt].selected;
      labels.push(item.name);
    });
    $scope.dLabel[opt] = labels;
  };
  
  $scope.isItemCheckFn = function(opt) {
    let allChecked = true;
    let checkCount = 0;
    let setName = '';
    let labels = [];
    angular.forEach($scope.options[opt].data, function(item) {
      if (!item.selected) {
        allChecked = false;
      } else {
        checkCount++;
        setName = item.name;
        labels.push(setName);
      }
      $scope.dLabel[opt] = labels;
    });
    if (checkCount == 1) {
      $scope.options[opt].name = setName;
    } else {
      $scope.options[opt].name = checkCount + ' selected';
    }
    if (allChecked == true) {
      $scope.options[opt].name = 'All';
    }
    if (checkCount == 0) {
      $scope.options[opt].name = $scope.optionsCopy[opt].name;
    }
    $scope.options[opt].selected = allChecked;
  };
  
  $scope.getSelected = function() {
    let selectedValues = {};
    angular.forEach($scope.options, function (option, key) {
      let setData = [];
      angular.forEach(option.data, function (data, index) {
        if (data.selected) {
          setData.push(data.value);
        }
      });
      selectedValues[$scope.optionsCopy[key].name] = setData;
      // selectedValues[key] = setData;
    });
    $scope.paramString = $httpParamSerializer(selectedValues);
    console.log(selectedValues);
    console.log($scope.paramString);
    // $scope.updateOptionState($scope.paramString);
  };
  
  $scope.urlParamToArray = function(paramString) {
    let paramPairs = paramString.split('&');
    let paramObj = {};
    for (let i = 0; i < paramPairs.length; i++) {
      let pair = paramPairs[i].split('=');
      let key = decodeURIComponent(pair[0]);
      let value = decodeURIComponent(pair[1]);
      if (!paramObj[key]) {
        paramObj[key] = [];
      }
      paramObj[key].push(value);
    }
    return paramObj;
  }
  
  $scope.updateOptionState = function(url) {
    let urlParam = $scope.urlParamToArray(url);
    console.log(urlParam);
  }

});

That’s all! hopefully, you have successfully created multiselect dropdown with checkboxes using AngularJS. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply