Skip to content

Commit

Permalink
refs #37020. Add Select2 selectAll feature
Browse files Browse the repository at this point in the history
  • Loading branch information
poliphilochu committed Oct 17, 2024
1 parent ae59dcb commit 598fcc2
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 7 deletions.
92 changes: 92 additions & 0 deletions packages/jquery/plugins/jquery.select2.selectAll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* jquery.select2.selectAll.js
*
* A Select2 extension that adds "Select All" and "Unselect All" functionality to Select2 dropdowns.
*
* @description
* This extension creates a custom adapter for Select2 that adds "Select All" and "Unselect All"
* buttons to the dropdown of multi-select Select2 instances. These buttons allow users to quickly
* select or unselect all options in the dropdown.
*
* @usage
* 1. Include this file after loading jQuery and Select2.
* 2. Initialize Select2 with the custom adapter:
* $('#your-select-element').select2({
* dropdownAdapter: $.fn.select2.amd.require('select2/selectAllAdapter')
* });
*
* @dependencies
* - jQuery (https://jquery.com)
* - Select2 (https://select2.org)
*
* @source
* This script is based on the code from:
* https://jsfiddle.net/beaver71/tjvjytp3/
* Modified and packaged as a reusable extension.
* The original code was written for Select2 version 4.0.5. When adapting it for the latest version
* (4.1.0-rc.0), some modifications were necessary due to changes in Select2's internal structure
* and API. The custom adapter code has been updated to be compatible with version 4.1.0-rc.0,
* addressing issues that arose from differences in how Select2 handles custom adapters in the
* newer version. These changes ensure that the "Select All" and "Unselect All" functionality
* works correctly with the latest Select2 release while maintaining backwards compatibility
* where possible.
*/

(function ($) {
'use strict';

$.fn.select2.amd.define('select2/selectAllAdapter', [
'select2/utils',
'select2/dropdown',
'select2/dropdown/attachBody'
], function (Utils, Dropdown, AttachBody) {

function SelectAll() { }
SelectAll.prototype.render = function (decorated) {
var self = this,
$rendered = decorated.call(this),
$selectAll = $(
'<button class="btn btn-xs btn-default" type="button" style="margin-left:6px;"><i class="fa fa-check-square-o"></i> Select All</button>'
),
$unselectAll = $(
'<button class="btn btn-xs btn-default" type="button" style="margin-left:6px;"><i class="fa fa-square-o"></i> Unselect All</button>'
),
$btnContainer = $('<div style="margin-top:3px;">').append($selectAll).append($unselectAll);
if (!this.$element.prop("multiple")) {
// This isn't a multi-select, don't add the buttons
return $rendered;
}
$rendered.find('.select2-dropdown').prepend($btnContainer);
$selectAll.on('click', function (e) {
e.preventDefault();
var $options = self.$element.find('option');
var values = [];

$options.each(function() {
if (!this.disabled) {
values.push(this.value);
}
});

self.$element.val(values);
self.$element.trigger('change');
self.trigger('close');
});
$unselectAll.on('click', function (e) {
e.preventDefault();
self.$element.val([]);
self.$element.trigger('change');
self.trigger('close');
});
return $rendered;
};

return Utils.Decorate(
Utils.Decorate(
Dropdown,
AttachBody
),
SelectAll
);
});
})(jQuery);
1 change: 1 addition & 0 deletions templates/CRM/common/jquery.files.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ packages/jquery/plugins/jquery.chosen.js
packages/jquery/css/jquery.chosen.css

packages/jquery/plugins/jquery.select2.js
packages/jquery/plugins/jquery.select2.selectAll.js
packages/jquery/css/jquery.select2.css

packages/jquery/plugins/jquery.modal.min.js
Expand Down
25 changes: 18 additions & 7 deletions templates/CRM/common/select2.tpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
{if !$nowrapper}<script type="text/javascript"> {/if}
{literal}
(function ($) {
cj(document).ready(function(){
$('{/literal}{$selector}{literal}').select2({
"allowClear": true,
"dropdownAutoWidth": true,
{/literal}{if $select_width}"width": "{$select_width}",{/if}{literal}
"placeholder": "{/literal}{ts}-- Select --{/ts}{literal}",
"language": "{/literal}{if $config->lcMessages}{$config->lcMessages|replace:'_':'-'}{else}en{/if}{literal}"
$(document).ready(function(){
let $elements = $('{/literal}{$selector}{literal}');
$elements.each(function() {
let $this = $(this);
let options = {
"allowClear": true,
"dropdownAutoWidth": true,
{/literal}{if $select_width}"width": "{$select_width}",{/if}{literal}
"placeholder": "{/literal}{ts}-- Select --{/ts}{literal}",
"language": "{/literal}{if $config->lcMessages}{$config->lcMessages|replace:'_':'-'}{else}en{/if}{literal}"
};
if ($this.is('select[multiple]')) {
options.dropdownAdapter = $.fn.select2.amd.require('select2/selectAllAdapter');
}
$this.select2(options);
});
$(document).on('select2:open select2:close', (e) => {
let thisSelect = e.target,
$thisSelect = $(thisSelect),
Expand Down

0 comments on commit 598fcc2

Please sign in to comment.