UNPKG

fuelux

Version:

Base Fuel UX styles and controls

266 lines (209 loc) 6.37 kB
/* * Fuel UX Combobox * https://github.com/ExactTarget/fuelux * * Copyright (c) 2014 ExactTarget * Licensed under the BSD New license. */ // -- BEGIN UMD WRAPPER PREFACE -- // For more information on UMD visit: // https://github.com/umdjs/umd/blob/master/jqueryPlugin.js (function (factory) { if (typeof define === 'function' && define.amd) { // if AMD loader is available, register as an anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object') { // Node/CommonJS module.exports = factory(require('jquery')); } else { // OR use browser globals if AMD is not present factory(jQuery); } }(function ($) { // -- END UMD WRAPPER PREFACE -- // -- BEGIN MODULE CODE HERE -- var old = $.fn.combobox; // COMBOBOX CONSTRUCTOR AND PROTOTYPE var Combobox = function (element, options) { this.$element = $(element); this.options = $.extend({}, $.fn.combobox.defaults, options); this.$dropMenu = this.$element.find('.dropdown-menu'); this.$input = this.$element.find('input'); this.$button = this.$element.find('.btn'); this.$element.on('click.fu.combobox', 'a', $.proxy(this.itemclicked, this)); this.$element.on('change.fu.combobox', 'input', $.proxy(this.inputchanged, this)); this.$element.on('shown.bs.dropdown', $.proxy(this.menuShown, this)); // set default selection this.setDefaultSelection(); // if dropdown is empty, disable it var items = this.$dropMenu.children('li'); if( items.length === 0) { this.$button.addClass('disabled'); } }; Combobox.prototype = { constructor: Combobox, destroy: function () { this.$element.remove(); // remove any external bindings // [none] // set input value attrbute in markup this.$element.find('input').each(function () { $(this).attr('value', $(this).val()); }); // empty elements to return to original markup // [none] return this.$element[0].outerHTML; }, doSelect: function ($item) { if (typeof $item[0] !== 'undefined') { this.$selectedItem = $item; this.$input.val(this.$selectedItem.text().trim()); } else { this.$selectedItem = null; } }, menuShown: function () { if (this.options.autoResizeMenu) { this.resizeMenu(); } }, resizeMenu: function () { var width = this.$element.outerWidth(); this.$dropMenu.outerWidth(width); }, selectedItem: function () { var item = this.$selectedItem; var data = {}; if (item) { var txt = this.$selectedItem.text().trim(); data = $.extend({ text: txt }, this.$selectedItem.data()); } else { data = { text: this.$input.val() }; } return data; }, selectByText: function (text) { var $item = $([]); this.$element.find('li').each(function () { if ((this.textContent || this.innerText || $(this).text() || '').toLowerCase() === (text || '').toLowerCase()) { $item = $(this); return false; } }); this.doSelect($item); }, selectByValue: function (value) { var selector = 'li[data-value="' + value + '"]'; this.selectBySelector(selector); }, selectByIndex: function (index) { // zero-based index var selector = 'li:eq(' + index + ')'; this.selectBySelector(selector); }, selectBySelector: function (selector) { var $item = this.$element.find(selector); this.doSelect($item); }, setDefaultSelection: function () { var selector = 'li[data-selected=true]:first'; var item = this.$element.find(selector); if (item.length > 0) { // select by data-attribute this.selectBySelector(selector); item.removeData('selected'); item.removeAttr('data-selected'); } }, enable: function () { this.$element.removeClass('disabled'); this.$input.removeAttr('disabled'); this.$button.removeClass('disabled'); }, disable: function () { this.$element.addClass('disabled'); this.$input.attr('disabled', true); this.$button.addClass('disabled'); }, itemclicked: function (e) { this.$selectedItem = $(e.target).parent(); // set input text and trigger input change event marked as synthetic this.$input.val(this.$selectedItem.text().trim()).trigger('change', { synthetic: true }); // pass object including text and any data-attributes // to onchange event var data = this.selectedItem(); // trigger changed event this.$element.trigger('changed.fu.combobox', data); e.preventDefault(); // return focus to control after selecting an option this.$element.find('.dropdown-toggle').focus(); }, inputchanged: function (e, extra) { // skip processing for internally-generated synthetic event // to avoid double processing if (extra && extra.synthetic) return; var val = $(e.target).val(); this.selectByText(val); // find match based on input // if no match, pass the input value var data = this.selectedItem(); if (data.text.length === 0) { data = { text: val }; } // trigger changed event this.$element.trigger('changed.fu.combobox', data); } }; // COMBOBOX PLUGIN DEFINITION $.fn.combobox = function (option) { var args = Array.prototype.slice.call(arguments, 1); var methodReturn; var $set = this.each(function () { var $this = $(this); var data = $this.data('fu.combobox'); var options = typeof option === 'object' && option; if (!data) { $this.data('fu.combobox', (data = new Combobox(this, options))); } if (typeof option === 'string') { methodReturn = data[option].apply(data, args); } }); return (methodReturn === undefined) ? $set : methodReturn; }; $.fn.combobox.defaults = { autoResizeMenu: true }; $.fn.combobox.Constructor = Combobox; $.fn.combobox.noConflict = function () { $.fn.combobox = old; return this; }; // DATA-API $(document).on('mousedown.fu.combobox.data-api', '[data-initialize=combobox]', function (e) { var $control = $(e.target).closest('.combobox'); if (!$control.data('fu.combobox')) { $control.combobox($control.data()); } }); // Must be domReady for AMD compatibility $(function () { $('[data-initialize=combobox]').each(function () { var $this = $(this); if (!$this.data('fu.combobox')) { $this.combobox($this.data()); } }); }); // -- BEGIN UMD WRAPPER AFTERWORD -- })); // -- END UMD WRAPPER AFTERWORD --