|
1 /** |
|
2 * jQuery Select2 Sortable |
|
3 * - enable select2 to be sortable via normal select element |
|
4 * |
|
5 * author : Vafour |
|
6 * modified : Kevin Provance (kprovance) |
|
7 * modified : Thierry Florac (tflorac@ulthar.net) |
|
8 * Enable sorting for Select2 based on hidden inputs |
|
9 * inspired by : jQuery Chosen Sortable (https://github.com/mrhenry/jquery-chosen-sortable) |
|
10 * License : GPL |
|
11 */ |
|
12 |
|
13 (function ($) { |
|
14 |
|
15 $.fn.extend({ |
|
16 |
|
17 select2SortableOrder: function () { |
|
18 var $this = this.filter('[multiple]'); |
|
19 |
|
20 $this.each(function () { |
|
21 var $select = $(this); |
|
22 |
|
23 // skip elements not select2-ed |
|
24 if (typeof ($select.data('select2')) !== 'object') { |
|
25 return false; |
|
26 } |
|
27 |
|
28 var $select2 = $select.siblings('.select2-container'); |
|
29 var sorted; |
|
30 |
|
31 if ($select.attr('type') === 'hidden') { |
|
32 |
|
33 // Update hidden field value |
|
34 var plugin = $select2.data('select2'); |
|
35 var separator = plugin.opts.separator; |
|
36 var values = []; |
|
37 $.each(plugin.data(), function() { |
|
38 values.push(this.id); |
|
39 }); |
|
40 $select.val(values.join(separator)); |
|
41 |
|
42 } else { |
|
43 |
|
44 // Opt group names |
|
45 var optArr = []; |
|
46 |
|
47 $select.find('optgroup').each(function (idx, val) { |
|
48 optArr.push(val); |
|
49 }); |
|
50 |
|
51 $select.find('option').each(function (idx, val) { |
|
52 var groupName = $(this).parent('optgroup').prop('label'); |
|
53 var optVal = this; |
|
54 |
|
55 if (groupName === undefined) { |
|
56 if (this.value !== '' && !this.selected) { |
|
57 optArr.push(optVal); |
|
58 } |
|
59 } |
|
60 }); |
|
61 |
|
62 sorted = $($select2.find('.select2-choices li[class!="select2-search-field"]').map(function () { |
|
63 if (!this) { |
|
64 return undefined; |
|
65 } |
|
66 |
|
67 var id = $(this).data('select2Data').id; |
|
68 |
|
69 return $select.find('option[value="' + id + '"]')[0]; |
|
70 })); |
|
71 |
|
72 sorted.push.apply(sorted, optArr); |
|
73 |
|
74 $select.children().remove(); |
|
75 $select.append(sorted); |
|
76 } |
|
77 }); |
|
78 |
|
79 return $this; |
|
80 }, |
|
81 |
|
82 select2Sortable: function () { |
|
83 var args = Array.prototype.slice.call(arguments, 0); |
|
84 var $this = this.filter('[multiple]'), |
|
85 validMethods = ['destroy']; |
|
86 |
|
87 if (args.length === 0 || typeof (args[0]) === 'object') { |
|
88 var defaultOptions = { |
|
89 bindOrder: 'formSubmit', // or sortableStop |
|
90 sortableOptions: { |
|
91 placeholder: 'ui-state-highlight', |
|
92 items: 'li:not(.select2-search-field)', |
|
93 tolerance: 'pointer' |
|
94 } |
|
95 }; |
|
96 |
|
97 var options = $.extend(defaultOptions, args[0]); |
|
98 |
|
99 // Init select2 only if not already initialized to prevent select2 configuration loss |
|
100 if (typeof ($this.data('select2')) !== 'object') { |
|
101 $this.select2(); |
|
102 } |
|
103 |
|
104 $this.each(function () { |
|
105 var $select = $(this) |
|
106 var $select2choices = $select.siblings('.select2-container').find('.select2-choices'); |
|
107 |
|
108 // Init jQuery UI Sortable |
|
109 $select2choices.sortable(options.sortableOptions); |
|
110 |
|
111 switch (options.bindOrder) { |
|
112 case 'sortableStop': |
|
113 // apply options ordering in sortstop event |
|
114 $select2choices.on("sortstop.select2sortable", function (event, ui) { |
|
115 $select.select2SortableOrder(); |
|
116 }); |
|
117 |
|
118 $select.on('change', function (e) { |
|
119 $(this).select2SortableOrder(); |
|
120 }); |
|
121 break; |
|
122 |
|
123 default: |
|
124 // apply options ordering in form submit |
|
125 $select.closest('form').unbind('submit.select2sortable').on('submit.select2sortable', function () { |
|
126 $select.select2SortableOrder(); |
|
127 }); |
|
128 break; |
|
129 } |
|
130 }); |
|
131 } |
|
132 else if (typeof (args[0] === 'string')) { |
|
133 if ($.inArray(args[0], validMethods) == -1) { |
|
134 throw "Unknown method: " + args[0]; |
|
135 } |
|
136 |
|
137 if (args[0] === 'destroy') { |
|
138 $this.select2SortableDestroy(); |
|
139 } |
|
140 } |
|
141 |
|
142 return $this; |
|
143 }, |
|
144 |
|
145 select2SortableDestroy: function () { |
|
146 var $this = this.filter('[multiple]'); |
|
147 $this.each(function () { |
|
148 var $select = $(this) |
|
149 var $select2choices = $select.parent().find('.select2-choices'); |
|
150 |
|
151 // unbind form submit event |
|
152 $select.closest('form').unbind('submit.select2sortable'); |
|
153 |
|
154 // unbind sortstop event |
|
155 $select2choices.unbind("sortstop.select2sortable"); |
|
156 |
|
157 // destroy select2Sortable |
|
158 $select2choices.sortable('destroy'); |
|
159 }); |
|
160 |
|
161 return $this; |
|
162 } |
|
163 }); |
|
164 |
|
165 }(jQuery)); |