Select2 with a checkbox list for a multiple select
Asked Answered
G

8

30

I need to implement a select similar to this http://www.erichynds.com/examples/jquery-ui-multiselect-widget/demos/

I want to use select2 for this, but I haven't been able to find anything from the creator of the select2 that would support this style of dropdown with checkboxes in it. Does anyone know a way to do this?

Gaytan answered 7/4, 2014 at 16:37 Comment(1)
This would interest you. davidstutz.github.io/bootstrap-multiselectConsuelaconsuelo
N
19

I've faced a similar need but was not able to find it.

The solution I've came across was using the flag closeOnSelect set to false

$("#yadayada").select2({closeOnSelect:false}); http://jsfiddle.net/jEADR/521/

New answered 29/7, 2014 at 10:1 Comment(0)
D
16

Seems this is old post, but as it is very common issue, I`m posting this here.

I found that the author already added a plugin to select2 for this feature to have checkbox-like selection and the dropdown does not hide on click:

https://github.com/wasikuss/select2-multi-checkboxes

Example:

$('.select2-multiple').select2MultiCheckboxes({
    placeholder: "Choose multiple elements",
})

http://jsfiddle.net/wasikuss/gx93rwnk/

All other features of select2 are preserved. There are few more predefined options set to work properly.

Descendent answered 14/5, 2017 at 9:49 Comment(4)
It doesn't work with Select2 4.0.x. Thanks for this example, but you used 3.5.4. I created a fiddle and a question about Multi-Checkboxes with 4.0.x: #52263930Brittaneybrittani
There is an update for 4.x version: github.com/wasikuss/select2-multi-checkboxes/tree/amdDescendent
There are no dist files for the amd version.Clathrate
While check the item, is there any way to stop moving on top?Ramonaramonda
C
6

I managed to put something together, not perfect, but it works.

https://jsfiddle.net/Lkkm2L48/7/

jQuery(function($) {
    $.fn.select2.amd.require([
    'select2/selection/single',
    'select2/selection/placeholder',
    'select2/selection/allowClear',
    'select2/dropdown',
    'select2/dropdown/search',
    'select2/dropdown/attachBody',
    'select2/utils'
  ], function (SingleSelection, Placeholder, AllowClear, Dropdown, DropdownSearch, AttachBody, Utils) {

        var SelectionAdapter = Utils.Decorate(
      SingleSelection,
      Placeholder
    );

    SelectionAdapter = Utils.Decorate(
      SelectionAdapter,
      AllowClear
    );

    var DropdownAdapter = Utils.Decorate(
      Utils.Decorate(
        Dropdown,
        DropdownSearch
      ),
      AttachBody
    );

        var base_element = $('.select2-multiple2')
    $(base_element).select2({
        placeholder: 'Select multiple items',
      selectionAdapter: SelectionAdapter,
      dropdownAdapter: DropdownAdapter,
      allowClear: true,
      templateResult: function (data) {

        if (!data.id) { return data.text; }

        var $res = $('<div></div>');

        $res.text(data.text);
        $res.addClass('wrap');

        return $res;
      },
      templateSelection: function (data) {
        if (!data.id) { return data.text; }
        var selected = ($(base_element).val() || []).length;
        var total = $('option', $(base_element)).length;
        return "Selected " + selected + " of " + total;
      }
    })

  });

});

CSS:

.select2-results__option .wrap:before{
    font-family:fontAwesome;
    color:#999;
    content:"\f096";
    width:25px;
    height:25px;
    padding-right: 10px;

}
.select2-results__option[aria-selected=true] .wrap:before{
    content:"\f14a";
}
Champ answered 25/10, 2017 at 18:10 Comment(0)
S
6

Here is very simple snippet, without strange modyfing of js - pure and simple css (with "Font Awesome")

$('.select2[multiple]').select2({
    width: '100%',
    closeOnSelect: false
})
#body{
padding: 30px
}

.select2-results__options[aria-multiselectable="true"] li {
    padding-left: 30px;
    position: relative
}

.select2-results__options[aria-multiselectable="true"] li:before {
    position: absolute;
    left: 8px;
    opacity: .6;
    top: 6px;
    font-family: "FontAwesome";
    content: "\f0c8";
}

.select2-results__options[aria-multiselectable="true"] li[aria-selected="true"]:before {
    content: "\f14a";
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/css/select2.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/js/select2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.min.js"></script>


<div id="body">
<select name="fabric_color_en[]" id="fabric_color_en[]" multiple="multiple" class="form-control select2">
    <option value="Beige">
        Beige
    </option>

    <option value="Red">
        Red
    </option>

    <option value="Petrol">
        Petrol
    </option>

    <option value="Royal Blue">
        Royal Blue
    </option>

    <option value="Dark Blue">
        Dark Blue
    </option>

    <option value="Bottle Green">
        Bottle Green
    </option>

    <option value="Light Grey">
        Light Grey
    </option>
</select>
</div>
Simitar answered 25/9, 2019 at 13:40 Comment(0)
I
5

Add just two emoji with css

.select2-results__options {
    &[aria-multiselectable=true] {

        .select2-results__option {
            &[aria-selected=true]:before {
                content: '☑';
                padding: 0 0 0 4px;
            }

            &:before {
                content: '◻';
                padding: 0 0 0 4px;
            }
        }
    }
}

You see this sample a RTL select2 with emoji based checkbox RTL select2 with emoji based checboxes

Improbity answered 16/1, 2018 at 22:2 Comment(0)
C
3

Now the code is ready to use for you to implement the multiple checkboxes select2 dropdown.

Enjoy :) //===============================================

//Start - Select 2 Multi-Select Code======================================================
var Select2MultiCheckBoxObj = [];
var id_selectElement = 'id_SelectElement';
var staticWordInID = 'state_';

function AddItemInSelect2MultiCheckBoxObj(id, IsChecked) {
    if (Select2MultiCheckBoxObj.length > 0) {
        let index = Select2MultiCheckBoxObj.findIndex(x => x.id == id);
        if (index > -1) {
            Select2MultiCheckBoxObj[index]["IsChecked"] = IsChecked;
        }
        else {
            Select2MultiCheckBoxObj.push({ "id": id, "IsChecked": IsChecked });
        }
    }
    else {
        Select2MultiCheckBoxObj.push({ "id": id, "IsChecked": IsChecked });
    }
}

function IsCheckedAllOption(trueOrFalse) {
    $.map($('#' + id_selectElement + ' option'), function (option) {
        AddItemInSelect2MultiCheckBoxObj(option.value, trueOrFalse);
    });
    $('#' + id_selectElement + " > option").not(':first').prop("selected", trueOrFalse); //This will select all options and adds in Select2
    $("#" + id_selectElement).trigger("change");//This will effect the changes
    $(".select2-results__option").not(':first').attr("aria-selected", trueOrFalse); //This will make grey color of selected options

    $("input[id^='" + staticWordInID + "']").prop("checked", trueOrFalse);
}

$(document).ready(function () {
    //Begin - Select 2 Multi-Select Code
    $.map($('#' + id_selectElement + ' option'), function (option) {
        AddItemInSelect2MultiCheckBoxObj(option.value, false);
    });

    function formatResult(state) {
        if (Select2MultiCheckBoxObj.length > 0) {
            var stateId = staticWordInID + state.id;
            let index = Select2MultiCheckBoxObj.findIndex(x => x.id == state.id);
            if (index > -1) {
                var checkbox = $('<div class="checkbox"><input class="select2Checkbox" id="' + stateId + '" type="checkbox" ' + (Select2MultiCheckBoxObj[index]["IsChecked"] ? 'checked' : '') +
                    '><label for="checkbox' + stateId + '">' + state.text + '</label></div>', { id: stateId });
                return checkbox;
            }
        }
    }

    let optionSelect2 = {
        templateResult: formatResult,
        closeOnSelect: false,
        width: '100%'
    };

    let $select2 = $("#" + id_selectElement).select2(optionSelect2);

    //var scrollTop;
    //$select2.on("select2:selecting", function (event) {
    //    var $pr = $('#' + event.params.args.data._resultId).parent();
    //    scrollTop = $pr.prop('scrollTop');
    //    let xxxx = 2;
    //});

    $select2.on("select2:select", function (event) {
        $("#" + staticWordInID + event.params.data.id).prop("checked", true);
        AddItemInSelect2MultiCheckBoxObj(event.params.data.id, true);
        //If all options are slected then selectAll option would be also selected.
        if (Select2MultiCheckBoxObj.filter(x => x.IsChecked === false).length === 1) {
            AddItemInSelect2MultiCheckBoxObj(0, true);
            $("#" + staticWordInID + "0").prop("checked", true);
        }
    });

    $select2.on("select2:unselect", function (event) {
        $("#" + staticWordInID + "0").prop("checked", false);
        AddItemInSelect2MultiCheckBoxObj(0, false);
        $("#" + staticWordInID + event.params.data.id).prop("checked", false);
        AddItemInSelect2MultiCheckBoxObj(event.params.data.id, false);
    });

    $(document).on("click", "#" + staticWordInID + "0", function () {
        //var b = !($("#state_SelectAll").is(':checked'));
        var b = $("#" + staticWordInID + "0").is(':checked');

        IsCheckedAllOption(b);
        //state_CheckAll = b;
        //$(window).scroll();
    });
    $(document).on("click", ".select2Checkbox", function (event) {
        let selector = "#" + this.id;
        let isChecked = Select2MultiCheckBoxObj[Select2MultiCheckBoxObj.findIndex(x => x.id == this.id.replaceAll(staticWordInID, ''))]['IsChecked'];
        $(selector).prop("checked", isChecked);
    });

});


//====End - Select 2 Multi-Select Code==
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet"/>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="undefined" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>


<div class="container-fluid">
<hr/>
<p>Here, you can select any item by clicking on row or checked in on checkbox and can unselect in reverse way.</p>
<p>But I didn't give the option to select "SelectAll" option by clicking on his row, you can select-all and unselect-all by click on checkbox only rather than row.</p>
        <div class="row" style="width:50%">

            <label for="id_SelectElement" class="col-sm-2">Part Name: </label>
            <div class="col-sm-4">
                <select id="id_SelectElement" placeholder="Select Text" multiple>
                    <option value="0" disabled>Select All</option>
                    <option value="11">Php</option>
                    <option value="22">Bootstrap</option>
                    <option value="33">sql</option>
                    <option value="44">Node Js</option>
                    <option value="55">Laravel</option>
                    <option value="66">Jquery</option>
                     <option value="77">React</option>
                    <option value="88">Vew.JS</option>
                    <option value="99">MVC</option>
                    <option value="10">DotNetCore</option>
                    <option value="12">Java</option>
                    <option value="13">Artifical Intiligence</option>
                     <option value="14">Data Structure</option>
                    <option value="15">Data Science</option>
                    <option value="16">Robotics</option>
                    <option value="17">Node Js 2</option>
                    <option value="18">Laravel 23</option>
                    <option value="19">Jquery 3.4</option>
                </select>

                
            </div>
        </div>


    </div>
Cryptozoic answered 17/6, 2021 at 17:40 Comment(0)
P
1

Another workaround is to "prepend" checkbox icons using CSS. I use bootstrap theme - your select2-container may be different.

.select2-container--bootstrap .select2-results__option[aria-selected=true]:before { content:'\e067 '; padding:0 8px 0 0px; font-family:'Glyphicons Halflings' }
.select2-container--bootstrap .select2-results__option:before { content:'\e157 '; padding:0 8px 0 0px; font-family:'Glyphicons Halflings' }
Pacifa answered 6/12, 2017 at 18:18 Comment(0)
P
0

just like this

<select class="js-example-basic-multiple" name="states[]" multiple="multiple">
    <option value="AL">Alabama</option>
    ...
    <option value="WY">Wyoming</option>
</select>

and in your scripts

$(document).ready(function() {
    $('.js-example-basic-multiple').select2();
});
Polished answered 1/9, 2023 at 10:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.