From 6452591f8fee0bf431cbee38864371d896818de1 Mon Sep 17 00:00:00 2001 From: Kevin Provance Date: Thu, 30 Oct 2014 02:27:40 -0400 Subject: [PATCH] Add support for optgroup --- select2.sortable.js | 253 ++++++++++++++++++++++++-------------------- 1 file changed, 137 insertions(+), 116 deletions(-) diff --git a/select2.sortable.js b/select2.sortable.js index 2bb246a..a68c83c 100644 --- a/select2.sortable.js +++ b/select2.sortable.js @@ -3,123 +3,144 @@ * - enable select2 to be sortable via normal select element * * author : Vafour + * modified : Kevin Provance (kprovance) * inspired by : jQuery Chosen Sortable (https://github.com/mrhenry/jquery-chosen-sortable) * License : GPL */ -(function($){ - $.fn.extend({ - select2SortableOrder: function(){ - var $this = this.filter('[multiple]'); - - $this.each(function(){ - var $select = $(this); - - // skip elements not select2-ed - if(typeof($select.data('select2')) !== 'object'){ - return false; - } - - var $select2 = $select.siblings('.select2-container'), - unselected = [], - sorted; - - $select.find('option').each(function(){ - !this.selected && unselected.push(this); - }); - - sorted = $($select2.find('.select2-choices li[class!="select2-search-field"]').map( function() { - if (!this) { - return undefined; - } - var id = $(this).data('select2Data').id; - return $select.find('option[value="' + id + '"]')[0]; - })); - - sorted.push.apply(sorted, unselected); - $select.children().remove(); - $select.append(sorted); - }); - - return $this; - }, - select2Sortable: function(){ - var args = Array.prototype.slice.call(arguments, 0); - $this = this.filter('[multiple]'), - validMethods = ['destroy']; - - if(args.length === 0 || typeof(args[0]) === 'object') - { - var defaultOptions = { - bindOrder : 'formSubmit', // or sortableStop - sortableOptions : { - placeholder : 'ui-state-highlight', - items : 'li:not(.select2-search-field)', - tolerance : 'pointer' - } - }; - var options = $.extend(defaultOptions, args[0]); - - // Init select2 only if not already initialized to prevent select2 configuration loss - if(typeof($this.data('select2')) !== 'object'){ - $this.select2(); - } - - $this.each(function(){ - var $select = $(this), - $select2choices = $select.siblings('.select2-container').find('.select2-choices'); - - // Init jQuery UI Sortable - $select2choices.sortable(options.sortableOptions); - - switch(options.bindOrder){ - case 'sortableStop': - // apply options ordering in sortstop event - $select2choices.on("sortstop.select2sortable", function( event, ui ) { - $select.select2SortableOrder(); - }); - $select.on('change', function(e){ - $(this).select2SortableOrder(); - }); - break; - default: - // apply options ordering in form submit - $select.closest('form').unbind('submit.select2sortable').on('submit.select2sortable', function(){ - $select.select2SortableOrder(); - }); - } - - }); - } - else if(typeof(args[0] === 'string')) - { - if($.inArray(args[0], validMethods) == -1) - { - throw "Unknown method: " + args[0]; - } - if(args[0] === 'destroy') - { - $this.select2SortableDestroy(); - } - } - return $this; - }, - select2SortableDestroy: function(){ - var $this = this.filter('[multiple]'); - $this.each(function(){ - var $select = $(this), - $select2choices = $select.parent().find('.select2-choices'); - - // unbind form submit event - $select.closest('form').unbind('submit.select2sortable'); - - // unbind sortstop event - $select2choices.unbind("sortstop.select2sortable"); - - // destroy select2Sortable - $select2choices.sortable('destroy'); - }); - return $this; - } - }); -}(jQuery)); \ No newline at end of file +(function ($) { + $.fn.extend({ + select2SortableOrder: function () { + var $this = this.filter('[multiple]'); + + $this.each(function () { + var $select = $(this); + + // skip elements not select2-ed + if (typeof ($select.data('select2')) !== 'object') { + return false; + } + + var $select2 = $select.siblings('.select2-container') + var sorted; + + // Opt group names + var optArr = []; + + $select.find('optgroup').each(function(idx, val) { + optArr.push (val); + }); + + $select.find('option').each(function(idx, val) { + var groupName = $(this).parent('optgroup').prop('label'); + var optVal = this; + + if (groupName === undefined) { + if (this.value !== '') { + optArr.push (optVal); + } + } + }); + + sorted = $($select2.find('.select2-choices li[class!="select2-search-field"]').map(function () { + if (!this) { + return undefined; + } + + var id = $(this).data('select2Data').id; + + return $select.find('option[value="' + id + '"]')[0]; + })); + + sorted.push.apply(sorted, optArr); + + $select.children().remove(); + $select.append(sorted); + }); + + return $this; + }, + + select2Sortable: function () { + var args = Array.prototype.slice.call(arguments, 0); + $this = this.filter('[multiple]'), + validMethods = ['destroy']; + + if (args.length === 0 || typeof (args[0]) === 'object') { + var defaultOptions = { + bindOrder: 'formSubmit', // or sortableStop + sortableOptions: { + placeholder: 'ui-state-highlight', + items: 'li:not(.select2-search-field)', + tolerance: 'pointer' + } + }; + + var options = $.extend(defaultOptions, args[0]); + + // Init select2 only if not already initialized to prevent select2 configuration loss + if (typeof ($this.data('select2')) !== 'object') { + $this.select2(); + } + + $this.each(function () { + var $select = $(this) + var $select2choices = $select.siblings('.select2-container').find('.select2-choices'); + + // Init jQuery UI Sortable + $select2choices.sortable(options.sortableOptions); + + switch (options.bindOrder) { + case 'sortableStop': + // apply options ordering in sortstop event + $select2choices.on("sortstop.select2sortable", function (event, ui) { + $select.select2SortableOrder(); + }); + + $select.on('change', function (e) { + $(this).select2SortableOrder(); + }); + break; + + default: + // apply options ordering in form submit + $select.closest('form').unbind('submit.select2sortable').on('submit.select2sortable', function () { + $select.select2SortableOrder(); + }); + break; + } + }); + } + else if (typeof (args[0] === 'string')) { + if ($.inArray(args[0], validMethods) == -1) { + throw "Unknown method: " + args[0]; + } + + if (args[0] === 'destroy') { + $this.select2SortableDestroy(); + } + } + + return $this; + }, + + select2SortableDestroy: function () { + var $this = this.filter('[multiple]'); + $this.each(function () { + var $select = $(this) + var $select2choices = $select.parent().find('.select2-choices'); + + // unbind form submit event + $select.closest('form').unbind('submit.select2sortable'); + + // unbind sortstop event + $select2choices.unbind("sortstop.select2sortable"); + + // destroy select2Sortable + $select2choices.sortable('destroy'); + }); + + return $this; + } + }); +}(jQuery));