39

I want to create a multiple selection dropbox list. Actually I have to select more than one option using a dropdown menu. When I simply do this as shown below:

    <select>
     <option><input type="checkbox"></option>
    </select>

Then checkbox is showing in front of dropdown field. But I want to create it for each option not for as a whole so that I can select more than one option. Is there any way to do this?

Vivek Kumar
  • 1,204
  • 4
  • 15
  • 35
  • 1
    Yes you can do this. I think you can use some libraries for this. This is [dropdown-check-list](https://code.google.com/p/dropdown-check-list/) one which you can use. You can also find the [test cases here](http://dropdown-check-list.googlecode.com/svn/trunk/doc/ddcl-tests.html). – Rahul Tripathi Oct 06 '13 at 08:34

9 Answers9

57

Here is a simple dropdown checklist:

var checkList = document.getElementById('list1');
checkList.getElementsByClassName('anchor')[0].onclick = function(evt) {
  if (checkList.classList.contains('visible'))
    checkList.classList.remove('visible');
  else
    checkList.classList.add('visible');
}
.dropdown-check-list {
  display: inline-block;
}

.dropdown-check-list .anchor {
  position: relative;
  cursor: pointer;
  display: inline-block;
  padding: 5px 50px 5px 10px;
  border: 1px solid #ccc;
}

.dropdown-check-list .anchor:after {
  position: absolute;
  content: "";
  border-left: 2px solid black;
  border-top: 2px solid black;
  padding: 5px;
  right: 10px;
  top: 20%;
  -moz-transform: rotate(-135deg);
  -ms-transform: rotate(-135deg);
  -o-transform: rotate(-135deg);
  -webkit-transform: rotate(-135deg);
  transform: rotate(-135deg);
}

.dropdown-check-list .anchor:active:after {
  right: 8px;
  top: 21%;
}

.dropdown-check-list ul.items {
  padding: 2px;
  display: none;
  margin: 0;
  border: 1px solid #ccc;
  border-top: none;
}

.dropdown-check-list ul.items li {
  list-style: none;
}

.dropdown-check-list.visible .anchor {
  color: #0094ff;
}

.dropdown-check-list.visible .items {
  display: block;
}
<div id="list1" class="dropdown-check-list" tabindex="100">
  <span class="anchor">Select Fruits</span>
  <ul class="items">
    <li><input type="checkbox" />Apple </li>
    <li><input type="checkbox" />Orange</li>
    <li><input type="checkbox" />Grapes </li>
    <li><input type="checkbox" />Berry </li>
    <li><input type="checkbox" />Mango </li>
    <li><input type="checkbox" />Banana </li>
    <li><input type="checkbox" />Tomato</li>
  </ul>
</div>
ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Arun Aravind
  • 1,238
  • 10
  • 9
  • 1
    Can you visible dropdown list when user click outside? – Hà Tây Quê Rượu Jan 21 '15 at 04:08
  • 1
    You want to hide it? Thats what you mean ryt? If so I have made some changes. Put a tabindex on the container and capture its blur event. This is the one of the cheapest ways of making things work. You could do this using css3 only. Or you could attach an event listener on document element. – Arun Aravind Feb 03 '15 at 15:49
  • 12
    This is great, but it doesn't work in the latest version of chrome. You need to change your display style. See: http://jsfiddle.net/evfnLn0x/ – j03m Feb 12 '15 at 19:55
  • 1
    Hi, This is not working in IE9. Is there any chance to make it work in IE9? – user318197 Aug 18 '15 at 13:59
  • 1
    Anyone looking to close the dropdown on outside click: checkList.addEventListener('blur', function(e) { if(!e.relatedTarget || !e.relatedTarget.classList.contains('anchor')) { checkList.setAttribute("class", "dropdown-check-list"); } }); – DARK_C0D3R Oct 18 '22 at 08:20
  • Note that this answer (and others below it) is not accessible, it lacks keyboard navigation, correct focus management, ARIA roles and states etc. For an accessible multi-select see this article by Sarah Higley: https://www.24a11y.com/2019/select-your-poison-part-2/ – clhenrick Jan 07 '23 at 17:41
25

This can't be done in just HTML (with form elements into option elements).

Or you can just use a standard select multiple field.

<select multiple>
  <option value="a">a</option>
  <option value="b">b</option>
  <option value="c">c</option>
</select>
Michael M.
  • 10,486
  • 9
  • 18
  • 34
Jivings
  • 22,834
  • 6
  • 60
  • 101
16

var expanded = false;

function showCheckboxes() {
  var checkboxes = document.getElementById("checkboxes");
  if (!expanded) {
    checkboxes.style.display = "block";
    expanded = true;
  } else {
    checkboxes.style.display = "none";
    expanded = false;
  }
}
.multiselect {
  width: 200px;
}

.selectBox {
  position: relative;
}

.selectBox select {
  width: 100%;
  font-weight: bold;
}

.overSelect {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}

#checkboxes {
  display: none;
  border: 1px #dadada solid;
}

