/* * Fuel UX Combobox * https://github.com/ExactTarget/fuelux * * Copyright (c) 2012 ExactTarget * Licensed under the MIT license. */ define(['require','jquery','./util'],function (require) { var $ = require('jquery'); require('./util'); // COMBOBOX CONSTRUCTOR AND PROTOTYPE var Combobox = function (element, options) { this.$element = $(element); this.options = $.extend({}, $.fn.combobox.defaults, options); this.$element.on('click', 'a', $.proxy(this.itemclicked, this)); this.$element.on('change', 'input', $.proxy(this.inputchanged, this)); this.$input = this.$element.find('input'); this.$button = this.$element.find('.btn'); // set default selection this.setDefaultSelection(); }; Combobox.prototype = { constructor: Combobox, selectedItem: function () { var item = this.$selectedItem; var data = {}; if (item) { var txt = this.$selectedItem.text(); data = $.extend({ text: txt }, this.$selectedItem.data()); } else { data = { text: this.$input.val()}; } return data; }, selectByText: function (text) { var selector = 'li:fuelTextExactCI(' + text + ')'; this.selectBySelector(selector); }, 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); if (typeof $item[0] !== 'undefined') { this.$selectedItem = $item; this.$input.val(this.$selectedItem.text()); } else { this.$selectedItem = null; } }, 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.$input.removeAttr('disabled'); this.$button.removeClass('disabled'); }, disable: function () { 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()).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', data); e.preventDefault(); }, 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', data); } }; // COMBOBOX PLUGIN DEFINITION $.fn.combobox = function (option, value) { var methodReturn; var $set = this.each(function () { var $this = $(this); var data = $this.data('combobox'); var options = typeof option === 'object' && option; if (!data) $this.data('combobox', (data = new Combobox(this, options))); if (typeof option === 'string') methodReturn = data[option](value); }); return (methodReturn === undefined) ? $set : methodReturn; }; $.fn.combobox.defaults = {}; $.fn.combobox.Constructor = Combobox; // COMBOBOX DATA-API $(function () { $(window).on('load', function () { $('.combobox').each(function () { var $this = $(this); if ($this.data('combobox')) return; $this.combobox($this.data()); }); }); $('body').on('mousedown.combobox.data-api', '.combobox', function (e) { var $this = $(this); if ($this.data('combobox')) return; $this.combobox($this.data()); }); }); });