/**
* 排序插件
*
* @file table列排序插件
* @author Brian Li(lbxxlht@163.com)
*
* 宿主fire的事件
* sorted
*
* 暴露的API
* .sort(column, desc)
*/
var define = typeof define === 'function' && define.amd ? define : function (factory) {
typeof module === 'object' ? (module.exports = factory(require)) : '';
};
define(function (require) {
var util = require('../core/util');
var Plugin = require('../core/plugin');
// public /////////////////////////////////////////////////////////////////
/**
* 构造函数
*
* @constructor
* @param {Object} param 初始化对象
* @param {Array.<Function>} param.sorter 排序方法队列
*/
function TableSorter(param) {
if (!(this instanceof TableSorter)) {
return new TableSorter(param);
}
param = param || {};
this.required = ['TableHeader'];
// 排序方法队列
this.sorters = param.sorter || [];
// 升序状态队列,升序应当为排序方法默认的顺序
this.sortAsce = [];
for (var n = 0; n < this.sorters.length; n++) {
this.sortAsce.push(true);
}
Plugin.call(this, param);
}
util.inherit(TableSorter, Plugin);
/**
* 初始化
*
* @override
* @param {Object} param 宿主UI初始化时的参数引用,***操作请小心***
* @return {boolean} 是否初始化成功
*/
TableSorter.prototype.load = function (param) {
util.appendHandler(param, 'click', headerClickHandler);
param.pluginSkin = util.joinClassName(param.pluginSkin, 'table-sorter');
param.tpl = extendTPL(param.tpl, param.fields, this.sorters);
extendAPI(this.host, this);
return true;
};
/**
* 排序
*
* @param {number} column 排序列或排序方法索引号,由0开始,代表第一个排序方法,对应第一列列头的click。
* @param {boolean | null} desc 是否为降序,若此处不指定,则按照升序排列
*/
TableSorter.prototype.sort = function (column, desc) {
var sorter = this.sorters[column];
if (typeof sorter !== 'function') {
return;
}
if (desc === undefined) {
desc = false;
}
var table = this.host;
var datasource = table.datasource;
datasource.sort(sorter);
if (desc) {
datasource.reverse();
}
table.datasource = datasource;
table.render();
this.sortAsce[column] = desc;
var th = table.container.getElementsByClassName('th');
if (th[column] instanceof HTMLElement) {
th[column].className = th[column].className + ' ' + (desc ? 'desc' : 'asce');
}
this.host.fire('sorted', {column: column});
};
return TableSorter;
// private /////////////////////////////////////////////////////////////////
/**
* 扩展宿主对象API
*
* @param {Table} table table实例
* @param {TableSorter} sorter TableSorter排序实例
*/
function extendAPI(table, sorter) {
table.sort = function (a, b) {
return sorter.sort(a, b);
};
}
/**
* 对模版进行扩充
*
* @param {Array.<string>} tpl 原始模板
* @param {Array.<Field>} fields table列配置
* @param {Array.<Function>} sorters 排序方法队列
* @return {Array.<string>} 扩展后的模板
*/
function extendTPL(tpl, fields, sorters) {
var picker = new util.Picker(tpl);
for (var n = 0; n < sorters.length; n++) {
if (typeof sorters[n] !== 'function') {
continue;
}
var button = [
'<div class="iconfont" data-ui-level="sort-button" data-ui-column="' + n + '">',
'</div>'
];
picker.find('.table-head [data-ui-column="' + n + '"]').head(button);
}
return picker.export();
}
/**
* 表头点击事件处理
*
* @param {Event} event 事件句柄
*/
function headerClickHandler(event) {
var tag = event.target;
var dataset = util.getDataset(tag);
var level = dataset.uiLevel;
var column = dataset.uiColumn === undefined ? -1 : ~~dataset.uiColumn;
if (level !== 'sort-button' || column < 0) {
return;
}
this.plugin.TableSorter.sort(column, !this.plugin.TableSorter.sortAsce[column]);
}
});
|