#checkboxes label {
  display: block;
}

#checkboxes label:hover {
  background-color: #1e90ff;
}
<form>
  <div class="multiselect">
    <div class="selectBox" onclick="showCheckboxes()">
      <select>
        <option>Select an option</option>
      </select>
      <div class="overSelect"></div>
    </div>
    <div id="checkboxes">
      <label for="one">
        <input type="checkbox" id="one" />First checkbox</label>
      <label for="two">
        <input type="checkbox" id="two" />Second checkbox</label>
      <label for="three">
        <input type="checkbox" id="three" />Third checkbox</label>
    </div>
  </div>
</form>
Naveen
  • 361
  • 2
  • 10
16

I have to say in advance that I was greatly inspired by the answer of Naveen so I created my own solution based on the answer.

Following 3 functions are the basis of our multiselect:

  • initiazation function - detects when user clicks away in order to close the dropdown
  • function that detects when user clicks on dropdown to uncollapse it
  • function that detects checkbox click events to update the label

few improvements include:

  • design as in bootstrap 5
  • collapse when clicking away
  • updating the label with list of values
  • added Y-axis overflow with scrollbar

also I tried to stick to native JS (no jQuery) and to use as much of a native Bootstrap 5 styling as possible

here is the video:

enter image description here

I had no intentions to make a ready to use solution that would suit every persons' needs so please adjust it to your liking. I am personally looking forward to adding a search feature.

fiddle:

window.onload = (event) => {
  initMultiselect();
};

function initMultiselect() {
  checkboxStatusChange();

  document.addEventListener("click", function(evt) {
    var flyoutElement = document.getElementById('myMultiselect'),
      targetElement = evt.target; // clicked element

    do {
      if (targetElement == flyoutElement) {
        // This is a click inside. Do nothing, just return.
        //console.log('click inside');
        return;
      }

      // Go up the DOM
      targetElement = targetElement.parentNode;
    } while (targetElement);

    // This is a click outside.
    toggleCheckboxArea(true);
    //console.log('click outside');
  });
}

function checkboxStatusChange() {
  var multiselect = document.getElementById("mySelectLabel");
  var multiselectOption = multiselect.getElementsByTagName('option')[0];

  var values = [];
  var checkboxes = document.getElementById("mySelectOptions");
  var checkedCheckboxes = checkboxes.querySelectorAll('input[type=checkbox]:checked');

  for (const item of checkedCheckboxes) {
    var checkboxValue = item.getAttribute('value');
    values.push(checkboxValue);
  }

  var dropdownValue = "Nothing is selected";
  if (values.length > 0) {
    dropdownValue = values.join(', ');
  }

  multiselectOption.innerText = dropdownValue;
}

function toggleCheckboxArea(onlyHide = false) {
  var checkboxes = document.getElementById("mySelectOptions");
  var displayValue = checkboxes.style.display;

  if (displayValue != "block") {
    if (onlyHide == false) {
      checkboxes.style.display = "block";
    }
  } else {
    checkboxes.style.display = "none";
  }
}
.multiselect {
  width: 100%;
}

