# HG changeset patch # User Thierry Florac # Date 1505812650 -7200 # Node ID afe6800e94ec61103fc4145393a88ac98c0c7a8f # Parent 7ac7101a76c678b805e353946927541daaf66546 Allow sorting of hidden-based inputs Select2 options diff -r 7ac7101a76c6 -r afe6800e94ec src/pyams_skin/resources/js/ext/jquery-select2-sortable.js --- a/src/pyams_skin/resources/js/ext/jquery-select2-sortable.js Tue Sep 19 11:15:38 2017 +0200 +++ b/src/pyams_skin/resources/js/ext/jquery-select2-sortable.js Tue Sep 19 11:17:30 2017 +0200 @@ -1,146 +1,165 @@ /** * jQuery Select2 Sortable * - enable select2 to be sortable via normal select element - * + * * author : Vafour * modified : Kevin Provance (kprovance) + * modified : Thierry Florac (tflorac@ulthar.net) + * Enable sorting for Select2 based on hidden inputs * inspired by : jQuery Chosen Sortable (https://github.com/mrhenry/jquery-chosen-sortable) * License : GPL */ (function ($) { - $.fn.extend({ - select2SortableOrder: function () { - var $this = this.filter('[multiple]'); + + $.fn.extend({ + + select2SortableOrder: function () { + var $this = this.filter('[multiple]'); - $this.each(function () { - var $select = $(this); + $this.each(function () { + var $select = $(this); + + // skip elements not select2-ed + if (typeof ($select.data('select2')) !== 'object') { + return false; + } - // skip elements not select2-ed - if (typeof ($select.data('select2')) !== 'object') { - return false; - } + var $select2 = $select.siblings('.select2-container'); + var sorted; + + if ($select.attr('type') === 'hidden') { - var $select2 = $select.siblings('.select2-container'); - var sorted; + // Update hidden field value + var plugin = $select2.data('select2'); + var separator = plugin.opts.separator; + var values = []; + $.each(plugin.data(), function() { + values.push(this.id); + }); + $select.val(values.join(separator)); + + } else { + + // Opt group names + var optArr = []; - // 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 !== '' && !this.selected) { - 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; + $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 !== '' && !this.selected) { + optArr.push(optVal); + } + } + }); + + sorted = $($select2.find('.select2-choices li[class!="select2-search-field"]').map(function () { + if (!this) { + return undefined; + } - return $select.find('option[value="' + id + '"]')[0]; - })); - - sorted.push.apply(sorted, optArr); - - $select.children().remove(); - $select.append(sorted); - }); + var id = $(this).data('select2Data').id; + + return $select.find('option[value="' + id + '"]')[0]; + })); + + sorted.push.apply(sorted, optArr); - return $this; - }, - - select2Sortable: function () { - var args = Array.prototype.slice.call(arguments, 0); - $this = this.filter('[multiple]'), - validMethods = ['destroy']; + $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]); + 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(); + } - // 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); - $this.each(function () { - var $select = $(this) - var $select2choices = $select.siblings('.select2-container').find('.select2-choices'); + switch (options.bindOrder) { + case 'sortableStop': + // apply options ordering in sortstop event + $select2choices.on("sortstop.select2sortable", function (event, ui) { + $select.select2SortableOrder(); + }); - // Init jQuery UI Sortable - $select2choices.sortable(options.sortableOptions); + $select.on('change', function (e) { + $(this).select2SortableOrder(); + }); + break; - 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'); + 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; + }, - // unbind form submit event - $select.closest('form').unbind('submit.select2sortable'); + select2SortableDestroy: function () { + var $this = this.filter('[multiple]'); + $this.each(function () { + var $select = $(this) + var $select2choices = $select.parent().find('.select2-choices'); - // unbind sortstop event - $select2choices.unbind("sortstop.select2sortable"); + // unbind form submit event + $select.closest('form').unbind('submit.select2sortable'); - // destroy select2Sortable - $select2choices.sortable('destroy'); - }); - - return $this; - } - }); + // unbind sortstop event + $select2choices.unbind("sortstop.select2sortable"); + + // destroy select2Sortable + $select2choices.sortable('destroy'); + }); + + return $this; + } + }); + }(jQuery)); diff -r 7ac7101a76c6 -r afe6800e94ec src/pyams_skin/resources/js/ext/jquery-select2-sortable.min.js --- a/src/pyams_skin/resources/js/ext/jquery-select2-sortable.min.js Tue Sep 19 11:15:38 2017 +0200 +++ b/src/pyams_skin/resources/js/ext/jquery-select2-sortable.min.js Tue Sep 19 11:17:30 2017 +0200 @@ -1,1 +1,1 @@ -(function(a){a.fn.extend({select2SortableOrder:function(){var b=this.filter("[multiple]");b.each(function(){var f=a(this);if(typeof(f.data("select2"))!=="object"){return false}var e=f.siblings(".select2-container");var d;var c=[];f.find("optgroup").each(function(g,h){c.push(h)});f.find("option").each(function(h,i){var j=a(this).parent("optgroup").prop("label");var g=this;if(j===undefined){if(this.value!==""&&!this.selected){c.push(g)}}});d=a(e.find('.select2-choices li[class!="select2-search-field"]').map(function(){if(!this){return undefined}var g=a(this).data("select2Data").id;return f.find('option[value="'+g+'"]')[0]}));d.push.apply(d,c);f.children().remove();f.append(d)});return b},select2Sortable:function(){var d=Array.prototype.slice.call(arguments,0);$this=this.filter("[multiple]"),validMethods=["destroy"];if(d.length===0||typeof(d[0])==="object"){var b={bindOrder:"formSubmit",sortableOptions:{placeholder:"ui-state-highlight",items:"li:not(.select2-search-field)",tolerance:"pointer"}};var c=a.extend(b,d[0]);if(typeof($this.data("select2"))!=="object"){$this.select2()}$this.each(function(){var e=a(this);var f=e.siblings(".select2-container").find(".select2-choices");f.sortable(c.sortableOptions);switch(c.bindOrder){case"sortableStop":f.on("sortstop.select2sortable",function(g,h){e.select2SortableOrder()});e.on("change",function(g){a(this).select2SortableOrder()});break;default:e.closest("form").unbind("submit.select2sortable").on("submit.select2sortable",function(){e.select2SortableOrder()});break}})}else{if(typeof(d[0]==="string")){if(a.inArray(d[0],validMethods)==-1){throw"Unknown method: "+d[0]}if(d[0]==="destroy"){$this.select2SortableDestroy()}}}return $this},select2SortableDestroy:function(){var b=this.filter("[multiple]");b.each(function(){var c=a(this);var d=c.parent().find(".select2-choices");c.closest("form").unbind("submit.select2sortable");d.unbind("sortstop.select2sortable");d.sortable("destroy")});return b}})}(jQuery)); \ No newline at end of file +(function(a){a.fn.extend({select2SortableOrder:function(){var b=this.filter("[multiple]");b.each(function(){var g=a(this);if(typeof(g.data("select2"))!=="object"){return false}var f=g.siblings(".select2-container");var e;if(g.attr("type")==="hidden"){var h=f.data("select2");var i=h.opts.separator;var d=[];a.each(h.data(),function(){d.push(this.id)});g.val(d.join(i))}else{var c=[];g.find("optgroup").each(function(j,k){c.push(k)});g.find("option").each(function(k,l){var m=a(this).parent("optgroup").prop("label");var j=this;if(m===undefined){if(this.value!==""&&!this.selected){c.push(j)}}});e=a(f.find('.select2-choices li[class!="select2-search-field"]').map(function(){if(!this){return undefined}var j=a(this).data("select2Data").id;return g.find('option[value="'+j+'"]')[0]}));e.push.apply(e,c);g.children().remove();g.append(e)}});return b},select2Sortable:function(){var d=Array.prototype.slice.call(arguments,0);$this=this.filter("[multiple]"),validMethods=["destroy"];if(d.length===0||typeof(d[0])==="object"){var b={bindOrder:"formSubmit",sortableOptions:{placeholder:"ui-state-highlight",items:"li:not(.select2-search-field)",tolerance:"pointer"}};var c=a.extend(b,d[0]);if(typeof($this.data("select2"))!=="object"){$this.select2()}$this.each(function(){var e=a(this);var f=e.siblings(".select2-container").find(".select2-choices");f.sortable(c.sortableOptions);switch(c.bindOrder){case"sortableStop":f.on("sortstop.select2sortable",function(g,h){e.select2SortableOrder()});e.on("change",function(g){a(this).select2SortableOrder()});break;default:e.closest("form").unbind("submit.select2sortable").on("submit.select2sortable",function(){e.select2SortableOrder()});break}})}else{if(typeof(d[0]==="string")){if(a.inArray(d[0],validMethods)==-1){throw"Unknown method: "+d[0]}if(d[0]==="destroy"){$this.select2SortableDestroy()}}}return $this},select2SortableDestroy:function(){var b=this.filter("[multiple]");b.each(function(){var c=a(this);var d=c.parent().find(".select2-choices");c.closest("form").unbind("submit.select2sortable");d.unbind("sortstop.select2sortable");d.sortable("destroy")});return b}})}(jQuery)); \ No newline at end of file