UNPKG

lu2

Version:

Simple and flexible UI component library based on native HTML and JavaScript

215 lines (185 loc) 6.97 kB
/** * @DropList.js * @author xinxuzhang * @version * Created: 15-06-30 */ (function (global, factory) { if (typeof define === 'function' && (define.amd || define.cmd)) { define(factory); } else { global.DropList = factory(); } }(this, function (require) { // require if (typeof require == 'function') { require('common/ui/Drop'); } else if (!$().drop) { if (window.console) { window.console.error('need Drop.js'); } return {}; } // 一些变量 var prefixDropList = 'ui-droplist-'; var SELECTED = 'selected'; var DISABLED = 'disabled'; // 支持jQuery调用的语法处理 $.fn.dropList = function (data, options) { return $(this).each(function() { var dropList = $(this).data('dropList'); if (!dropList) { $(this).data('dropList', new DropList($(this), data, options)); } }); }; /** * 下拉列表 * @trigger 触发下拉的按钮元素 * @data * 也可以是Function函数,表示数据是动态呈现的 * @param {Object} trigger jQuery包装器元素 * @param {Array|Function} data * 下拉列表数据,数组,例如: [{ id: 1, value: '所有评论', selected: true }, { id: 2, value: '未审核评论', disabled: true }, { id: 3, value: '通过评论' }] 也可以是Function函数,表示数据是动态呈现的。 * @param {Object} options 可选参数 */ var DropList = function(trigger, data, options) { var defaults = { // 触发元素显示的事件,‘null’直接显示;‘hover’是hover方法;‘click’是点击显示;其他为手动显示与隐藏。 eventType: 'click', offsets: { x: 0, y: 0 }, position: '4-1', selector: '', width: '', onShow: $.noop, onHide: $.noop, // this为当前点击的列表元素,支持两个参数,第一个参数为列表元素对应的数据(纯对象),第二个是当前实例对象 onSelect: $.noop }; var params = $.extend({}, defaults, options || {}); // 列表元素 var target = $('<div></div>').addClass(prefixDropList + 'x').css('width', params.width).attr({ role: 'listbox' }); if (trigger.length == 0) { return; } // 下拉三角 var arrow = trigger.find('.' + prefixDropList + 'arrow'); // 下拉三角元素的HTML代码 var htmlArrow = arrow.length ? arrow.get(0).outerHTML : ''; // trigger除去三角以外的HTML代码 var htmlLeft = $.trim(trigger.html().replace(htmlArrow, '')); // 创建列表 // 不管怎样,data需要是个有数据的数组 // 如果不符合条件,我们只能反馈没有数据 if ($.isArray(data) && data.length == 0) { data = [{ value: '没有数据', disabled: true }]; } else if ($.isArray(data) && params.selector == '') { // 1. 如果列表数据含有selected: true, 则自动重置trigger里面的内容 // 2. 如果列表数据没有selected: true, 则根据trigger的内容信息确定哪个数据是selected var hasSelected = false; var matchIndex = -1; // 遍历数据 $.each(data, function(index, obj) { if (obj.selected) { trigger.html(obj.value + htmlArrow); hasSelected = true; } if ($.trim(obj.value) == htmlLeft) { matchIndex = index; } }); // 选中项标示 if (hasSelected == false && matchIndex != -1) { data[matchIndex].selected = true; } } // 根据data组装列表 var _get = function(arr) { var html = ''; $.each(arr, function(index, obj) { // 选中列表的类名 var clSelected = ''; if (obj[SELECTED]) { clSelected = ' ' + SELECTED; } // 禁用态和非禁用使用标签区分 if (obj[DISABLED] != true) { html = html + '<a href="' + (obj.href || 'javascript:') + '" class="' + prefixDropList + 'li' + clSelected + '" data-index="' + index + '" role="option" aria-selected="' + (obj[SELECTED] || 'false') + '" data-target="' + target.attr('id') + '">' + obj.value + '</a>'; } else { html = html + '<span class="' + prefixDropList + 'li">' + obj.value + '</span>'; } }); return html; }; // 下拉面板 trigger.drop(target, { eventType: params.eventType, offsets: params.offsets, selector: params.selector, position: params.position, onShow: function() { var _data = this.data; if ($.isFunction(data)) { _data = data(); // 更新 drop.data = _data; } target.html(_get(_data)); params.onShow.apply(this, [trigger, target]); }, onHide: params.onHide }); var drop = trigger.data('drop'); drop.data = data; // 列表元素内容,事件 target.delegate('a', 'click', function() { var index = $(this).attr('data-index') * 1; if (params.eventType == 'contextmenu') { params.onSelect.call(this, drop.data[index], drop); drop.hide(); return; } if ($(this).hasClass(SELECTED) == false) { // 除去所有的selected if ($.isArray(data) && /^javas/.test($(this).attr('href'))) { $.each(data, function(i, obj) { if (obj[SELECTED]) { obj[SELECTED] = null; } if (i == index) { obj[SELECTED] = true; } }); // 缓存新的数据 drop.data = data; trigger.html($(this).html() + htmlArrow); } params.onSelect.call(this, drop.data[index], drop); } drop.hide(); }); return drop; }; return DropList; }));