.selectBox {
  position: relative;
}

.selectBox select {
  width: 100%;
}

.overSelect {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}

#mySelectOptions {
  display: none;
  border: 0.5px #7c7c7c solid;
  background-color: #ffffff;
  max-height: 150px;
  overflow-y: scroll;
}

#mySelectOptions label {
  display: block;
  font-weight: normal;
  display: block;
  white-space: nowrap;
  min-height: 1.2em;
  background-color: #ffffff00;
  padding: 0 2.25rem 0 .75rem;
  /* padding: .375rem 2.25rem .375rem .75rem; */
}

#mySelectOptions label:hover {
  background-color: #1e90ff;
}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>

<div class="container-fluid">


  <div class="form-group col-sm-8">
    <label for="dur">BS original select</label>
    <select id="dur" class="form-select">
      <option value="12" selected>One Year</option>
      <option value="24">Two Year</option>
      <option value="36">Three Year</option>
      <option value="48">Four year</option>
      <option value="60">Five Year</option>
    </select>
  </div>

  <div class="form-group col-sm-8">
    <label for="myMultiselect">BS custom multiselect</label>
    <div id="myMultiselect" class="multiselect">
      <div id="mySelectLabel" class="selectBox" onclick="toggleCheckboxArea()">
        <select class="form-select">
          <option>somevalue</option>
        </select>
        <div class="overSelect"></div>
      </div>
      <div id="mySelectOptions">
        <label for="one"><input type="checkbox" id="one" onchange="checkboxStatusChange()" value="one" /> First checkbox</label>
        <label for="two"><input type="checkbox" id="two" onchange="checkboxStatusChange()" value="two" /> Second checkbox</label>
        <label for="three"><input type="checkbox" id="three" onchange="checkboxStatusChange()" value="three" /> Third checkbox</label>
        <label for="four"><input type="checkbox" id="four" onchange="checkboxStatusChange()" value="four" /> Third checkbox</label>
        <label for="five"><input type="checkbox" id="five" onchange="checkboxStatusChange()" value="five" /> First checkbox</label>
        <label for="six"><input type="checkbox" id="six" onchange="checkboxStatusChange()" value="six" /> Second checkbox</label>
        <label for="seven"><input type="checkbox" id="seven" onchange="checkboxStatusChange()" value="seven" /> Third checkbox</label>
        <label for="eight"><input type="checkbox" id="eight" onchange="checkboxStatusChange()" value="eight" /> First checkbox</label>
        <label for="nine"><input type="checkbox" id="nine" onchange="checkboxStatusChange()" value="nine" /> Second checkbox</label>
        <label for="ten"><input type="checkbox" id="ten" onchange="checkboxStatusChange()" value="ten" /> Third checkbox</label>
      </div>
    </div>
  </div>

</div>
Alex
  • 4,607
  • 9
  • 61
  • 99
9

You can always use multiple or multiple = "true" option with a select tag, but there is one jquery plugin which makes it more beautiful. It is called chosen and can be found here.

This fiddle-example might help you to get started

Thank you.

Blauharley
  • 4,186
  • 6
  • 28
  • 47
Santosh
  • 1,027
  • 13
  • 12
7

Very simple code with Bootstrap and JQuery without any additional javascript code :

HTML :

.dropdown-menu label {
  display: block;
}
<div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Dropdown button
  </button>
  <form class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    <label class="dropdown-item"><input type="checkbox" name="" value="one">First checkbox</label>
    <label class="dropdown-item"><input type="checkbox" name="" value="two">Second checkbox</label>
    <label class="dropdown-item"><input type="checkbox" name="" value="three">Third checkbox</label>
  </form>
</div>

https://codepen.io/funkycram/pen/joVYBv

AliNajafZadeh
  • 1,216
  • 2
  • 13
  • 22
FunkycraM
  • 103
  • 1
  • 6
