/*jshint asi:true, expr:true */ /** * Plugin Name: Combo Select * Author : Vinay@Pebbleroad * Date: 23/11/2014 * Description: * Converts a select box into a searchable and keyboard friendly interface. Fallbacks to native select on mobile and tablets */ // Expose plugin as an AMD module if AMD loader is present: (function (factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object' && typeof require === 'function') { // Browserify factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function ( $, undefined ) { var pluginName = "comboSelect", dataKey = 'comboselect'; var defaults = { comboClass : 'combo-select', comboArrowClass : 'combo-arrow', comboDropDownClass : 'combo-dropdown', inputClass : 'combo-input text-input', disabledClass : 'option-disabled', hoverClass : 'option-hover', selectedClass : 'option-selected', markerClass : 'combo-marker', themeClass : '', maxHeight : 200, extendStyle : true, focusInput : true }; /** * Utility functions */ var keys = { ESC: 27, TAB: 9, RETURN: 13, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, ENTER: 13, SHIFT: 16 }, isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())); /** * Constructor * @param {[Node]} element [Select element] * @param {[Object]} options [Option object] */ function Plugin ( element, options ) { /* Name of the plugin */ this._name = pluginName; /* Reverse lookup */ this.el = element /* Element */ this.$el = $(element) /* If multiple select: stop */ if(this.$el.prop('multiple')) return; /* Settings */ this.settings = $.extend( {}, defaults, options, this.$el.data() ); /* Defaults */ this._defaults = defaults; /* Options */ this.$options = this.$el.find('option, optgroup') /* Initialize */ this.init(); /* Instances */ $.fn[ pluginName ].instances.push(this); } $.extend(Plugin.prototype, { init: function () { /* Construct the comboselect */ this._construct(); /* Add event bindings */ this._events(); }, _construct: function(){ var self = this /** * Add negative TabIndex to `select` * Preserves previous tabindex */ this.$el.data('plugin_'+ dataKey + '_tabindex', this.$el.prop('tabindex')) /* Add a tab index for desktop browsers */ !isMobile && this.$el.prop("tabIndex", -1) /** * Wrap the Select */ this.$container = this.$el.wrapAll('
').parent(); /** * Check if select has a width attribute */ if(this.settings.extendStyle && this.$el.attr('style')){ this.$container.attr('style', this.$el.attr("style")) } /** * Append dropdown arrow */ this.$arrow = $('
').appendTo(this.$container) /** * Append dropdown */ this.$dropdown = $('