select2 multiple select as count in select2 search box - jquery-select2

Need to get just values and number of selection in multiple-select search box
Please check first screenshot using select2 multiselect,
I wants it like bellow one because the above selection is not looking good if I have multiple selectboxes as filters.
var elm = $('#error-type');
$(elm).select2({
placeholder: "Select features",
data: [
{ id: 0, text: "enhancement" },
{ id: 1, text: "bug" },
{ id: 2, text: "duplicate" },
{ id: 3, text: "invalid" },
{ id: 4, text: "wontfix" },
{ id: 5, text: "sdfsadf" },
{ id: 6, text: "ihfgdhfgdh" },
{ id: 7, text: "Vijaysinh" },
{ id: 8, text: "Parmar" },
{ id: 9, text: "invalid" },
{ id: 10, text: "Test device morel laravel" },
{ id: 11, text: "sky is blue" },
]
}).change(function () {
var selectedIDs = $.map($(elm).select2('data'), function (val, i) {
return val.id;
}).join(",");
$('#selectedIDs').text(selectedIDs);
});
#error-type {
width: 300px;
}
p {
margin: 1em 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.min.js"></script>
<p>Selected IDs: <span id="selectedIDs"></span></p>
<select id="error-type" multiple>
</select>

Try using select2:close event
$('select').select2()
$('.select1').on('select2:close', function() {
let select = $(this)
$(this).next('span.select2').find('ul').html(function() {
let count = select.select2('data').length
return "<li>" + count + " options selected</li>"
})
})
$('.select2').on('select2:close', function() {
let select = $(this)
select.next('span.select2').find('ul').html(function() {
return "<li>" + $(select).val() + "</li>"
})
})
.select2-selection__rendered li {
margin: 6px 0px 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.min.js"></script>
<select class="select1" multiple style="width:100%">
<option value="Alaska">Alaska</option>
<option value="Alaska">Alaska</option>
<option value="California">California</option>
<option value="Nevada">Nevada</option>
<option value="Oregon">Oregon</option>
<option value="Washington">Washington</option>
<option value="Arizona">Arizona</option>
</select>
<br/><br/>
<select class="select2" multiple style="width:100%">
<option value="Alaska">Alaska</option>
<option value="Alaska">Alaska</option>
<option value="California">California</option>
<option value="Nevada">Nevada</option>
<option value="Oregon">Oregon</option>
<option value="Washington">Washington</option>
<option value="Arizona">Arizona</option>
</select>
UPDATE (with search)
$('select').select2()
$('.select1').on('select2:close', function() {
let select = $(this),
ul = select.next('span.select2').find('ul');
ul.find('.select2-selection__choice').remove();
ul.prepend(function() {
let count = select.select2('data').length
return "<li class='select2-selection__choice'>" + count + " options selected</li>"
})
})
.select2-selection__rendered li {
margin: 6px 0px 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.min.js"></script>
<select class="select1" multiple style="width:100%">
<option value="Alaska">Alaska</option>
<option value="Alaska">Alaska</option>
<option value="California">California</option>
<option value="Nevada">Nevada</option>
<option value="Oregon">Oregon</option>
<option value="Washington">Washington</option>
<option value="Arizona">Arizona</option>
</select>

Related

How do I make a link open in an option

I added a link to the options, but when clicked only the option is selected. How do I make the link open without making a selection?
$(document).ready(function() {
$('.js-select-multi').select2({
placeholder: 'Select an option',
templateResult: formatOption
});
function formatOption(option) {
var $option_text = '';
var $option_details = '';
var $option_url = '';
$option_head = $(
'<div style="display: flex; flex-direction: column; flex-wrap: wrap; justify-content: space-between;">'
);
$option_text = $(
'<div style="font-size: 14px; min-width: 70%; height: 100%;">' + option.text + '</div>'
);
if ($(option.element).data('details')) {
$option_details = $(
'<div style="font-size: 10px; min-width: 70%; height: 100%;">' + $(option.element).data('details') + '</div>'
);
}
if ($(option.element).data('url')) {
$option_url = $(
'<div style="font-size: 9px; height: 100%; width: 30%;">Preview</div>'
);
}
$option_foot = $(
'</div>'
);
return $option_head.append($option_text).append($option_details).append($option_url).append($option_foot);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<div id="main">
<select class="js-select-multi" name="demos[]" id="userInput" style="width: 650px;" multiple="multiple">
<optgroup label="Opt Group 1">
<option value="90d1aba6" data-details="Customer" data-url="https://yahoo.com">Option #1</option>
<option value="238e894f" data-details="Customer" data-url="https://yahoo.com">Option #2</option>
</optgroup>
<optgroup label="Opt Group 2">
<option value="574b18e9" data-details="Customer" data-url="https://yahoo.com">Option #3</option>
<option value="5b626e8b" data-details="Customer" data-url="https://yahoo.com">Option #4</option>
</optgroup>
</select>
</div>
I was able to get this to work with version 3.5.4 of select2. Does not work on select2 4.x
$(document).ready(function() {
var select2 = $(".js-select-multi").select2({
formatResult: format,
allowClear: true
}).data('select2');
select2.onSelect = (function(fn) {
return function(data, options) {
var target;
if (options != null) {
target = $(options.target);
}
if (target && target.hasClass('link')) {
target_url = $(data.element).data('url');
//alert(target_url);
var win = window.open(target_url, '_blank');
if (win) {
//Browser has allowed it to be opened
win.focus();
} else {
//Browser has blocked it
alert('Please allow popup to preview demoboards');
}
} else {
return fn.apply(this, arguments);
}
}
})(select2.onSelect);
function format(option) {
if (!option.id) {
return option.text; // optgroup
} else {
var $option_text = '';
var $option_details = '';
var $option_url = '';
$option_head = $(
'<div style="display: flex; flex-direction: column; flex-wrap: wrap; justify-content: space-between;">'
);
$option_text = $(
'<div style="font-size: 14px; min-width: 70%; height: 100%;">' + option.text + '</div>'
);
if ($(option.element).data('details')) {
$option_details = $(
'<div style="font-size: 10px; min-width: 70%; height: 100%;">' + $(option.element).data('details') + '</div>'
);
}
if ($(option.element).data('url')) {
$option_url = $(
'<div style="font-size: 9px; height: 100%; width: 30%;"><a class="link" href="' + $(option.element).data('url') + '">Preview</a></div>'
);
}
$option_foot = $(
'</div>'
);
return $option_head.append($option_text).append($option_details).append($option_url).append($option_foot);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.min.js"></script>
<select class="js-select-multi" name="demos[]" id="userInput" style="width: 650px;" multiple="multiple">
<optgroup label="Opt Group 1">
<option value="90d1aba6" data-details="Customer" data-url="https://yahoo.com">Option #1</option>
<option value="238e894f" data-details="Customer" data-url="https://yahoo.com">Option #2</option>
</optgroup>
<optgroup label="Opt Group 2">
<option value="574b18e9" data-details="Customer" data-url="https://yahoo.com">Option #3</option>
<option value="5b626e8b" data-details="Customer" data-url="https://yahoo.com">Option #4</option>
</optgroup>
</select>

Select2 with tags set to true: Is it possible to always keep the placeholder after selecting the options?

I want the placeholder to be shown always whether the option is added, selected, or removed. Currently, the placeholder shows after removing the options or after adding the new options. But when the option is selected from the dropdown the placeholder will disappear. This may be the original functionality of the seelct2 plugin. Is there any way to keep the placeholder always visible?
$("select.add-tags").select2({
tags: true,
dropdownParent: $(".select-tags"),
placeholder: "Start typing the tag name..."
});
if ($("select.add-tags").select2("data").length) {
$("select.add-tags")
.next()
.find(".select2-search.select2-search--inline .select2-search__field")
.attr("placeholder", "Placeholder on default");
$("select.add-tags")
.next()
.find(".select2-search.select2-search--inline .select2-search__field")
.css("width", "200px");
}
$("select.add-tags").on("select2:select", function (evt) {
// console.log($(this).val());
console.log("select2 : select");
var element = evt.params.data.element;
var $element = $(element);
$element.detach();
$(this).append($element);
$(this).trigger("change");
if (
$(".select2-search.select2-search--inline .select2-search__field").is(
":focus"
)
) {
console.log("tag input fpcused");
$(".select2-search.select2-search--inline").removeAttr("style");
$(
".select2-search.select2-search--inline .select2-search__field"
).removeAttr("style");
$(".select2-search.select2-search--inline .select2-search__field").attr(
"placeholder",
"Placeholder on select"
);
$(".select2-search.select2-search--inline .select2-search__field").css(
"width",
"200px"
);
}
});
$("select.add-tags").on("select2:unselect", function () {
console.log($(this).val());
console.log("select2 : unselect");
if ($("select.add-tags").val().length == 0) {
$(".select2-search.select2-search--inline .select2-search__field").attr(
"placeholder",
"Start typing the tag name..."
);
$(".select2-search.select2-search--inline .select2-search__field").css(
"width",
"100%"
);
$(".select2-search.select2-search--.select2-search__field").css(
"width",
"100%"
);
} else {
$(".select2-search.select2-search--inline .select2-search__field").attr(
"placeholder",
"Add another tag"
);
$(".select2-search.select2-search--inline .select2-search__field").css(
"width",
"200px"
);
$(".select2-search.select2-search--inline").removeAttr("style");
}
});
select {
width: 300px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2-bootstrap-css/1.4.6/select2-bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
<div class="container select-tags">
<select class="add-tags error" multiple="multiple">
<option value="Red">Red</option>
<option value="Yellow">Yellow</option>
<option value="Green">Green</option>
<option value="Blue" selected>Blue</option>
<option value="Pink">Pink</option>
<option value="Black">Black</option>
</select>
</div>
Codepen: https://codepen.io/jagruti23/pen/bGggJZR

Autocomplete combobox widget force change

I'm getting absolutely no where in getting the underlying select to fire a changed event after a autocomplete value is selected.
How can I force a change within the widget. From what I can find I need to
trigger a select event and trigger a change with something like this, but I can't get it to work
select: function(event,ui) {
this.value=ui.item.value;
$(this).trigger('change');
return false; }
(function( $ ) {
$.widget("st.comboboxAutocomplete", {
options: {
minLength: 0,
showDropdown: false,
width: '',
Id: '',
},
_create: function () {
this.wrapper = $("<span>")
.addClass("st-comboboxAutocomplete")
.css({ 'padding': '0px 0px', 'width': this.options.width})
.insertAfter(this.element);
this.element.hide();
this._createAutocomplete();
if (this.options.showDropdown)
{
this._createShowAllButton();
}
},
_createAutocomplete: function () {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.attr("id", this.options.Id)
.addClass("st-comboboxAutocomplete-input")
.css('margin-right', '5px')
.autocomplete({
delay: 0,
minLength: this.options.minLength,
source: $.proxy(this, "_source"),
});
this._on(this.input, {
autocompleteselect: function (event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function () {
var input = this.input,
wasOpen = false;
$("<a>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.tooltip()
.css('background-color', '#fff')
.appendTo(this.wrapper)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("st-comboboxAutocomplete-toggle ui-corner-right")
.on("mousedown", function () {
wasOpen = input.autocomplete("widget").is(":visible");
})
.on("click", function () {
input.trigger("focus");
// Close if already visible
if (wasOpen) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete("search", "");
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text)))
return {
label: text,
value: text,
option: this
};
}));
},
_removeIfInvalid: function (event, ui) {
// Selected an item, nothing to do
if (ui.item) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function () {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if (valid) {
return;
}
// Remove invalid value
this.input
.val("")
.attr("title", value + " didn't match any item")
.tooltip("open");
this.element.val("");
this._delay(function () {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.autocomplete("instance").term = "";
},
_destroy: function () {
this.wrapper.remove();
this.element.show();
}
});
})( jQuery );
$(function() {
$( "#combobox" ).comboboxAutocomplete();
$("#combobox").change(function() {
alert(this.value);
});
});
.ui-button { margin-left: -1px; }
.ui-button-icon-only .ui-button-text { padding: 0.35em; }
.ui-autocomplete-input { margin: 0; padding: 0.48em 0 0.47em 0.45em; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<meta charset="utf-8">
<div class="demo">
<div class="ui-widget">
<label>Your preferred programming language: </label>
<select id="combobox">
<option value="">Select one...</option>
<option value="ActionScript">ActionScript</option>
<option value="AppleScript">AppleScript</option>
<option value="Asp">Asp</option>
<option value="BASIC">BASIC</option>
<option value="C">C</option>
<option value="C++">C++</option>
<option value="Clojure">Clojure</option>
<option value="COBOL">COBOL</option>
<option value="ColdFusion">ColdFusion</option>
<option value="Erlang">Erlang</option>
<option value="Fortran">Fortran</option>
<option value="Groovy">Groovy</option>
<option value="Haskell">Haskell</option>
<option value="Java">Java</option>
<option value="JavaScript">JavaScript</option>
<option value="Lisp">Lisp</option>
<option value="Perl">Perl</option>
<option value="PHP">PHP</option>
<option value="Python">Python</option>
<option value="Ruby">Ruby</option>
<option value="Scala">Scala</option>
<option value="Scheme">Scheme</option>
</select>
</div>
<button id="toggle">Show underlying select</button>
</div><!-- End demo -->
<div class="demo-description">
<p>A custom widget built by composition of Autocomplete and Button. You can either type something into the field to get filtered suggestions based on your input, or use the button to get the full list of selections.</p>
<p>The input is read from an existing select-element for progressive enhancement, passed to Autocomplete with a customized source-option.</p>
</div><!-- End demo-description -->
In case inquiring minds want to know, I solved this with the following
_createAutocomplete: function () {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.attr("id", this.options.Id)
.addClass("st-comboboxAutocomplete-input")
.css('margin-right', '5px')
.autocomplete({
delay: 0,
minLength: this.options.minLength,
source: $.proxy(this, "_source"),
change: $.proxy(this, "_change")
});
this._on(this.input, {
autocompleteselect: function (event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
}
_change: function (event, ui) {
this.value = ui.item.value;
this.element.trigger('change');
return false;
}
This will fire a change when you tab or exit the autocomplete. If you want it to fire the change on select then use
select: $.proxy(this, "_select")
_select: function (event, ui) {
this.element.trigger('change');
},

Filtering data from Fusion table on map using more than one selection

I have Fusion Table data that I would like to map on a web page and give users the ability to filter the geopoints using selection menus based on data in columns. I can do this using one column from the Fusion Table but I can't figure out how to do this using two or more columns. i.e./e.g. They can select/filter a column called 'Program' for entries labelled with 'GypsyMoth' and then further filter all these entries for 'TrapRteList' entries labelled 'NE'.
I have tried many, many ways of accomplishing this but so far no luck. Below is my best attempt but it will only select data from TrapRteList. How can get two column selections to update the map? I'm not a programmer (obviously) and have been banging my head against a wall for awhile now. None of the solutions I've found seem to work quite the way I want them to. Any help would be appreciated. Thank you.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="UTF-8">
<title>Tree Traps Map</title>
<style>
#map-canvas { width:1080px; height:768px; }
.layer-wizard-search-label { font-family: sans-serif };
</style>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function initialize() {
var pointTableID = '1EADJbmeOJj60i_jIMDPNwVt0SMYEwYsw8kuU3nwI';
var pointColumn = 'GPSpoint';
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(53.637692, -113.422068),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Initialize the points layer
var pointsLayer = new google.maps.FusionTablesLayer({
query: {
select: pointColumn,
from: pointTableID
},
map: map,
styleId: 2,
templateId: 2
});
// -----------------------------------
google.maps.event.addDomListener(document.getElementById('Program'),
'change', function() {
updateMap(pointsLayer, pointTableID, pointColumn);
});
google.maps.event.addDomListener(document.getElementById('TrapRteList'),
'change', function() {
updateMap(pointsLayer, pointTableID, pointColumn);
});
}
// Update the query sent to the Fusion Table Layer based on
// the user selection in the select menu
function updateMap(pointsLayer, pointTableID, pointColumn) {
var Program = document.getElementById('Program').value;
if (Program) {
pointsLayer.setOptions({
query: {
select: pointColumn,
from: pointTableID,
where: "Program = '" + Program + "'"
}
});
} else {
pointsLayer.setOptions({
query: {
select: pointColumn,
from: pointTableID
}
});
}
var TrapRteList = document.getElementById('TrapRteList').value;
if (TrapRteList) {
pointsLayer.setOptions({
query: {
select: pointColumn,
from: pointTableID,
where: "TrapRteList = '" + TrapRteList + "'"
}
});
} else {
pointsLayer.setOptions({
query: {
select: pointColumn,
from: pointTableID
}
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<p style="margin-left:auto; margin-right:auto; margin-top:0.25em; margin-bottom:0.25em; width:20%; font-size:14pt; font-weight:bold;">Trapping Program</p>
<label style="font-size:11pt; font-weight:bold;">Select trapping program: </label>
<select id="Program">
<option value="--Select--">--Select--</option>
<option value="">(no value)</option>
<option value="Apanteles">Apanteles</option>
<option value="AshBorer">Ash (or Lilac) Borer</option>
<option value="EBB-Banded">Banded Elm Bark Beetle</option>
<option value="EBB">Elm Bark Beetle</option>
<option value="EmeraldAshBorer">Emerald Ash Borer</option>
<option value="GypsyMoth">Gypsy Moth</option>
<option value="InvasiveAliens">Invasive Alien Species</option>
<option value="MountainPineBeetle">Mountain Pine Beetle</option>
<option value="Sirix">Sirix</option>
<option value="UglynestCaterpillar">Uglynest Caterpillar</option>
<option value="Other:">Other Program</option>
</select>
<label style="font-size:11pt; font-weight:bold;">Select trap route: </label>
<select id="TrapRteList">
<option value="--Select--">--Select--</option>
<option value="">(no value)</option>
<option value="NE">Northeast</option>
<option value="NW">Northwest</option>
<option value="SE">Southeast</option>
<option value="SW">Southwest</option>
<option value="OuterCommunity">Outer Community</option>
<option value="Other:">Other</option>
</select>
<div id="map-canvas"></div>
</body>
</html>
This should be sufficient:
function updateMap(pointsLayer, pointTableID, pointColumn) {
var o={
Program : document.getElementById('Program').value,
TrapRteList : document.getElementById('TrapRteList').value
},where=[];
for(var k in o){
if(o[k]){
where.push(k+"='"+o[k]+"'");
}
}
pointsLayer.setOptions({
query: {
select: pointColumn,
from: pointTableID,
where: where.join(' and ')
}
});
}
Note: all options that shouldn't be used for filtering must have an value which evaluates to false , e.g. a empty string.

Select2 with a checkbox list for a multiple select

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?
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/
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.
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";
}
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
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>
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/bootstrap#4.6.0/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>
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' }

Resources