6

Multiple drop downs with checkbox's and jQuery.

jQuery(function($) {
  var checkList = $('.dropdown-check-list');
  checkList.on('click', 'span.anchor', function(event) {
    var element = $(this).parent();

    if (element.hasClass('visible')) {
      element.removeClass('visible');
    } else {
      element.addClass('visible');
    }
  });
});
.dropdown-check-list {
  display: inline-block;
  width: 100%;
}

.dropdown-check-list:focus {
  outline: 0;
}

.dropdown-check-list .anchor {
  width: 98%;
  position: relative;
  cursor: pointer;
  display: inline-block;
  padding-top: 5px;
  padding-left: 5px;
  padding-bottom: 5px;
  border: 1px #ccc solid;
}

.dropdown-check-list .anchor:after {
  position: absolute;
  content: "";
  border-left: 2px solid black;
  border-top: 2px solid black;
  padding: 5px;
  right: 10px;
  top: 20%;
  -moz-transform: rotate(-135deg);
  -ms-transform: rotate(-135deg);
  -o-transform: rotate(-135deg);
  -webkit-transform: rotate(-135deg);
  transform: rotate(-135deg);
}

.dropdown-check-list .anchor:active:after {
  right: 8px;
  top: 21%;
}

.dropdown-check-list ul.items {
  padding: 2px;
  display: none;
  margin: 0;
  border: 1px solid #ccc;
  border-top: none;
}

.dropdown-check-list ul.items li {
  list-style: none;
}

.dropdown-check-list.visible .anchor {
  color: #0094ff;
}

