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