/*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 = $('