123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /*
- * Fuel UX Selectlist
- * 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 {
- // OR use browser globals if AMD is not present
- factory(jQuery);
- }
- }(function ($) {
- // -- END UMD WRAPPER PREFACE --
- // -- BEGIN MODULE CODE HERE --
- var old = $.fn.selectlist;
- // SELECT CONSTRUCTOR AND PROTOTYPE
- var Selectlist = function (element, options) {
- this.$element = $(element);
- this.options = $.extend({}, $.fn.selectlist.defaults, options);
- this.$button = this.$element.find('.btn.dropdown-toggle');
- this.$hiddenField = this.$element.find('.hidden-field');
- this.$label = this.$element.find('.selected-label');
- this.$dropdownMenu = this.$element.find('.dropdown-menu');
- this.$element.on('click.fu.selectlist', '.dropdown-menu a', $.proxy(this.itemClicked, this));
- this.setDefaultSelection();
- if (options.resize === 'auto' || this.$element.attr('data-resize') === 'auto') {
- this.resize();
- }
- };
- Selectlist.prototype = {
- constructor: Selectlist,
- destroy: function () {
- this.$element.remove();
- // any external bindings
- // [none]
- // empty elements to return to original markup
- // [none]
- // returns string of markup
- return this.$element[0].outerHTML;
- },
- doSelect: function ($item) {
- var $selectedItem;
- this.$selectedItem = $selectedItem = $item;
- this.$hiddenField.val(this.$selectedItem.attr('data-value'));
- this.$label.html($(this.$selectedItem.children()[0]).html());
- // clear and set selected item to allow declarative init state
- // unlike other controls, selectlist's value is stored internal, not in an input
- this.$element.find('li').each(function () {
- if ($selectedItem.is($(this))) {
- $(this).attr('data-selected', true);
- } else {
- $(this).removeData('selected').removeAttr('data-selected');
- }
- });
- },
- itemClicked: function (e) {
- this.$element.trigger('clicked.fu.selectlist', this.$selectedItem);
- e.preventDefault();
- // is clicked element different from currently selected element?
- if (!($(e.target).parent().is(this.$selectedItem))) {
- this.itemChanged(e);
- }
- // return focus to control after selecting an option
- this.$element.find('.dropdown-toggle').focus();
- },
- itemChanged: function (e) {
- //selectedItem needs to be <li> since the data is stored there, not in <a>
- this.doSelect($(e.target).closest('li'));
- // pass object including text and any data-attributes
- // to onchange event
- var data = this.selectedItem();
- // trigger changed event
- this.$element.trigger('changed.fu.selectlist', data);
- },
- resize: function () {
- var width = 0;
- var newWidth = 0;
- var sizer = $('<div/>').addClass('selectlist-sizer');
- if (Boolean($(document).find('html').hasClass('fuelux'))) {
- // default behavior for fuel ux setup. means fuelux was a class on the html tag
- $(document.body).append(sizer);
- } else {
- // fuelux is not a class on the html tag. So we'll look for the first one we find so the correct styles get applied to the sizer
- $('.fuelux:first').append(sizer);
- }
- sizer.append(this.$element.clone());
- this.$element.find('a').each(function () {
- sizer.find('.selected-label').text($(this).text());
- newWidth = sizer.find('.selectlist').outerWidth();
- newWidth = newWidth + sizer.find('.sr-only').outerWidth();
- if (newWidth > width) {
- width = newWidth;
- }
- });
- if (width <= 1) {
- return;
- }
- this.$button.css('width', width);
- this.$dropdownMenu.css('width', width);
- sizer.remove();
- },
- selectedItem: function () {
- var txt = this.$selectedItem.text();
- return $.extend({
- text: txt
- }, this.$selectedItem.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 $item = this.$element.find('li[data-selected=true]').eq(0);
- if ($item.length === 0) {
- $item = this.$element.find('li').has('a').eq(0);
- }
- this.doSelect($item);
- },
- enable: function () {
- this.$element.removeClass('disabled');
- this.$button.removeClass('disabled');
- },
- disable: function () {
- this.$element.addClass('disabled');
- this.$button.addClass('disabled');
- }
- };
- // SELECT PLUGIN DEFINITION
- $.fn.selectlist = 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.selectlist');
- var options = typeof option === 'object' && option;
- if (!data) {
- $this.data('fu.selectlist', (data = new Selectlist(this, options)));
- }
- if (typeof option === 'string') {
- methodReturn = data[option].apply(data, args);
- }
- });
- return (methodReturn === undefined) ? $set : methodReturn;
- };
- $.fn.selectlist.defaults = {};
- $.fn.selectlist.Constructor = Selectlist;
- $.fn.selectlist.noConflict = function () {
- $.fn.selectlist = old;
- return this;
- };
- // DATA-API
- $(document).on('mousedown.fu.selectlist.data-api', '[data-initialize=selectlist]', function (e) {
- var $control = $(e.target).closest('.selectlist');
- if (!$control.data('fu.selectlist')) {
- $control.selectlist($control.data());
- }
- });
- // Must be domReady for AMD compatibility
- $(function () {
- $('[data-initialize=selectlist]').each(function () {
- var $this = $(this);
- if (!$this.data('fu.selectlist')) {
- $this.selectlist($this.data());
- }
- });
- });
- // -- BEGIN UMD WRAPPER AFTERWORD --
- }));
- // -- END UMD WRAPPER AFTERWORD --
|