Allow sorting of hidden-based inputs Select2 options
authorThierry Florac <thierry.florac@onf.fr>
Tue, 19 Sep 2017 11:17:30 +0200
changeset 207 afe6800e94ec
parent 206 7ac7101a76c6
child 208 d3d38d0b3d18
Allow sorting of hidden-based inputs Select2 options
src/pyams_skin/resources/js/ext/jquery-select2-sortable.js
src/pyams_skin/resources/js/ext/jquery-select2-sortable.min.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));
--- 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