| 1411 |
lars |
1 |
/**
|
|
|
2 |
* Display a nice easy to use multiselect list
|
|
|
3 |
* @Version: 2.4.16
|
|
|
4 |
* @Author: Patrick Springstubbe
|
|
|
5 |
* @Contact: @JediNobleclem
|
|
|
6 |
* @Website: springstubbe.us
|
|
|
7 |
* @Source: https://github.com/nobleclem/jQuery-MultiSelect
|
|
|
8 |
*
|
|
|
9 |
* Usage:
|
|
|
10 |
* $('select[multiple]').multiselect();
|
|
|
11 |
* $('select[multiple]').multiselect({ texts: { placeholder: 'Select options' } });
|
|
|
12 |
* $('select[multiple]').multiselect('reload');
|
|
|
13 |
* $('select[multiple]').multiselect( 'loadOptions', [{
|
|
|
14 |
* name : 'Option Name 1',
|
|
|
15 |
* value : 'option-value-1',
|
|
|
16 |
* checked: false,
|
|
|
17 |
* attributes : {
|
|
|
18 |
* custom1: 'value1',
|
|
|
19 |
* custom2: 'value2'
|
|
|
20 |
* }
|
|
|
21 |
* },{
|
|
|
22 |
* name : 'Option Name 2',
|
|
|
23 |
* value : 'option-value-2',
|
|
|
24 |
* checked: false,
|
|
|
25 |
* attributes : {
|
|
|
26 |
* custom1: 'value1',
|
|
|
27 |
* custom2: 'value2'
|
|
|
28 |
* }
|
|
|
29 |
* }]);
|
|
|
30 |
*
|
|
|
31 |
**/
|
|
|
32 |
(function($){
|
|
|
33 |
var defaults = {
|
|
|
34 |
columns: 1, // how many columns should be use to show options
|
|
|
35 |
search : false, // include option search box
|
|
|
36 |
|
|
|
37 |
// search filter options
|
|
|
38 |
searchOptions : {
|
|
|
39 |
delay : 250, // time (in ms) between keystrokes until search happens
|
|
|
40 |
showOptGroups: false, // show option group titles if no options remaining
|
|
|
41 |
searchText : true, // search within the text
|
|
|
42 |
searchValue : false, // search within the value
|
|
|
43 |
onSearch : function( element ){} // fires on keyup before search on options happens
|
|
|
44 |
},
|
|
|
45 |
|
|
|
46 |
// plugin texts
|
|
|
47 |
texts: {
|
|
|
48 |
placeholder : 'Select options', // text to use in dummy input
|
|
|
49 |
search : 'Search', // search input placeholder text
|
|
|
50 |
selectedOptions: ' selected', // selected suffix text
|
|
|
51 |
selectAll : 'Select all', // select all text
|
|
|
52 |
unselectAll : 'Unselect all', // unselect all text
|
|
|
53 |
noneSelected : 'None Selected' // None selected text
|
|
|
54 |
},
|
|
|
55 |
|
|
|
56 |
// general options
|
|
|
57 |
selectAll : false, // add select all option
|
|
|
58 |
selectGroup : false, // select entire optgroup
|
|
|
59 |
minHeight : 200, // minimum height of option overlay
|
|
|
60 |
maxHeight : null, // maximum height of option overlay
|
|
|
61 |
maxWidth : null, // maximum width of option overlay (or selector)
|
|
|
62 |
maxPlaceholderWidth: null, // maximum width of placeholder button
|
|
|
63 |
maxPlaceholderOpts : 10, // maximum number of placeholder options to show until "# selected" shown instead
|
|
|
64 |
showCheckbox : true, // display the checkbox to the user
|
|
|
65 |
checkboxAutoFit : false, // auto calc checkbox padding
|
|
|
66 |
optionAttributes : [], // attributes to copy to the checkbox from the option element
|
|
|
67 |
|
|
|
68 |
// Callbacks
|
|
|
69 |
onLoad : function( element ){}, // fires at end of list initialization
|
|
|
70 |
onOptionClick : function( element, option ){}, // fires when an option is clicked
|
|
|
71 |
onControlClose: function( element ){}, // fires when the options list is closed
|
|
|
72 |
onSelectAll : function( element, selected ){}, // fires when (un)select all is clicked
|
|
|
73 |
};
|
|
|
74 |
|
|
|
75 |
var msCounter = 1; // counter for each select list
|
|
|
76 |
var msOptCounter = 1; // counter for each option on page
|
|
|
77 |
|
|
|
78 |
// FOR LEGACY BROWSERS (talking to you IE8)
|
|
|
79 |
if( typeof Array.prototype.map !== 'function' ) {
|
|
|
80 |
Array.prototype.map = function( callback, thisArg ) {
|
|
|
81 |
if( typeof thisArg === 'undefined' ) {
|
|
|
82 |
thisArg = this;
|
|
|
83 |
}
|
|
|
84 |
|
|
|
85 |
return $.isArray( thisArg ) ? $.map( thisArg, callback ) : [];
|
|
|
86 |
};
|
|
|
87 |
}
|
|
|
88 |
if( typeof String.prototype.trim !== 'function' ) {
|
|
|
89 |
String.prototype.trim = function() {
|
|
|
90 |
return this.replace(/^\s+|\s+$/g, '');
|
|
|
91 |
};
|
|
|
92 |
}
|
|
|
93 |
|
|
|
94 |
function MultiSelect( element, options )
|
|
|
95 |
{
|
|
|
96 |
this.element = element;
|
|
|
97 |
this.options = $.extend( true, {}, defaults, options );
|
|
|
98 |
this.updateSelectAll = true;
|
|
|
99 |
this.updatePlaceholder = true;
|
|
|
100 |
this.listNumber = msCounter;
|
|
|
101 |
|
|
|
102 |
msCounter = msCounter + 1; // increment counter
|
|
|
103 |
|
|
|
104 |
/* Make sure its a multiselect list */
|
|
|
105 |
if( !$(this.element).attr('multiple') ) {
|
|
|
106 |
throw new Error( '[jQuery-MultiSelect] Select list must be a multiselect list in order to use this plugin' );
|
|
|
107 |
}
|
|
|
108 |
|
|
|
109 |
/* Options validation checks */
|
|
|
110 |
if( this.options.search ){
|
|
|
111 |
if( !this.options.searchOptions.searchText && !this.options.searchOptions.searchValue ){
|
|
|
112 |
throw new Error( '[jQuery-MultiSelect] Either searchText or searchValue should be true.' );
|
|
|
113 |
}
|
|
|
114 |
}
|
|
|
115 |
|
|
|
116 |
/** BACKWARDS COMPATIBILITY **/
|
|
|
117 |
if( 'placeholder' in this.options ) {
|
|
|
118 |
this.options.texts.placeholder = this.options.placeholder;
|
|
|
119 |
delete this.options.placeholder;
|
|
|
120 |
}
|
|
|
121 |
if( 'default' in this.options.searchOptions ) {
|
|
|
122 |
this.options.texts.search = this.options.searchOptions['default'];
|
|
|
123 |
delete this.options.searchOptions['default'];
|
|
|
124 |
}
|
|
|
125 |
/** END BACKWARDS COMPATIBILITY **/
|
|
|
126 |
|
|
|
127 |
// load this instance
|
|
|
128 |
this.load();
|
|
|
129 |
}
|
|
|
130 |
|
|
|
131 |
MultiSelect.prototype = {
|
|
|
132 |
/* LOAD CUSTOM MULTISELECT DOM/ACTIONS */
|
|
|
133 |
load: function() {
|
|
|
134 |
var instance = this;
|
|
|
135 |
|
|
|
136 |
// make sure this is a select list and not loaded
|
|
|
137 |
if( (instance.element.nodeName != 'SELECT') || $(instance.element).hasClass('jqmsLoaded') ) {
|
|
|
138 |
return true;
|
|
|
139 |
}
|
|
|
140 |
|
|
|
141 |
// sanity check so we don't double load on a select element
|
|
|
142 |
$(instance.element).addClass('jqmsLoaded ms-list-'+ instance.listNumber ).data( 'plugin_multiselect-instance', instance );
|
|
|
143 |
|
|
|
144 |
// add option container
|
|
|
145 |
$(instance.element).after('<div id="ms-list-'+ instance.listNumber +'" class="ms-options-wrap"><button type="button"><span>None Selected</span></button><div class="ms-options"><ul></ul></div></div>');
|
|
|
146 |
|
|
|
147 |
var placeholder = $(instance.element).siblings('#ms-list-'+ instance.listNumber +'.ms-options-wrap').find('> button:first-child');
|
|
|
148 |
var optionsWrap = $(instance.element).siblings('#ms-list-'+ instance.listNumber +'.ms-options-wrap').find('> .ms-options');
|
|
|
149 |
var optionsList = optionsWrap.find('> ul');
|
|
|
150 |
|
|
|
151 |
// don't show checkbox (add class for css to hide checkboxes)
|
|
|
152 |
if( !instance.options.showCheckbox ) {
|
|
|
153 |
optionsWrap.addClass('hide-checkbox');
|
|
|
154 |
}
|
|
|
155 |
else if( instance.options.checkboxAutoFit ) {
|
|
|
156 |
optionsWrap.addClass('checkbox-autofit');
|
|
|
157 |
}
|
|
|
158 |
|
|
|
159 |
// check if list is disabled
|
|
|
160 |
if( $(instance.element).prop( 'disabled' ) ) {
|
|
|
161 |
placeholder.prop( 'disabled', true );
|
|
|
162 |
}
|
|
|
163 |
|
|
|
164 |
// set placeholder maxWidth
|
|
|
165 |
if( instance.options.maxPlaceholderWidth ) {
|
|
|
166 |
placeholder.css( 'maxWidth', instance.options.maxPlaceholderWidth );
|
|
|
167 |
}
|
|
|
168 |
|
|
|
169 |
// override with user defined maxHeight
|
|
|
170 |
if( instance.options.maxHeight ) {
|
|
|
171 |
var maxHeight = instance.options.maxHeight;
|
|
|
172 |
}
|
|
|
173 |
else {
|
|
|
174 |
// cacl default maxHeight
|
|
|
175 |
var maxHeight = ($(window).height() - optionsWrap.offset().top + $(window).scrollTop() - 20);
|
|
|
176 |
}
|
|
|
177 |
|
|
|
178 |
// maxHeight cannot be less than options.minHeight
|
|
|
179 |
maxHeight = maxHeight < instance.options.minHeight ? instance.options.minHeight : maxHeight;
|
|
|
180 |
|
|
|
181 |
optionsWrap.css({
|
|
|
182 |
maxWidth : instance.options.maxWidth,
|
|
|
183 |
minHeight: instance.options.minHeight,
|
|
|
184 |
maxHeight: maxHeight,
|
|
|
185 |
});
|
|
|
186 |
|
|
|
187 |
// isolate options scroll
|
|
|
188 |
// @source: https://github.com/nobleclem/jQuery-IsolatedScroll
|
|
|
189 |
optionsWrap.on( 'touchmove mousewheel DOMMouseScroll', function ( e ) {
|
|
|
190 |
if( ($(this).outerHeight() < $(this)[0].scrollHeight) ) {
|
|
|
191 |
var e0 = e.originalEvent,
|
|
|
192 |
delta = e0.wheelDelta || -e0.detail;
|
|
|
193 |
|
|
|
194 |
if( ($(this).outerHeight() + $(this)[0].scrollTop) > $(this)[0].scrollHeight ) {
|
|
|
195 |
e.preventDefault();
|
|
|
196 |
this.scrollTop += ( delta < 0 ? 1 : -1 );
|
|
|
197 |
}
|
|
|
198 |
}
|
|
|
199 |
});
|
|
|
200 |
|
|
|
201 |
// hide options menus if click happens off of the list placeholder button
|
|
|
202 |
$(document).off('click.ms-hideopts').on('click.ms-hideopts', function( event ){
|
|
|
203 |
if( !$(event.target).closest('.ms-options-wrap').length ) {
|
|
|
204 |
$('.ms-options-wrap.ms-active > .ms-options').each(function(){
|
|
|
205 |
$(this).closest('.ms-options-wrap').removeClass('ms-active');
|
|
|
206 |
|
|
|
207 |
var listID = $(this).closest('.ms-options-wrap').attr('id');
|
|
|
208 |
|
|
|
209 |
var thisInst = $(this).parent().siblings('.'+ listID +'.jqmsLoaded').data('plugin_multiselect-instance');
|
|
|
210 |
|
|
|
211 |
// USER CALLBACK
|
|
|
212 |
if( typeof thisInst.options.onControlClose == 'function' ) {
|
|
|
213 |
thisInst.options.onControlClose( thisInst.element );
|
|
|
214 |
}
|
|
|
215 |
});
|
|
|
216 |
}
|
|
|
217 |
// hide open option lists if escape key pressed
|
|
|
218 |
}).on('keydown', function( event ){
|
|
|
219 |
if( (event.keyCode || event.which) == 27 ) { // esc key
|
|
|
220 |
$(this).trigger('click.ms-hideopts');
|
|
|
221 |
}
|
|
|
222 |
});
|
|
|
223 |
|
|
|
224 |
// handle pressing enter|space while tabbing through
|
|
|
225 |
placeholder.on('keydown', function( event ){
|
|
|
226 |
var code = (event.keyCode || event.which);
|
|
|
227 |
if( (code == 13) || (code == 32) ) { // enter OR space
|
|
|
228 |
placeholder.trigger( 'mousedown' );
|
|
|
229 |
}
|
|
|
230 |
});
|
|
|
231 |
|
|
|
232 |
// disable button action
|
|
|
233 |
placeholder.on( 'mousedown', function( event ){
|
|
|
234 |
// ignore if its not a left click
|
|
|
235 |
if( event.which && (event.which != 1) ) {
|
|
|
236 |
return true;
|
|
|
237 |
}
|
|
|
238 |
|
|
|
239 |
// hide other menus before showing this one
|
|
|
240 |
$('.ms-options-wrap.ms-active').each(function(){
|
|
|
241 |
if( $(this).siblings( '.'+ $(this).attr('id') +'.jqmsLoaded')[0] != optionsWrap.parent().siblings('.ms-list-'+ instance.listNumber +'.jqmsLoaded')[0] ) {
|
|
|
242 |
$(this).removeClass('ms-active');
|
|
|
243 |
|
|
|
244 |
var thisInst = $(this).siblings( '.'+ $(this).attr('id') +'.jqmsLoaded').data('plugin_multiselect-instance');
|
|
|
245 |
|
|
|
246 |
// USER CALLBACK
|
|
|
247 |
if( typeof thisInst.options.onControlClose == 'function' ) {
|
|
|
248 |
thisInst.options.onControlClose( thisInst.element );
|
|
|
249 |
}
|
|
|
250 |
}
|
|
|
251 |
});
|
|
|
252 |
|
|
|
253 |
// show/hide options
|
|
|
254 |
optionsWrap.closest('.ms-options-wrap').toggleClass('ms-active');
|
|
|
255 |
|
|
|
256 |
// recalculate height
|
|
|
257 |
if( optionsWrap.closest('.ms-options-wrap').hasClass('ms-active') ) {
|
|
|
258 |
optionsWrap.css( 'maxHeight', '' );
|
|
|
259 |
|
|
|
260 |
// override with user defined maxHeight
|
|
|
261 |
if( instance.options.maxHeight ) {
|
|
|
262 |
var maxHeight = instance.options.maxHeight;
|
|
|
263 |
}
|
|
|
264 |
else {
|
|
|
265 |
// cacl default maxHeight
|
|
|
266 |
var maxHeight = ($(window).height() - optionsWrap.offset().top + $(window).scrollTop() - 20);
|
|
|
267 |
}
|
|
|
268 |
|
|
|
269 |
if( maxHeight ) {
|
|
|
270 |
// maxHeight cannot be less than options.minHeight
|
|
|
271 |
maxHeight = maxHeight < instance.options.minHeight ? instance.options.minHeight : maxHeight;
|
|
|
272 |
|
|
|
273 |
optionsWrap.css( 'maxHeight', maxHeight );
|
|
|
274 |
}
|
|
|
275 |
}
|
|
|
276 |
else if( typeof instance.options.onControlClose == 'function' ) {
|
|
|
277 |
instance.options.onControlClose( instance.element );
|
|
|
278 |
}
|
|
|
279 |
}).click(function( event ){ event.preventDefault(); });
|
|
|
280 |
|
|
|
281 |
// add placeholder copy
|
|
|
282 |
if( instance.options.texts.placeholder ) {
|
|
|
283 |
placeholder.find('span').text( instance.options.texts.placeholder );
|
|
|
284 |
}
|
|
|
285 |
|
|
|
286 |
// add search box
|
|
|
287 |
if( instance.options.search ) {
|
|
|
288 |
optionsList.before('<div class="ms-search"><input type="text" value="" placeholder="'+ instance.options.texts.search +'" /></div>');
|
|
|
289 |
|
|
|
290 |
var search = optionsWrap.find('.ms-search input');
|
|
|
291 |
search.on('keyup', function(){
|
|
|
292 |
// ignore keystrokes that don't make a difference
|
|
|
293 |
if( $(this).data('lastsearch') == $(this).val() ) {
|
|
|
294 |
return true;
|
|
|
295 |
}
|
|
|
296 |
|
|
|
297 |
// pause timeout
|
|
|
298 |
if( $(this).data('searchTimeout') ) {
|
|
|
299 |
clearTimeout( $(this).data('searchTimeout') );
|
|
|
300 |
}
|
|
|
301 |
|
|
|
302 |
var thisSearchElem = $(this);
|
|
|
303 |
|
|
|
304 |
$(this).data('searchTimeout', setTimeout(function(){
|
|
|
305 |
thisSearchElem.data('lastsearch', thisSearchElem.val() );
|
|
|
306 |
|
|
|
307 |
// USER CALLBACK
|
|
|
308 |
if( typeof instance.options.searchOptions.onSearch == 'function' ) {
|
|
|
309 |
instance.options.searchOptions.onSearch( instance.element );
|
|
|
310 |
}
|
|
|
311 |
|
|
|
312 |
// search non optgroup li's
|
|
|
313 |
var searchString = $.trim( search.val().toLowerCase() );
|
|
|
314 |
if( searchString ) {
|
|
|
315 |
optionsList.find('li[data-search-term*="'+ searchString +'"]:not(.optgroup)').removeClass('ms-hidden');
|
|
|
316 |
optionsList.find('li:not([data-search-term*="'+ searchString +'"], .optgroup)').addClass('ms-hidden');
|
|
|
317 |
}
|
|
|
318 |
else {
|
|
|
319 |
optionsList.find('.ms-hidden').removeClass('ms-hidden');
|
|
|
320 |
}
|
|
|
321 |
|
|
|
322 |
// show/hide optgroups based on if there are items visible within
|
|
|
323 |
if( !instance.options.searchOptions.showOptGroups ) {
|
|
|
324 |
optionsList.find('.optgroup').each(function(){
|
|
|
325 |
if( $(this).find('li:not(.ms-hidden)').length ) {
|
|
|
326 |
$(this).show();
|
|
|
327 |
}
|
|
|
328 |
else {
|
|
|
329 |
$(this).hide();
|
|
|
330 |
}
|
|
|
331 |
});
|
|
|
332 |
}
|
|
|
333 |
|
|
|
334 |
instance._updateSelectAllText();
|
|
|
335 |
}, instance.options.searchOptions.delay ));
|
|
|
336 |
});
|
|
|
337 |
}
|
|
|
338 |
|
|
|
339 |
// add global select all options
|
|
|
340 |
if( instance.options.selectAll ) {
|
|
|
341 |
optionsList.before('<a href="#" class="ms-selectall global">' + instance.options.texts.selectAll + '</a>');
|
|
|
342 |
}
|
|
|
343 |
|
|
|
344 |
// handle select all option
|
|
|
345 |
optionsWrap.on('click', '.ms-selectall', function( event ){
|
|
|
346 |
event.preventDefault();
|
|
|
347 |
|
|
|
348 |
instance.updateSelectAll = false;
|
|
|
349 |
instance.updatePlaceholder = false;
|
|
|
350 |
|
|
|
351 |
var select = optionsWrap.parent().siblings('.ms-list-'+ instance.listNumber +'.jqmsLoaded');
|
|
|
352 |
|
|
|
353 |
if( $(this).hasClass('global') ) {
|
|
|
354 |
// check if any options are not selected if so then select them
|
|
|
355 |
if( optionsList.find('li:not(.optgroup, .selected, .ms-hidden)').length ) {
|
|
|
356 |
// get unselected vals, mark as selected, return val list
|
|
|
357 |
optionsList.find('li:not(.optgroup, .selected, .ms-hidden)').addClass('selected');
|
|
|
358 |
optionsList.find('li.selected input[type="checkbox"]:not(:disabled)').prop( 'checked', true );
|
|
|
359 |
}
|
|
|
360 |
// deselect everything
|
|
|
361 |
else {
|
|
|
362 |
optionsList.find('li:not(.optgroup, .ms-hidden).selected').removeClass('selected');
|
|
|
363 |
optionsList.find('li:not(.optgroup, .ms-hidden, .selected) input[type="checkbox"]:not(:disabled)').prop( 'checked', false );
|
|
|
364 |
}
|
|
|
365 |
}
|
|
|
366 |
else if( $(this).closest('li').hasClass('optgroup') ) {
|
|
|
367 |
var optgroup = $(this).closest('li.optgroup');
|
|
|
368 |
|
|
|
369 |
// check if any selected if so then select them
|
|
|
370 |
if( optgroup.find('li:not(.selected, .ms-hidden)').length ) {
|
|
|
371 |
optgroup.find('li:not(.selected, .ms-hidden)').addClass('selected');
|
|
|
372 |
optgroup.find('li.selected input[type="checkbox"]:not(:disabled)').prop( 'checked', true );
|
|
|
373 |
}
|
|
|
374 |
// deselect everything
|
|
|
375 |
else {
|
|
|
376 |
optgroup.find('li:not(.ms-hidden).selected').removeClass('selected');
|
|
|
377 |
optgroup.find('li:not(.ms-hidden, .selected) input[type="checkbox"]:not(:disabled)').prop( 'checked', false );
|
|
|
378 |
}
|
|
|
379 |
}
|
|
|
380 |
|
|
|
381 |
var vals = [];
|
|
|
382 |
optionsList.find('li.selected input[type="checkbox"]').each(function(){
|
|
|
383 |
vals.push( $(this).val() );
|
|
|
384 |
});
|
|
|
385 |
select.val( vals ).trigger('change');
|
|
|
386 |
|
|
|
387 |
instance.updateSelectAll = true;
|
|
|
388 |
instance.updatePlaceholder = true;
|
|
|
389 |
|
|
|
390 |
// USER CALLBACK
|
|
|
391 |
if( typeof instance.options.onSelectAll == 'function' ) {
|
|
|
392 |
instance.options.onSelectAll( instance.element, vals.length );
|
|
|
393 |
}
|
|
|
394 |
|
|
|
395 |
instance._updateSelectAllText();
|
|
|
396 |
instance._updatePlaceholderText();
|
|
|
397 |
});
|
|
|
398 |
|
|
|
399 |
// add options to wrapper
|
|
|
400 |
var options = [];
|
|
|
401 |
$(instance.element).children().each(function(){
|
|
|
402 |
if( this.nodeName == 'OPTGROUP' ) {
|
|
|
403 |
var groupOptions = [];
|
|
|
404 |
|
|
|
405 |
$(this).children('option').each(function(){
|
|
|
406 |
var thisOptionAtts = {};
|
|
|
407 |
for( var i = 0; i < instance.options.optionAttributes.length; i++ ) {
|
|
|
408 |
var thisOptAttr = instance.options.optionAttributes[ i ];
|
|
|
409 |
|
|
|
410 |
if( $(this).attr( thisOptAttr ) !== undefined ) {
|
|
|
411 |
thisOptionAtts[ thisOptAttr ] = $(this).attr( thisOptAttr );
|
|
|
412 |
}
|
|
|
413 |
}
|
|
|
414 |
|
|
|
415 |
groupOptions.push({
|
|
|
416 |
name : $(this).text(),
|
|
|
417 |
value : $(this).val(),
|
|
|
418 |
checked: $(this).prop( 'selected' ),
|
|
|
419 |
attributes: thisOptionAtts
|
|
|
420 |
});
|
|
|
421 |
});
|
|
|
422 |
|
|
|
423 |
options.push({
|
|
|
424 |
label : $(this).attr('label'),
|
|
|
425 |
options: groupOptions
|
|
|
426 |
});
|
|
|
427 |
}
|
|
|
428 |
else if( this.nodeName == 'OPTION' ) {
|
|
|
429 |
var thisOptionAtts = {};
|
|
|
430 |
for( var i = 0; i < instance.options.optionAttributes.length; i++ ) {
|
|
|
431 |
var thisOptAttr = instance.options.optionAttributes[ i ];
|
|
|
432 |
|
|
|
433 |
if( $(this).attr( thisOptAttr ) !== undefined ) {
|
|
|
434 |
thisOptionAtts[ thisOptAttr ] = $(this).attr( thisOptAttr );
|
|
|
435 |
}
|
|
|
436 |
}
|
|
|
437 |
|
|
|
438 |
options.push({
|
|
|
439 |
name : $(this).text(),
|
|
|
440 |
value : $(this).val(),
|
|
|
441 |
checked : $(this).prop( 'selected' ),
|
|
|
442 |
attributes: thisOptionAtts
|
|
|
443 |
});
|
|
|
444 |
}
|
|
|
445 |
else {
|
|
|
446 |
// bad option
|
|
|
447 |
return true;
|
|
|
448 |
}
|
|
|
449 |
});
|
|
|
450 |
instance.loadOptions( options, true, false );
|
|
|
451 |
|
|
|
452 |
// BIND SELECT ACTION
|
|
|
453 |
optionsWrap.on( 'click', 'input[type="checkbox"]', function(){
|
|
|
454 |
$(this).closest( 'li' ).toggleClass( 'selected' );
|
|
|
455 |
|
|
|
456 |
var select = optionsWrap.parent().siblings('.ms-list-'+ instance.listNumber +'.jqmsLoaded');
|
|
|
457 |
|
|
|
458 |
// toggle clicked option
|
|
|
459 |
select.find('option[value="'+ instance._escapeSelector( $(this).val() ) +'"]').prop(
|
|
|
460 |
'selected', $(this).is(':checked')
|
|
|
461 |
).closest('select').trigger('change');
|
|
|
462 |
|
|
|
463 |
// USER CALLBACK
|
|
|
464 |
if( typeof instance.options.onOptionClick == 'function' ) {
|
|
|
465 |
instance.options.onOptionClick(instance.element, this);
|
|
|
466 |
}
|
|
|
467 |
|
|
|
468 |
instance._updateSelectAllText();
|
|
|
469 |
instance._updatePlaceholderText();
|
|
|
470 |
});
|
|
|
471 |
|
|
|
472 |
// BIND FOCUS EVENT
|
|
|
473 |
optionsWrap.on('focusin', 'input[type="checkbox"]', function(){
|
|
|
474 |
$(this).closest('label').addClass('focused');
|
|
|
475 |
}).on('focusout', 'input[type="checkbox"]', function(){
|
|
|
476 |
$(this).closest('label').removeClass('focused');
|
|
|
477 |
});
|
|
|
478 |
|
|
|
479 |
// USER CALLBACK
|
|
|
480 |
if( typeof instance.options.onLoad === 'function' ) {
|
|
|
481 |
instance.options.onLoad( instance.element );
|
|
|
482 |
}
|
|
|
483 |
|
|
|
484 |
// hide native select list
|
|
|
485 |
$(instance.element).hide();
|
|
|
486 |
},
|
|
|
487 |
|
|
|
488 |
/* LOAD SELECT OPTIONS */
|
|
|
489 |
loadOptions: function( options, overwrite, updateSelect ) {
|
|
|
490 |
overwrite = (typeof overwrite == 'boolean') ? overwrite : true;
|
|
|
491 |
updateSelect = (typeof updateSelect == 'boolean') ? updateSelect : true;
|
|
|
492 |
|
|
|
493 |
var instance = this;
|
|
|
494 |
var select = $(instance.element);
|
|
|
495 |
var optionsList = select.siblings('#ms-list-'+ instance.listNumber +'.ms-options-wrap').find('> .ms-options > ul');
|
|
|
496 |
var optionsWrap = select.siblings('#ms-list-'+ instance.listNumber +'.ms-options-wrap').find('> .ms-options');
|
|
|
497 |
|
|
|
498 |
if( overwrite ) {
|
|
|
499 |
optionsList.find('> li').remove();
|
|
|
500 |
|
|
|
501 |
if( updateSelect ) {
|
|
|
502 |
select.find('> *').remove();
|
|
|
503 |
}
|
|
|
504 |
}
|
|
|
505 |
|
|
|
506 |
var containers = [];
|
|
|
507 |
for( var key in options ) {
|
|
|
508 |
// Prevent prototype methods injected into options from being iterated over.
|
|
|
509 |
if( !options.hasOwnProperty( key ) ) {
|
|
|
510 |
continue;
|
|
|
511 |
}
|
|
|
512 |
|
|
|
513 |
var thisOption = options[ key ];
|
|
|
514 |
var container = $('<li/>');
|
|
|
515 |
var appendContainer = true;
|
|
|
516 |
|
|
|
517 |
// OPTION
|
|
|
518 |
if( thisOption.hasOwnProperty('value') ) {
|
|
|
519 |
if( instance.options.showCheckbox && instance.options.checkboxAutoFit ) {
|
|
|
520 |
container.addClass('ms-reflow');
|
|
|
521 |
}
|
|
|
522 |
|
|
|
523 |
// add option to ms dropdown
|
|
|
524 |
instance._addOption( container, thisOption );
|
|
|
525 |
|
|
|
526 |
if( updateSelect ) {
|
|
|
527 |
var selOption = $('<option value="'+ thisOption.value +'">'+ thisOption.name +'</option>');
|
|
|
528 |
|
|
|
529 |
// add custom user attributes
|
|
|
530 |
if( thisOption.hasOwnProperty('attributes') && Object.keys( thisOption.attributes ).length ) {
|
|
|
531 |
selOption.attr( thisOption.attributes );
|
|
|
532 |
}
|
|
|
533 |
|
|
|
534 |
// mark option as selected
|
|
|
535 |
if( thisOption.checked ) {
|
|
|
536 |
selOption.prop( 'selected', true );
|
|
|
537 |
}
|
|
|
538 |
|
|
|
539 |
select.append( selOption );
|
|
|
540 |
}
|
|
|
541 |
}
|
|
|
542 |
// OPTGROUP
|
|
|
543 |
else if( thisOption.hasOwnProperty('options') ) {
|
|
|
544 |
var optGroup = $('<optgroup label="'+ thisOption.label +'"></optgroup>');
|
|
|
545 |
|
|
|
546 |
optionsList.find('> li.optgroup > span.label').each(function(){
|
|
|
547 |
if( $(this).text() == thisOption.label ) {
|
|
|
548 |
container = $(this).closest('.optgroup');
|
|
|
549 |
appendContainer = false;
|
|
|
550 |
}
|
|
|
551 |
});
|
|
|
552 |
|
|
|
553 |
// prepare to append optgroup to select element
|
|
|
554 |
if( updateSelect ) {
|
|
|
555 |
if( select.find('optgroup[label="'+ thisOption.label +'"]').length ) {
|
|
|
556 |
optGroup = select.find('optgroup[label="'+ thisOption.label +'"]');
|
|
|
557 |
}
|
|
|
558 |
else {
|
|
|
559 |
select.append( optGroup );
|
|
|
560 |
}
|
|
|
561 |
}
|
|
|
562 |
|
|
|
563 |
// setup container
|
|
|
564 |
if( appendContainer ) {
|
|
|
565 |
container.addClass('optgroup');
|
|
|
566 |
container.append('<span class="label">'+ thisOption.label +'</span>');
|
|
|
567 |
container.find('> .label').css({
|
|
|
568 |
clear: 'both'
|
|
|
569 |
});
|
|
|
570 |
|
|
|
571 |
// add select all link
|
|
|
572 |
if( instance.options.selectGroup ) {
|
|
|
573 |
container.append('<a href="#" class="ms-selectall">' + instance.options.texts.selectAll + '</a>');
|
|
|
574 |
}
|
|
|
575 |
|
|
|
576 |
container.append('<ul/>');
|
|
|
577 |
}
|
|
|
578 |
|
|
|
579 |
for( var gKey in thisOption.options ) {
|
|
|
580 |
// Prevent prototype methods injected into options from
|
|
|
581 |
// being iterated over.
|
|
|
582 |
if( !thisOption.options.hasOwnProperty( gKey ) ) {
|
|
|
583 |
continue;
|
|
|
584 |
}
|
|
|
585 |
|
|
|
586 |
var thisGOption = thisOption.options[ gKey ];
|
|
|
587 |
var gContainer = $('<li/>');
|
|
|
588 |
if( instance.options.showCheckbox && instance.options.checkboxAutoFit ) {
|
|
|
589 |
gContainer.addClass('ms-reflow');
|
|
|
590 |
}
|
|
|
591 |
|
|
|
592 |
// no clue what this is we hit (skip)
|
|
|
593 |
if( !thisGOption.hasOwnProperty('value') ) {
|
|
|
594 |
continue;
|
|
|
595 |
}
|
|
|
596 |
|
|
|
597 |
instance._addOption( gContainer, thisGOption );
|
|
|
598 |
|
|
|
599 |
container.find('> ul').append( gContainer );
|
|
|
600 |
|
|
|
601 |
// add option to optgroup in select element
|
|
|
602 |
if( updateSelect ) {
|
|
|
603 |
var selOption = $('<option value="'+ thisGOption.value +'">'+ thisGOption.name +'</option>');
|
|
|
604 |
|
|
|
605 |
// add custom user attributes
|
|
|
606 |
if( thisGOption.hasOwnProperty('attributes') && Object.keys( thisGOption.attributes ).length ) {
|
|
|
607 |
selOption.attr( thisGOption.attributes );
|
|
|
608 |
}
|
|
|
609 |
|
|
|
610 |
// mark option as selected
|
|
|
611 |
if( thisGOption.checked ) {
|
|
|
612 |
selOption.prop( 'selected', true );
|
|
|
613 |
}
|
|
|
614 |
|
|
|
615 |
optGroup.append( selOption );
|
|
|
616 |
}
|
|
|
617 |
}
|
|
|
618 |
}
|
|
|
619 |
else {
|
|
|
620 |
// no clue what this is we hit (skip)
|
|
|
621 |
continue;
|
|
|
622 |
}
|
|
|
623 |
|
|
|
624 |
if( appendContainer ) {
|
|
|
625 |
containers.push( container );
|
|
|
626 |
}
|
|
|
627 |
}
|
|
|
628 |
optionsList.append( containers );
|
|
|
629 |
|
|
|
630 |
// pad out label for room for the checkbox
|
|
|
631 |
if( instance.options.checkboxAutoFit && instance.options.showCheckbox && !optionsWrap.hasClass('hide-checkbox') ) {
|
|
|
632 |
var chkbx = optionsList.find('.ms-reflow:eq(0) input[type="checkbox"]');
|
|
|
633 |
if( chkbx.length ) {
|
|
|
634 |
var checkboxWidth = chkbx.outerWidth();
|
|
|
635 |
checkboxWidth = checkboxWidth ? checkboxWidth : 15;
|
|
|
636 |
|
|
|
637 |
optionsList.find('.ms-reflow label').css(
|
|
|
638 |
'padding-left',
|
|
|
639 |
(parseInt( chkbx.closest('label').css('padding-left') ) * 2) + checkboxWidth
|
|
|
640 |
);
|
|
|
641 |
|
|
|
642 |
optionsList.find('.ms-reflow').removeClass('ms-reflow');
|
|
|
643 |
}
|
|
|
644 |
}
|
|
|
645 |
|
|
|
646 |
// update placeholder text
|
|
|
647 |
instance._updatePlaceholderText();
|
|
|
648 |
|
|
|
649 |
// RESET COLUMN STYLES
|
|
|
650 |
optionsWrap.find('ul').css({
|
|
|
651 |
'column-count' : '',
|
|
|
652 |
'column-gap' : '',
|
|
|
653 |
'-webkit-column-count': '',
|
|
|
654 |
'-webkit-column-gap' : '',
|
|
|
655 |
'-moz-column-count' : '',
|
|
|
656 |
'-moz-column-gap' : ''
|
|
|
657 |
});
|
|
|
658 |
|
|
|
659 |
// COLUMNIZE
|
|
|
660 |
if( select.find('optgroup').length ) {
|
|
|
661 |
// float non grouped options
|
|
|
662 |
optionsList.find('> li:not(.optgroup)').css({
|
|
|
663 |
'float': 'left',
|
|
|
664 |
width: (100 / instance.options.columns) +'%'
|
|
|
665 |
});
|
|
|
666 |
|
|
|
667 |
// add CSS3 column styles
|
|
|
668 |
optionsList.find('li.optgroup').css({
|
|
|
669 |
clear: 'both'
|
|
|
670 |
}).find('> ul').css({
|
|
|
671 |
'column-count' : instance.options.columns,
|
|
|
672 |
'column-gap' : 0,
|
|
|
673 |
'-webkit-column-count': instance.options.columns,
|
|
|
674 |
'-webkit-column-gap' : 0,
|
|
|
675 |
'-moz-column-count' : instance.options.columns,
|
|
|
676 |
'-moz-column-gap' : 0
|
|
|
677 |
});
|
|
|
678 |
|
|
|
679 |
// for crappy IE versions float grouped options
|
|
|
680 |
if( this._ieVersion() && (this._ieVersion() < 10) ) {
|
|
|
681 |
optionsList.find('li.optgroup > ul > li').css({
|
|
|
682 |
'float': 'left',
|
|
|
683 |
width: (100 / instance.options.columns) +'%'
|
|
|
684 |
});
|
|
|
685 |
}
|
|
|
686 |
}
|
|
|
687 |
else {
|
|
|
688 |
// add CSS3 column styles
|
|
|
689 |
optionsList.css({
|
|
|
690 |
'column-count' : instance.options.columns,
|
|
|
691 |
'column-gap' : 0,
|
|
|
692 |
'-webkit-column-count': instance.options.columns,
|
|
|
693 |
'-webkit-column-gap' : 0,
|
|
|
694 |
'-moz-column-count' : instance.options.columns,
|
|
|
695 |
'-moz-column-gap' : 0
|
|
|
696 |
});
|
|
|
697 |
|
|
|
698 |
// for crappy IE versions float grouped options
|
|
|
699 |
if( this._ieVersion() && (this._ieVersion() < 10) ) {
|
|
|
700 |
optionsList.find('> li').css({
|
|
|
701 |
'float': 'left',
|
|
|
702 |
width: (100 / instance.options.columns) +'%'
|
|
|
703 |
});
|
|
|
704 |
}
|
|
|
705 |
}
|
|
|
706 |
|
|
|
707 |
// update un/select all logic
|
|
|
708 |
instance._updateSelectAllText();
|
|
|
709 |
},
|
|
|
710 |
|
|
|
711 |
/* UPDATE MULTISELECT CONFIG OPTIONS */
|
|
|
712 |
settings: function( options ) {
|
|
|
713 |
this.options = $.extend( true, {}, this.options, options );
|
|
|
714 |
this.reload();
|
|
|
715 |
},
|
|
|
716 |
|
|
|
717 |
/* RESET THE DOM */
|
|
|
718 |
unload: function() {
|
|
|
719 |
$(this.element).siblings('#ms-list-'+ this.listNumber +'.ms-options-wrap').remove();
|
|
|
720 |
$(this.element).show(function(){
|
|
|
721 |
$(this).css('display','').removeClass('jqmsLoaded');
|
|
|
722 |
});
|
|
|
723 |
},
|
|
|
724 |
|
|
|
725 |
/* RELOAD JQ MULTISELECT LIST */
|
|
|
726 |
reload: function() {
|
|
|
727 |
// remove existing options
|
|
|
728 |
$(this.element).siblings('#ms-list-'+ this.listNumber +'.ms-options-wrap').remove();
|
|
|
729 |
$(this.element).removeClass('jqmsLoaded');
|
|
|
730 |
|
|
|
731 |
// load element
|
|
|
732 |
this.load();
|
|
|
733 |
},
|
|
|
734 |
|
|
|
735 |
// RESET BACK TO DEFAULT VALUES & RELOAD
|
|
|
736 |
reset: function() {
|
|
|
737 |
var defaultVals = [];
|
|
|
738 |
$(this.element).find('option').each(function(){
|
|
|
739 |
if( $(this).prop('defaultSelected') ) {
|
|
|
740 |
defaultVals.push( $(this).val() );
|
|
|
741 |
}
|
|
|
742 |
});
|
|
|
743 |
|
|
|
744 |
$(this.element).val( defaultVals );
|
|
|
745 |
|
|
|
746 |
this.reload();
|
|
|
747 |
},
|
|
|
748 |
|
|
|
749 |
disable: function( status ) {
|
|
|
750 |
status = (typeof status === 'boolean') ? status : true;
|
|
|
751 |
$(this.element).prop( 'disabled', status );
|
|
|
752 |
$(this.element).siblings('#ms-list-'+ this.listNumber +'.ms-options-wrap').find('button:first-child')
|
|
|
753 |
.prop( 'disabled', status );
|
|
|
754 |
},
|
|
|
755 |
|
|
|
756 |
/** PRIVATE FUNCTIONS **/
|
|
|
757 |
// update the un/select all texts based on selected options and visibility
|
|
|
758 |
_updateSelectAllText: function(){
|
|
|
759 |
if( !this.updateSelectAll ) {
|
|
|
760 |
return;
|
|
|
761 |
}
|
|
|
762 |
|
|
|
763 |
var instance = this;
|
|
|
764 |
|
|
|
765 |
// select all not used at all so just do nothing
|
|
|
766 |
if( !instance.options.selectAll && !instance.options.selectGroup ) {
|
|
|
767 |
return;
|
|
|
768 |
}
|
|
|
769 |
|
|
|
770 |
var optionsWrap = $(instance.element).siblings('#ms-list-'+ instance.listNumber +'.ms-options-wrap').find('> .ms-options');
|
|
|
771 |
|
|
|
772 |
// update un/select all text
|
|
|
773 |
optionsWrap.find('.ms-selectall').each(function(){
|
|
|
774 |
var unselected = $(this).parent().find('li:not(.optgroup,.selected,.ms-hidden)');
|
|
|
775 |
|
|
|
776 |
$(this).text(
|
|
|
777 |
unselected.length ? instance.options.texts.selectAll : instance.options.texts.unselectAll
|
|
|
778 |
);
|
|
|
779 |
});
|
|
|
780 |
},
|
|
|
781 |
|
|
|
782 |
// update selected placeholder text
|
|
|
783 |
_updatePlaceholderText: function(){
|
|
|
784 |
if( !this.updatePlaceholder ) {
|
|
|
785 |
return;
|
|
|
786 |
}
|
|
|
787 |
|
|
|
788 |
var instance = this;
|
|
|
789 |
var select = $(instance.element);
|
|
|
790 |
var selectVals = select.val() ? select.val() : [];
|
|
|
791 |
var placeholder = select.siblings('#ms-list-'+ instance.listNumber +'.ms-options-wrap').find('> button:first-child');
|
|
|
792 |
var placeholderTxt = placeholder.find('span');
|
|
|
793 |
var optionsWrap = select.siblings('#ms-list-'+ instance.listNumber +'.ms-options-wrap').find('> .ms-options');
|
|
|
794 |
|
|
|
795 |
// if there are disabled options get those values as well
|
|
|
796 |
if( select.find('option:selected:disabled').length ) {
|
|
|
797 |
selectVals = [];
|
|
|
798 |
select.find('option:selected').each(function(){
|
|
|
799 |
selectVals.push( $(this).val() );
|
|
|
800 |
});
|
|
|
801 |
}
|
|
|
802 |
|
|
|
803 |
// get selected options
|
|
|
804 |
var selOpts = [];
|
|
|
805 |
for( var key in selectVals ) {
|
|
|
806 |
// Prevent prototype methods injected into options from being iterated over.
|
|
|
807 |
if( !selectVals.hasOwnProperty( key ) ) {
|
|
|
808 |
continue;
|
|
|
809 |
}
|
|
|
810 |
|
|
|
811 |
selOpts.push(
|
|
|
812 |
$.trim( select.find('option[value="'+ instance._escapeSelector( selectVals[ key ] ) +'"]').text() )
|
|
|
813 |
);
|
|
|
814 |
|
|
|
815 |
if( selOpts.length >= instance.options.maxPlaceholderOpts ) {
|
|
|
816 |
break;
|
|
|
817 |
}
|
|
|
818 |
}
|
|
|
819 |
|
|
|
820 |
// UPDATE PLACEHOLDER TEXT WITH OPTIONS SELECTED
|
|
|
821 |
placeholderTxt.text( selOpts.join( ', ' ) );
|
|
|
822 |
|
|
|
823 |
if( selOpts.length ) {
|
|
|
824 |
optionsWrap.closest('.ms-options-wrap').addClass('ms-has-selections');
|
|
|
825 |
}
|
|
|
826 |
else {
|
|
|
827 |
optionsWrap.closest('.ms-options-wrap').removeClass('ms-has-selections');
|
|
|
828 |
}
|
|
|
829 |
|
|
|
830 |
// replace placeholder text
|
|
|
831 |
if( !selOpts.length ) {
|
|
|
832 |
placeholderTxt.text( instance.options.texts.placeholder );
|
|
|
833 |
}
|
|
|
834 |
// if copy is larger than button width use "# selected"
|
|
|
835 |
else if( (placeholderTxt.width() > placeholder.width()) || (selOpts.length != selectVals.length) ) {
|
|
|
836 |
placeholderTxt.text( selectVals.length + instance.options.texts.selectedOptions );
|
|
|
837 |
}
|
|
|
838 |
},
|
|
|
839 |
|
|
|
840 |
// Add option to the custom dom list
|
|
|
841 |
_addOption: function( container, option ) {
|
|
|
842 |
var instance = this;
|
|
|
843 |
var thisOption = $('<label/>', {
|
|
|
844 |
for : 'ms-opt-'+ msOptCounter,
|
|
|
845 |
text: option.name
|
|
|
846 |
});
|
|
|
847 |
|
|
|
848 |
var thisCheckbox = $('<input>', {
|
|
|
849 |
type : 'checkbox',
|
|
|
850 |
title: option.name,
|
|
|
851 |
id : 'ms-opt-'+ msOptCounter,
|
|
|
852 |
value: option.value
|
|
|
853 |
});
|
|
|
854 |
|
|
|
855 |
// add user defined attributes
|
|
|
856 |
if( option.hasOwnProperty('attributes') && Object.keys( option.attributes ).length ) {
|
|
|
857 |
thisCheckbox.attr( option.attributes );
|
|
|
858 |
}
|
|
|
859 |
|
|
|
860 |
if( option.checked ) {
|
|
|
861 |
container.addClass('default selected');
|
|
|
862 |
thisCheckbox.prop( 'checked', true );
|
|
|
863 |
}
|
|
|
864 |
|
|
|
865 |
thisOption.prepend( thisCheckbox );
|
|
|
866 |
|
|
|
867 |
var searchTerm = '';
|
|
|
868 |
if( instance.options.searchOptions.searchText ) {
|
|
|
869 |
searchTerm += ' ' + option.name.toLowerCase();
|
|
|
870 |
}
|
|
|
871 |
if( instance.options.searchOptions.searchValue ) {
|
|
|
872 |
searchTerm += ' ' + option.value.toLowerCase();
|
|
|
873 |
}
|
|
|
874 |
|
|
|
875 |
container.attr( 'data-search-term', $.trim( searchTerm ) ).prepend( thisOption );
|
|
|
876 |
|
|
|
877 |
msOptCounter = msOptCounter + 1;
|
|
|
878 |
},
|
|
|
879 |
|
|
|
880 |
// check ie version
|
|
|
881 |
_ieVersion: function() {
|
|
|
882 |
var myNav = navigator.userAgent.toLowerCase();
|
|
|
883 |
return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
|
|
|
884 |
},
|
|
|
885 |
|
|
|
886 |
// escape selector
|
|
|
887 |
_escapeSelector: function( string ) {
|
|
|
888 |
if( typeof $.escapeSelector == 'function' ) {
|
|
|
889 |
return $.escapeSelector( string );
|
|
|
890 |
}
|
|
|
891 |
else {
|
|
|
892 |
return string.replace(/[!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
|
893 |
}
|
|
|
894 |
}
|
|
|
895 |
};
|
|
|
896 |
|
|
|
897 |
// ENABLE JQUERY PLUGIN FUNCTION
|
|
|
898 |
$.fn.multiselect = function( options ){
|
|
|
899 |
if( !this.length ) {
|
|
|
900 |
return;
|
|
|
901 |
}
|
|
|
902 |
|
|
|
903 |
var args = arguments;
|
|
|
904 |
var ret;
|
|
|
905 |
|
|
|
906 |
// menuize each list
|
|
|
907 |
if( (options === undefined) || (typeof options === 'object') ) {
|
|
|
908 |
return this.each(function(){
|
|
|
909 |
if( !$.data( this, 'plugin_multiselect' ) ) {
|
|
|
910 |
$.data( this, 'plugin_multiselect', new MultiSelect( this, options ) );
|
|
|
911 |
}
|
|
|
912 |
});
|
|
|
913 |
} else if( (typeof options === 'string') && (options[0] !== '_') && (options !== 'init') ) {
|
|
|
914 |
this.each(function(){
|
|
|
915 |
var instance = $.data( this, 'plugin_multiselect' );
|
|
|
916 |
|
|
|
917 |
if( instance instanceof MultiSelect && typeof instance[ options ] === 'function' ) {
|
|
|
918 |
ret = instance[ options ].apply( instance, Array.prototype.slice.call( args, 1 ) );
|
|
|
919 |
}
|
|
|
920 |
|
|
|
921 |
// special destruct handler
|
|
|
922 |
if( options === 'unload' ) {
|
|
|
923 |
$.data( this, 'plugin_multiselect', null );
|
|
|
924 |
}
|
|
|
925 |
});
|
|
|
926 |
|
|
|
927 |
return ret;
|
|
|
928 |
}
|
|
|
929 |
};
|
|
|
930 |
}(jQuery));
|