PageSourceSearch

https://powiatminski.pl/js/jquery.selectBox.js

js powiatminski.pl collected 2026-10-02 11:56:42 UTC 41,785 bytes, 1,165 lines download raw bytes

1/*
2 * jQuery selectBox - A cosmetic, styleable replacement for SELECT elements
3 *
4 * Licensed under the MIT license: http://opensource.org/licenses/MIT
5 *
6 * v1.2.0
7 *
8 * https://github.com/marcj/jquery-selectBox
9 */
10
11
12;(function ($) {
13
14    /**
15     * SelectBox class.
16     *
17     * @param {HTMLElement|jQuery} select If it's a jQuery object, we use the first element.
18     * @param {Object}             options
19     * @constructor
20     */
21    var SelectBox = window.SelectBox = function (select, options) {
22        if (select instanceof jQuery) {
23            if (select.length > 0) {
24                select = select[0];
25            } else {
26                return;
27            }
28        }
29
30        this.typeTimer     = null;
31        this.typeSearch    = '';
32        this.isMac         = navigator.platform.match(/mac/i);
33        options            = 'object' === typeof options ? options :  {};
34        this.selectElement = select;
35
36        // Disable for iOS devices (their native controls are more suitable for a touch device)
37        if (!options.mobile && navigator.userAgent.match(/iPad|iPhone|Android|IEMobile|BlackBerry/i)) {
38            return false;
39        }
40
41        // Element must be a select control
42        if ('select' !== select.tagName.toLowerCase()) {
43            return false;
44        }
45
46        this.init(options);
47    };
48
49    /**
50     * @type {String}
51     */
52    SelectBox.prototype.version = '1.2.0';
53
54    /**
55     * @param {Object} options
56     *
57     * @returns {Boolean}
58     */
59    SelectBox.prototype.init = function (options) {
60        var select = $(this.selectElement);
61        if (select.data('selectBox-control')) {
62            return false;
63        }
64
65        var control    = $('<a class="selectBox" />')
66            , inline   = select.attr('multiple') || parseInt(select.attr('size')) > 1
67            , settings = options || {}
68            , tabIndex = parseInt(select.prop('tabindex')) || 0
69            , self     = this;
70
71        control
72            .width(select.outerWidth())
73            .addClass(select.attr('class'))
74            .attr('title', select.attr('title') || '')
75            .attr('tabindex', tabIndex)
76            .css('display', 'inline-block')
77            .bind('focus.selectBox', function () {
78                if (this !== document.activeElement && document.body !== document.activeElement) {
79                    $(document.activeElement).blur();
80                }
81                if (control.hasClass('selectBox-active')) {
82                    return;
83                }
84                control.addClass('selectBox-active');
85                select.trigger('focus');
86            })
87            .bind('blur.selectBox', function () {
88                if (!control.hasClass('selectBox-active')) {
89                    return;
90                }
91                control.removeClass('selectBox-active');
92                select.trigger('blur');
93            });
94
95        if (!$(window).data('selectBox-bindings')) {
96            $(window)
97                .data('selectBox-bindings', true)
98                .bind('scroll.selectBox', (settings.hideOnWindowScroll) ? this.hideMenus : $.noop)
99                .bind('resize.selectBox', this.hideMenus);
100        }
101
102        if (select.attr('disabled')) {
103            control.addClass('selectBox-disabled');
104        }
105
106        // Focus on control when label is clicked
107        select.bind('click.selectBox', function (event) {
108            control.focus();
109            event.preventDefault();
110        });
111
112        // Generate control
113        if (inline) {
114            // Inline controls
115            options = this.getOptions('inline');
116
117            control
118                .append(options)
119                .data('selectBox-options', options).addClass('selectBox-inline selectBox-menuShowing')
120                .bind('keydown.selectBox', function (event) {
121                    self.handleKeyDown(event);
122                })
123                .bind('keypress.selectBox',function (event) {
124                    self.handleKeyPress(event);
125                })
126                .bind('mousedown.selectBox',function (event) {
127                    if (1 !== event.which) {
128                        return;
129                    }
130                    if ($(event.target).is('A.selectBox-inline')) {
131                        event.preventDefault();
132                    }
133                    if (!control.hasClass('selectBox-focus')) {
134                        control.focus();
135                    }
136                })
137                .insertAfter(select);
138
139            // Auto-height based on size attribute
140            if (!select[0].style.height) {
141                var size = select.attr('size') ? parseInt(select.attr('size')) : 5;
142                // Draw a dummy control off-screen, measure, and remove it
143                var tmp = control
144                    .clone()
145                    .removeAttr('id')
146                    .css({
147                        position: 'absolute',
148                        top: '-9999em'
149                    })
150                    .show()
151                    .appendTo('body');
152                tmp.find('.selectBox-options').html('<li><a>\u00A0</a></li>');
153                var optionHeight = parseInt(tmp.find('.selectBox-options A:first').html('&nbsp;').outerHeight());
154                tmp.remove();
155                control.height(optionHeight * size);
156            }
157            this.disableSelection(control);
158        } else {
159            // Dropdown controls
160            var label = $('<span class="selectBox-label" />'),
161                arrow = $('<span class="selectBox-arrow" />');
162
163            // Update label
164            label.attr('class', this.getLabelClass()).html(this.getLabelHtml());
165            options = this.getOptions('dropdown');
166            options.appendTo('BODY');
167
168            control
169                .data('selectBox-options', options)
170                .addClass('selectBox-dropdown')
171                .append(label)
172                .append(arrow)
173                .bind('mousedown.selectBox', function (event) {
174                    if (1 === event.which) {
175                        if (control.hasClass('selectBox-menuShowing')) {
176                            self.hideMenus();
177                        } else {
178                            event.stopPropagation();
179                            // Webkit fix to prevent premature selection of options
180                            options
181                                .data('selectBox-down-at-x', event.screenX)
182                                .data('selectBox-down-at-y', event.screenY);
183                            self.showMenu();
184                        }
185                    }
186                })
187                .bind('keydown.selectBox', function (event) {
188                    self.handleKeyDown(event);
189                })
190                .bind('keypress.selectBox', function (event) {
191                    self.handleKeyPress(event);
192                })
193                .bind('open.selectBox',function (event, triggerData) {
194                    if (triggerData && triggerData._selectBox === true) {
195                        return;
196                    }
197                    self.showMenu();
198                })
199                .bind('close.selectBox', function (event, triggerData) {
200                    if (triggerData && triggerData._selectBox === true) {
201                        return;
202                    }
203                    self.hideMenus();
204                })
205                .insertAfter(select);
206
207            // Set label width
208            var labelWidth =
209                    control.width()
210                  - arrow.outerWidth()
211                  - (parseInt(label.css('paddingLeft')) || 0)
212                  - (parseInt(label.css('paddingRight')) || 0);
213
214            label.width(labelWidth);
215            this.disableSelection(control);
216        }
217        // Store data for later use and show the control
218        select
219            .addClass('selectBox')
220            .data('selectBox-control', control)
221            .data('selectBox-settings', settings)
222            .hide();
223    };
224
225    /**
226     * @param {String} type 'inline'|'dropdown'
227     * @returns {jQuery}
228     */
229    SelectBox.prototype.getOptions = function (type) {
230        var options;
231        var select = $(this.selectElement);
232        var self   = this;
233        // Private function to handle recursion in the getOptions function.
234        var _getOptions = function (select, options) {
235            // Loop through the set in order of element children.
236            select.children('OPTION, OPTGROUP').each(function () {
237                // If the element is an option, add it to the list.
238                if ($(this).is('OPTION')) {
239                    // Check for a value in the option found.
240                    if ($(this).length > 0) {
241                        // Create an option form the found element.
242                        self.generateOptions($(this), options);
243                    } else {
244                        // No option information found, so add an empty.
245                        options.append('<li>\u00A0</li>');
246                    }
247                } else {
248                    // If the element is an option group, add the group and call this function on it.
249                    var optgroup = $('<li class="selectBox-optgroup" />');
250                    optgroup.text($(this).attr('label'));
251                    options.append(optgroup);
252                    options = _getOptions($(this), options);
253                }
254            });
255            // Return the built strin
256            return options;
257        };
258
259        switch (type) {
260            case 'inline':
261                options = $('<ul class="selectBox-options" />');
262                options = _getOptions(select, options);
263                options
264                    .find('A')
265                    .bind('mouseover.selectBox', function (event) {
266                        self.addHover($(this).parent());
267                    })
268                    .bind('mouseout.selectBox',function (event) {
269                        self.removeHover($(this).parent());
270                    })
271                    .bind('mousedown.selectBox',function (event) {
272                        if (1 !== event.which) {
273                            return
274                        }
275                        event.preventDefault(); // Prevent options from being "dragged"
276                        if (!select.selectBox('control').hasClass('selectBox-active')) {
277                            select.selectBox('control').focus();
278                        }
279                    })
280                    .bind('mouseup.selectBox', function (event) {
281                        if (1 !== event.which) {
282                            return;
283                        }
284                        self.hideMenus();
285                        self.selectOption($(this).parent(), event);
286                    });
287
288                this.disableSelection(options);
289                return options;
290            case 'dropdown':
291                options = $('<ul class="selectBox-dropdown-menu selectBox-options" />');
292                options = _getOptions(select, options);
293
294                options
295                    .data('selectBox-select', select)
296                    .css('display', 'none')
297                    .appendTo('BODY')
298                    .find('A')
299                    .bind('mousedown.selectBox', function (event) {
300                        if (event.which === 1) {
301                            event.preventDefault(); // Prevent options from being "dragged"
302                            if (event.screenX === options.data('selectBox-down-at-x') &&
303                                event.screenY === options.data('selectBox-down-at-y')) {
304                                options.removeData('selectBox-down-at-x').removeData('selectBox-down-at-y');
305                                if (/android/i.test(navigator.userAgent.toLowerCase()) &&
306                                    /chrome/i.test(navigator.userAgent.toLowerCase())) {
307                                    self.selectOption($(this).parent());
308                                }
309                                self.hideMenus();
310                            }
311                        }
312                    })
313                    .bind('mouseup.selectBox', function (event) {
314                        if (1 !== event.which) {
315                            return;
316                        }
317                        if (event.screenX === options.data('selectBox-down-at-x') &&
318                            event.screenY === options.data('selectBox-down-at-y')) {
319                            return;
320                        } else {
321                            options.removeData('selectBox-down-at-x').removeData('selectBox-down-at-y');
322                        }
323                        self.selectOption($(this).parent());
324                        self.hideMenus();
325                    })
326                    .bind('mouseover.selectBox', function (event) {
327                        self.addHover($(this).parent());
328                    })
329                    .bind('mouseout.selectBox', function (event) {
330                        self.removeHover($(this).parent());
331                    });
332
333                // Inherit classes for dropdown menu
334                var classes = select.attr('class') || '';
335                if ('' !== classes) {
336                    classes = classes.split(' ');
337                    for (var i = 0; i < classes.length; i++) {
338                        options.addClass(classes[i] + '-selectBox-dropdown-menu');
339                    }
340
341                }
342                this.disableSelection(options);
343                return options;
344        }
345    };
346
347    /**
348     * Returns the current class of the selected option.
349     *
350     * @returns {String}
351     */
352    SelectBox.prototype.getLabelClass = function () {
353        var selected = $(this.selectElement).find('OPTION:selected');
354        return ('selectBox-label ' + (selected.attr('class') || '')).replace(/\s+$/, '');
355    };
356
357    /**
358     * Returns the current label of the selected option.
359     *
360     * @returns {String}
361     */
362    SelectBox.prototype.getLabelHtml = function () {
363        var selected = $(this.selectElement).find('OPTION:selected');
364        var labelHtml;
365        if (selected.data('icon')) {
366            labelHtml = '<i class="fa fa-'+selected.data('icon')+' fa-fw fa-lg"></i> '+selected.text();
367        } else {
368            labelHtml = selected.text();
369        }
370        return labelHtml || '\u00A0';
371    };
372
373    /**
374     * Sets the label.
375     * This method uses the getLabelClass() and getLabelHtml() methods.
376     */
377    SelectBox.prototype.setLabel = function () {
378        var select = $(this.selectElement);
379        var control = select.data('selectBox-control');
380        if (!control) {
381            return;
382        }
383
384        control
385            .find('.selectBox-label')
386            .attr('class', this.getLabelClass())
387            .html(this.getLabelHtml());
388    };
389
390    /**
391     * Destroys the SelectBox instance and shows the origin select element.
392     *
393     */
394    SelectBox.prototype.destroy = function () {
395        var select = $(this.selectElement);
396        var control = select.data('selectBox-control');
397        if (!control) {
398            return;
399        }
400
401        var options = control.data('selectBox-options');
402        options.remove();
403        control.remove();
404        select
405            .removeClass('selectBox')
406            .removeData('selectBox-control')
407            .data('selectBox-control', null)
408            .removeData('selectBox-settings')
409            .data('selectBox-settings', null)
410            .show();
411    };
412
413    /**
414     * Refreshes the option elements.
415     */
416    SelectBox.prototype.refresh = function () {
417        var select = $(this.selectElement)
418            , control = select.data('selectBox-control')
419            , type = control.hasClass('selectBox-dropdown') ? 'dropdown' : 'inline'
420            , options;
421
422        // Remove old options
423        control.data('selectBox-options').remove();
424
425        // Generate new options
426        options  = this.getOptions(type);
427        control.data('selectBox-options', options);
428
429        switch (type) {
430            case 'inline':
431                control.append(options);
432                break;
433            case 'dropdown':
434                // Update label
435                this.setLabel();
436                $("BODY").append(options);
437                break;
438        }
439
440        // Restore opened dropdown state (original menu was trashed)
441        if ('dropdown' === type && control.hasClass('selectBox-menuShowing')) {
442            this.showMenu();
443        }
444    };
445
446    /**
447     * Shows the dropdown menu.
448     */
449    SelectBox.prototype.showMenu = function () {
450        var self = this
451            , select   = $(this.selectElement)
452            , control  = select.data('selectBox-control')
453            , settings = select.data('selectBox-settings')
454            , options  = control.data('selectBox-options');
455
456        if (control.hasClass('selectBox-disabled')) {
457            return false;
458        }
459
460        this.hideMenus();
461
462        // Get top and bottom width of selectBox
463        var borderBottomWidth = parseInt(control.css('borderBottomWidth')) || 0;
464        var borderTopWidth = parseInt(control.css('borderTopWidth')) || 0;
465
466        // Get proper variables for keeping options in viewport
467        var pos = control.offset()
468            , topPositionCorrelation = (settings.topPositionCorrelation) ? settings.topPositionCorrelation : 0
469            , bottomPositionCorrelation = (settings.bottomPositionCorrelation) ? settings.bottomPositionCorrelation : 0
470            , optionsHeight = options.outerHeight()
471            , controlHeight = control.outerHeight()
472            , maxHeight = parseInt(options.css('max-height'))
473            , scrollPos = $(window).scrollTop()
474            , heightToTop = pos.top - scrollPos
475            , heightToBottom = $(window).height() - ( heightToTop + controlHeight )
476            , posTop = (heightToTop >
476 heightToBottom) && (settings.keepInViewport == null ? true : settings.keepInViewport)
477            , width = control.innerWidth() >= options.innerWidth() ? control.innerWidth() + 'px' : 'auto'
478            , top = posTop
479                  ? pos.top - optionsHeight + borderTopWidth + topPositionCorrelation
480                  : pos.top + controlHeight - borderBottomWidth - bottomPositionCorrelation;
481
482
483        // If the height to top and height to bottom are less than the max-height
484        if(heightToTop < maxHeight&& heightToBottom < maxHeight){
485
486            // Set max-height and top
487            if(posTop){
488                var maxHeightDiff = maxHeight - ( heightToTop - 5 );
489                options.css({'max-height': maxHeight - maxHeightDiff + 'px'});
490                top = top + maxHeightDiff;
491            }else{
492                var maxHeightDiff = maxHeight - ( heightToBottom - 5 );
493                options.css({'max-height': maxHeight - maxHeightDiff + 'px'});
494            }
495
496        }
497
498        // Save if position is top to options data
499        options.data('posTop',posTop);
500
501
502        // Menu position
503        options
504            .width(width)
505            .css({
506                top: top,
507                left: control.offset().left
508            })
509            // Add Top and Bottom class based on position
510            .addClass('selectBox-options selectBox-options-'+(posTop?'top':'bottom'));
511
512		if (settings.styleClass) {
513			options.addClass(settings.styleClass);
514		}
515		
516        if (select.triggerHandler('beforeopen')) {
517            return false;
518        }
519
520        var dispatchOpenEvent = function () {
521            select.triggerHandler('open', {
522                _selectBox: true
523            });
524        };
525
526        // Show menu
527        switch (settings.menuTransition) {
528            case 'fade':
529                options.fadeIn(settings.menuSpeed, dispatchOpenEvent);
530                break;
531            case 'slide':
532                options.slideDown(settings.menuSpeed, dispatchOpenEvent);
533                break;
534            default:
535                options.show(settings.menuSpeed, dispatchOpenEvent);
536                break;
537        }
538
539        if (!settings.menuSpeed) {
540            dispatchOpenEvent();
541        }
542
543        // Center on selected option
544        var li = options.find('.selectBox-selected:first');
545        this.keepOptionInView(li, true);
546        this.addHover(li);
547        control.addClass('selectBox-menuShowing selectBox-menuShowing-'+(posTop?'top':'bottom'));
548
549        $(document).bind('mousedown.selectBox', function (event) {
550            if (1 === event.which) {
551                if ($(event.target).parents().andSelf().hasClass('selectBox-options')) {
552                    return;
553                }
554                self.hideMenus();
555            }
556        });
557    };
558
559    /**
560     * Hides the menu of all instances.
561     */
562    SelectBox.prototype.hideMenus = function () {
563        if ($(".selectBox-dropdown-menu:visible").length === 0) {
564            return;
565        }
566
567        $(document).unbind('mousedown.selectBox');
568        $(".selectBox-dropdown-menu").each(function () {
569            var options = $(this)
570                , select = options.data('selectBox-select')
571                , control = select.data('selectBox-control')
572                , settings = select.data('selectBox-settings')
573                , posTop = options.data('posTop');
574
575            if (select.triggerHandler('beforeclose')) {
576                return false;
577            }
578
579            var dispatchCloseEvent = function () {
580                select.triggerHandler('close', {
581                    _selectBox: true
582                });
583            };
584            if (settings) {
585                switch (settings.menuTransition) {
586                    case 'fade':
587                        options.fadeOut(settings.menuSpeed, dispatchCloseEvent);
588                        break;
589                    case 'slide':
590                        options.slideUp(settings.menuSpeed, dispatchCloseEvent);
591                        break;
592                    default:
593                        options.hide(settings.menuSpeed, dispatchCloseEvent);
594                        break;
595                }
596                if (!settings.menuSpeed) {
597                    dispatchCloseEvent();
598                }
599                control.removeClass('selectBox-menuShowing selectBox-menuShowing-'+(posTop?'top':'bottom'));
600            } else {
601                $(this).hide();
602                $(this).triggerHandler('close', {
603                    _selectBox: true
604                });
605                $(this).removeClass('selectBox-menuShowing selectBox-menuShowing-'+(posTop?'top':'bottom'));
606            }
607
608            options.css('max-height','');
609            //Remove Top or Bottom class based on position
610            options.removeClass('selectBox-options-'+(posTop?'top':'bottom'));
611            options.data('posTop' , false);
612        });
613    };
614
615    /**
616     * Selects an option.
617     *
618     * @param {HTMLElement} li
619     * @param {DOMEvent}    event
620     * @returns {Boolean}
621     */
622    SelectBox.prototype.selectOption = function (li, event) {
623        var select = $(this.selectElement);
624        li         = $(li);
625
626        var control    = select.data('selectBox-control')
627            , settings = select.data('selectBox-settings');
628
629        if (control.hasClass('selectBox-disabled')) {
630            return false;
631        }
632
633        if (0 === li.length || li.hasClass('selectBox-disabled')) {
634            return false;
635        }
636
637        if (select.attr('multiple')) {
638            // If event.shiftKey is true, this will select all options between li and the last li selected
639            if (event.shiftKey && control.data('selectBox-last-selected')) {
640                li.toggleClass('selectBox-selected');
641                var affectedOptions;
642                if (li.index() > control.data('selectBox-last-selected').index()) {
643                    affectedOptions = li
644                        .siblings()
645                        .slice(control.data('selectBox-last-selected').index(), li.index());
646                } else {
647                    affectedOptions = li
648                        .siblings()
649                        .slice(li.index(), control.data('selectBox-last-selected').index());
650                }
651                affectedOptions = affectedOptions.not('.selectBox-optgroup, .selectBox-disabled');
652                if (li.hasClass('selectBox-selected')) {
653                    affectedOptions.addClass('selectBox-selected');
654                } else {
655                    affectedOptions.removeClass('selectBox-selected');
656                }
657            } else if ((this.isMac && event.metaKey) || (!this.isMac && event.ctrlKey)) {
658                li.toggleClass('selectBox-selected');
659            } else {
660                li.siblings().removeClass('selectBox-selected');
661                li.addClass('selectBox-selected');
662            }
663        } else {
664            li.siblings().removeClass('selectBox-selected');
665            li.addClass('selectBox-selected');
666        }
667
668        if (control.hasClass('selectBox-dropdown')) {
669            control.find('.selectBox-label').html(li.html());
670        }
671
672        // Update original control's value
673        var i = 0, selection = [];
674        if (select.attr('multiple')) {
675            control.find('.selectBox-selected A').each(function () {
676                selection[i++] = $(this).attr('rel');
677            });
678        } else {
679            selection = li.find('A').attr('rel');
680        }
681
682        // Remember most recently selected item
683        control.data('selectBox-last-selected', li);
684
685        // Change callback
686        if (select.val() !== selection) {
687            select.val(selection);
688            this.setLabel();
689            select.trigger('change');
690        }
691
692        return true;
693    };
694
695    /**
696     * Adds the hover class.
697     *
698     * @param {HTMLElement} li
699     */
700    SelectBox.prototype.addHover = function (li) {
701        li = $(li);
702        var select = $(this.selectElement)
703            , control   = select.data('selectBox-control')
704            , options = control.data('selectBox-options');
705
706        options.find('.selectBox-hover').removeClass('selectBox-hover');
707        li.addClass('selectBox-hover');
708    };
709
710    /**
711     * Returns the original HTML select element.
712     *
713     * @returns {HTMLElement}
714     */
715    SelectBox.prototype.getSelectElement = function () {
716        return this.selectElement;
717    };
718
719    /**
720     * Remove the hover class.
721     *
722     * @param {HTMLElement} li
723     */
724    SelectBox.prototype.removeHover = function (li) {
725        li = $(li);
726        var select = $(this.selectElement)
727            , control = select.data('selectBox-control')
728            , options = control.data('selectBox-options');
729
730        options.find('.selectBox-hover').removeClass('selectBox-hover');
731    };
732
733    /**
734     * Checks if the widget is in the view.
735     *
736     * @param {jQuery}      li
737     * @param {Boolean}     center
738     */
739    SelectBox.prototype.keepOptionInView = function (li, center) {
740        if (!li || li.length === 0) {
741            return;
742        }
743
744        var select = $(this.selectElement)
745            , control     = select.data('selectBox-control')
746            , options   = control.data('selectBox-options')
747            , scrollBox = control.hasClass('selectBox-dropdown') ? options : options.parent()
748            , top       = parseInt(li.offset().top -scrollBox.position().top)
749            , bottom    = parseInt(top + li.outerHeight());
750
751        if (center) {
752            scrollBox.scrollTop(li.offset().top - scrollBox.offset().top + scrollBox.scrollTop() -
753                (scrollBox.height() / 2));
754        } else {
755            if (top < 0) {
756                scrollBox.scrollTop(li.offset().top - scrollBox.offset().top + scrollBox.scrollTop());
757            }
758            if (bottom > scrollBox.height()) {
759                scrollBox.scrollTop((li.offset().top + li.outerHeight()) - scrollBox.offset().top +
760                    scrollBox.scrollTop() - scrollBox.height());
761            }
762        }
763    };
764
765    /**
766     * Handles the keyDown event.
767     * Handles open/close and arrow key functionality
768     *
769     * @param {DOMEvent}    event
770     */
771    SelectBox.prototype.handleKeyDown = function (event) {
772        var select = $(this.selectElement)
773            , control        = select.data('selectBox-control')
774            , options      = control.data('selectBox-options')
775            , settings     = select.data('selectBox-settings')
776            , totalOptions = 0, i = 0;
777
778        if (control.hasClass('selectBox-disabled')) {
779            return;
780        }
781
782        switch (event.keyCode) {
783            case 8:
784                // backspace
785                event.preventDefault();
786                this.typeSearch = '';
787                break;
788            case 9:
789            // tab
790            case 27:
791                // esc
792                this.hideMenus();
793                this.removeHover();
794                break;
795            case 13:
796                // enter
797                if (control.hasClass('selectBox-menuShowing')) {
798                    this.selectOption(options.find('LI.selectBox-hover:first'), event);
799                    if (control.hasClass('selectBox-dropdown')) {
800                        this.hideMenus();
801                    }
802                } else {
803                    this.showMenu();
804                }
805                break;
806            case 38:
807            // up
808            case 37:
809                // left
810                event.preventDefault();
811                if (control.hasClass('selectBox-menuShowing')) {
812                    var prev = options.find('.selectBox-hover').prev('LI');
813                    totalOptions = options.find('LI:not(.selectBox-optgroup)').length;
814                    i = 0;
815                    while (prev.length === 0 || prev.hasClass('selectBox-disabled') ||
816                        prev.hasClass('selectBox-optgroup')) {
817                        prev = prev.prev('LI');
818                        if (prev.length === 0) {
819                            if (settings.loopOptions) {
820                                prev = options.find('LI:last');
821                            } else {
822                                prev = options.find('LI:first');
823                            }
824                        }
825                        if (++i >= totalOptions) {
826                            break;
827                        }
828                    }
829                    this.addHover(prev);
830                    this.selectOption(prev, event);
831                    this.keepOptionInView(prev);
832                } else {
833                    this.showMenu();
834                }
835                break;
836            case 40:
837            // down
838            case 39:
839                // right
840                event.preventDefault();
841                if (control.hasClass('selectBox-menuShowing')) {
842                    var next = options.find('.selectBox-hover').next('LI');
843                    totalOptions = options.find('LI:not(.selectBox-optgroup)').length;
844                    i = 0;
845                    while (0 === next.length || next.hasClass('selectBox-disabled') ||
846                        next.hasClass('selectBox-optgroup')) {
847                        next = next.next('LI');
848                        if (next.length === 0) {
849                            if (settings.loopOptions) {
850                                next = options.find('LI:first');
851                            } else {
852                                next = options.find('LI:last');
853                            }
854                        }
855                        if (++i >= totalOptions) {
856                            break;
857                        }
858                    }
859                    this.addHover(next);
860                    this.selectOption(next, event);
861                    this.keepOptionInView(next);
862                } else {
863                    this.showMenu();
864                }
865                break;
866        }
867    };
868
869    /**
870     * Handles the keyPress event.
871     * Handles type-to-find functionality
872     *
873     * @param {DOMEvent}    event
874     */
875    SelectBox.prototype.handleKeyPress = function (event) {
876        var select = $(this.selectElement)
877            , control = select.data('selectBox-control')
878            , options = control.data('selectBox-options')
879            , self    = this;
880
881        if (control.hasClass('selectBox-disabled')) {
882            return;
883        }
884
885        switch (event.keyCode) {
886            case 9:
887            // tab
888            case 27:
889            // esc
890            case 13:
891            // enter
892            case 38:
893            // up
894            case 37:
895            // left
896            case 40:
897            // down
898            case 39:
899                // right
900                // Don't interfere with the keydown event!
901                break;
902            default:
903                // Type to find
904                if (!control.hasClass('selectBox-menuShowing')) {
905                    this.showMenu();
906                }
907                event.preventDefault();
908                clearTimeout(this.typeTimer);
909                this.typeSearch += String.fromCharCode(event.charCode || event.keyCode);
910                options.find('A').each(function () {
911                    if ($(this).text().substr(0, self.typeSearch.length).toLowerCase() === self.typeSearch.toLowerCase()) {
912                        self.addHover($(this).parent());
913                        self.selectOption($(this).parent(), event);
914                        self.keepOptionInView($(this).parent());
915                        return false;
916                    }
917                });
918                // Clear after a brief pause
919                this.typeTimer = setTimeout(function () {
920                    self.typeSearch = '';
921                }, 1000);
922                break;
923        }
924    };
925
926    /**
927     * Enables the selectBox.
928     */
929    SelectBox.prototype.enable = function () {
930        var select = $(this.selectElement);
931        select.prop('disabled', false);
932        var control = select.data('selectBox-control');
933        if (!control) {
934            return;
935        }
936        control.removeClass('selectBox-disabled');
937    };
938
939    /**
940     * Disables the selectBox.
941     */
942    SelectBox.prototype.disable = function () {
943        var select = $(this.selectElement);
944        select.prop('disabled', true);
945        var control = select.data('selectBox-control');
946        if (!control) {
947            return;
948        }
949        control.addClass('selectBox-disabled');
950    };
951
952    /**
953     * Sets the current value.
954     *
955     * @param {String}      value
956     */
957    SelectBox.prototype.setValue = function (value) {
958        var select = $(this.selectElement);
959        select.val(value);
960        value = select.val(); // IE9's select would be null if it was set with a non-exist options value
961
962        if (null === value) { // So check it here and set it with the first option's value if possible
963            value = select.children().first().val();
964            select.val(value);
965        }
966
967        var control = select.data('selectBox-control');
968        if (!control) {
969            return;
970        }
971
972        var settings = select.data('selectBox-settings')
973            , options = control.data('selectBox-options');
974
975        // Update label
976        this.setLabel();
977
978        // Update control values
979        options.find('.selectBox-selected').removeClass('selectBox-selected');
980        options.find('A').each(function () {
981            if (typeof(value) === 'object') {
982                for (var i = 0; i < value.length; i++) {
983                    if ($(this).attr('rel') == value[i]) {
984                        $(this).parent().addClass('selectBox-selected');
985                    }
986                }
987            } else {
988                if ($(this).attr('rel') == value) {
989                    $(this).parent().addClass('selectBox-selected');
990                }
991            }
992        });
993
994        if (settings.change) {
995            settings.change.call(select);
996        }
997    };
998
999
1000
1001    /**
1002     * Disables the selection.
1003     *
1004     * @param {*} selector
1005     */
1006    SelectBox.prototype.disableSelection = function (selector) {
1007        $(selector).css('MozUserSelect', 'none').bind('selectstart', function (event) {
1008            event.preventDefault();
1009        });
1010    };
1011
1012    /**
1013     * Generates the options.
1014     *
1015     * @param {jQuery} self
1016     * @param {jQuery} options
1017     */
1018    SelectBox.prototype.generateOptions = function (self, options) {
1019        var li = $('<li />'), a = $('<a />');
1020        li.addClass(self.attr('class'));
1021        li.data(self.data());
1022        if (self.data('icon')) {
1023            a.attr('rel', self.val()).html('<i class="fa fa-'+self.data('icon')+' fa-fw fa-lg"></i> '+self.text());
1024        } else {
1025            a.attr('rel', self.val()).text(self.text());
1026        }
1027        li.append(a);
1028        if (self.attr('disabled')) {
1029            li.addClass('selectBox-disabled');
1030        }
1031        if (self.attr('selected')) {
1032            li.addClass('selectBox-selected');
1033        }
1034        options.append(li);
1035    };
1036
1037    /**
1038     * Extends the jQuery.fn object.
1039     */
1040    $.extend($.fn, {
1041
1042          /**
1043     * Sets the option elements.
1044     *
1045     * @param {String|Object} options
1046     */
1047    setOptions : function (options) {
1048        var select = $(this)
1049            , control = select.data('selectBox-control');
1050         
1051      
1052        switch (typeof(options)) {
1053            case 'string':
1054                select.html(options);
1055                break;
1056            case 'object':
1057                select.html('');
1058                for (var i in options) {
1059                    if (options[i] === null) {
1060                        continue;
1061                    }
1062                    if (typeof(options[i]) === 'object') {
1063                        var optgroup = $('<optgroup label="' + i + '" />');
1064                        for (var j in options[i]) {
1065                            optgroup.append('<option value="' + j + '">' + options[i][j] + '</option>');
1066                        }
1067                        select.append(optgroup);
1068                    } else {
1069                        var option = $('<option value="' + i + '">' + options[i] + '</option>');
1070                        select.append(option);
1071                    }
1072                }
1073                break;
1074        }
1075
1076        if (control) {
1077            // Refresh the control
1078            $(this).selectBox('refresh');
1079            // Remove old options
1080  
1081        }
1082      },
1083      
1084      
1085      
1086      selectBox: function (method, options) {
1087            var selectBox;
1088
1089            switch (method) {
1090                case 'control':
1091                    return $(this).data('selectBox-control');
1092                case 'settings':
1093                    if (!options) {
1094                        return $(this).data('selectBox-settings');
1095                    }
1096                    $(this).each(function () {
1097                        $(this).data('selectBox-settings', $.extend(true, $(this).data('selectBox-settings'), options));
1098                    });
1099                    break;
1100                case 'options':
1101                    // Getter
1102                   
1103                    if (undefined === options) {
1104                        return $(this).data('selectBox-control').data('selectBox-options');
1105                    }
1106                   
1107                    // Setter
1108                    $(this).each(function () {
1109                        $(this).setOptions(options);
1110                    });
1111                    break;
1112                case 'value':
1113                    // Empty string is a valid value
1114                    if (undefined === options) {
1115                        return $(this).val();
1116                    }
1117                    $(this).each(function () {
1118                        if (selectBox = $(this).data('selectBox')) {
1119                            selectBox.setValue(options);
1120                        }
1121                    });
1122                    break;
1123                case 'refresh':
1124                    $(this).each(function () {
1125                        if (selectBox = $(this).data('selectBox')) {
1126                            selectBox.refresh();
1127                        }
1128                    });
1129                    break;
1130                case 'enable':
1131                    $(this).each(function () {
1132                        if (selectBox = $(this).data('selectBox')) {
1133                            selectBox.enable(this);
1134                        }
1135                    });
1136                    break;
1137                case 'disable':
1138                    $(this).each(function () {
1139                        if (selectBox = $(this).data('selectBox')) {
1140                            selectBox.disable();
1141                        }
1142                    });
1143                    break;
1144                case 'destroy':
1145                    $(this).each(function () {
1146                        if (selectBox = $(this).data('selectBox')) {
1147                            selectBox.destroy();
1148                            $(this).data('selectBox', null);
1149                        }
1150                    });
1151                    break;
1152                case 'instance':
1153                    return $(this).data('selectBox');
1154                default:
1155                    $(this).each(function (idx, select) {
1156                        if (!$(select).data('selectBox')) {
1157                            $(select).data('selectBox', new SelectBox(select, method));
1158                        }
1159                    });
1160                    break;
1161            }
1162            return $(this);
1163        }
1164    });
1165})(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.