.dropdown-check-list.visible .items {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list3" class="dropdown-check-list" tabindex="100">
  <span class="anchor">Which development(s) are you interested in?</span>
  <ul class="items">
    <li><input id="answers_2529_the-lawns" name="answers[2529][answers][]" type="checkbox" value="The Lawns" /><label for="answers_2529_the-lawns">The Lawns</label></li>
    <li><input id="answers_2529_the-residence" name="answers[2529][answers][]" type="checkbox" value="The Residence" /><label for="answers_2529_the-residence">The Residence</label></li>
  </ul>
</div>
double-beep
  • 5,031
  • 17
  • 33
  • 41
Luke
  • 386
  • 1
  • 4
  • 15
2

Simply use bootstrap-multiselect where you can populate dropdown with multiselect option and many more feaatures.

For doc and tutorials you may visit below link

https://www.npmjs.com/package/bootstrap-multiselect

http://davidstutz.de/bootstrap-multiselect/

0

At first it is not possible to add checkboxes to select element directly. You need to use js for this purpose. There are basically two ways how to do "select" dropdown list with checkboxes:

  1. use select and create dropdown menu in another div element with inputs (type checkbox) which will be showed instead of original select options
  2. as in my example, I am using two divs, one is for dropdown list (consists from inputs type checkbox) and one is for showing results.

Second approach is better according to my experiences bcz when you send form, it will send just input values. In first option it will send also select value.

I make sample in jquery for your reference.

HTML/PHP code:

<div class="form__select-wrapper form__select-wrapper--multiselect">
    <div class="form__select form__select--multiselect" required>Vyberte zdravotnú poisťovňu *</div>
        <i class="arrow"></i>
        <div class="form__select-dropdown">
            <?php foreach ($insurances as $insurance) : ?>
                <label for="<?= plainText($insurance['insurance_id']); ?>" class="form__label--multiselect">
                    <input name="insurances[]" type="checkbox" id="<?= plainText($insurance['insurance_id']); ?>" value="<?= plainText($insurance['insurance_id']); ?>" class="form__checkbox" /> <?= plainText($insurance['insurance_name']); ?>
                        </label>
            <?php endforeach ?>
        </div>
    </div>
</div>

CSS code:

.form__label--multiselect {
    display: block;
    padding: 0.2em;
    background-color: #e0f4ff;
    color: #888;
}

.form__label--multiselect:hover {
    background-color: #ddd;
    color: #555;
}

.form__select-dropdown {
    display: none;
    position: absolute;
    width: 100%;
    border: 0.5px #7c7c7c solid;
    background-color: #ffffff;
    font-family: 'Sofia Sans', sans-serif;
    max-height: 150px;
    overflow-y: scroll;
    z-index: 999;
}

.form__select-wrapper {
    position: relative;
    margin-top: 1rem;
}

jQuery code:

// Function to show or hide multiselect list
function toggleCheckboxArea(onlyHide = false) {
    var checkboxes = $('.form__select-dropdown');
    var displayValue = checkboxes.css('display');

    if (displayValue !== 'block') {
        if (onlyHide) {
        checkboxes.css({display: 'block'});
        }
    } else {
        checkboxes.css('display', 'none');
    }
}

// Function to get cheked options from multiselect list with checkboxes and show in div textarea
function handleMultiSelectChange() {
    var currentLabel = $(this),
        currentCheckedInputs = currentLabel.parent().find('input:checked'),
        currentOption = currentLabel.find('option')[0],
        currentInputText = currentLabel.text(),
        currentDiv = currentLabel.parent().prev().prev(),
        selectedInsurances = [];

    // Check all checkboxes and add texts to array selectedInsurances
    currentCheckedInputs.each(function() {
        var insuranceName = $(this).parent().text().trim().split(' ')[0],
            fullInsuranceName = $(this).parent().text().trim();

        if (fullInsuranceName === 'Bez zmluvnej poisťovňe') {
            // Add full text to array
            selectedInsurances.push(fullInsuranceName);
        } else {
            // Add text to array
            selectedInsurances.push(insuranceName);
        }
    });

    // Show text form checkboxes in div
    if (currentCheckedInputs.length !== 0) {
        // Show texts from array separated by ;
        currentDiv.text(selectedInsurances.join('; '));
        currentDiv.css({color: '#555'});
    } else {
        // If user choose uncheck all checkboxes return default text
        currentDiv.text('Vyberte zdravotnú poisťovňu *');
        currentDiv.css({color: '#aaa'});
    }
};

// Event listener for change
multiSelectLabel.on('change', handleMultiSelectChange);

// Event listener pre page reloading

    $(window).on('load', function() {
        // Make action after page loading
        multiSelectLabel.trigger('change');
    });

    // Show dropdown menu if click on div
$('.form__select--multiselect').on('click', function(event) {
    event.preventDefault();

    var multiSelectLabel = $('.form__label--multiselect'),
        currentDivSelect = $(this),
        multiSelectCheckbox = $('.form__checkbox'),
        targetElement = event.target; // Get target element in html text form

        // Hide and show dropdown list just if it is not clicked on dorpdown list directly
        if ((targetElement.className !== multiSelectCheckbox.attr('class')) && (targetElement.className !== multiSelectLabel.attr('class'))) {
            toggleCheckboxArea(true);
        }

        // Change color of div on click
        if (currentDivSelect.css("background-color") == fieldsBackgroundColor) {
            currentDivSelect.css({backgroundColor: 'white'});
        } else {
            currentDivSelect.css({backgroundColor: '#e0f4ff'});
        }
});

// Hide dropdown menu if click outside of select
    $(document).on('mousedown', function() {
    var multiSelectDropdown = $('.form__select-dropdown'),
        multiSelectTextArea = $('.form__select--multiselect'),
        multiSelectLabel = $('.form__label--multiselect'),
        multiSelectCheckbox = $('.form__checkbox'),
        currentSelectArrow = multiSelectTextArea.parent().find('.arrow');
        targetElement = event.target; // Get target element in html text form

    if (multiSelectDropdown.is(':visible') && (targetElement.className !== multiSelectCheckbox.attr('class')) && (targetElement.className !== multiSelectLabel.attr('class')) && (targetElement.className !== multiSelectTextArea.attr('class'))) {
        toggleCheckboxArea(true);
    }

});
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 31 '23 at 13:05