PageSourceSearch

https://www.axilaris.de/files/axilaris/assets/multiselect/jquery.multiselect.js?v=2692781f

js axilaris.de collected 2026-10-08 02:43:22 UTC 41,626 bytes, 966 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.