New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

datagrid

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

datagrid - npm Package Compare versions

Comparing version 0.3.6 to 0.4.0

declaration/core/index.d.ts

1997

dist/datagrid.js

@@ -1,1293 +0,794 @@

(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["Datagrid"] = factory();
else
root["Datagrid"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/*!
* datagrid v0.4.0
* https://github.com/lmk123/datagrid
* Released under the MIT License.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.datagrid = {})));
}(this, (function (exports) { 'use strict';
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
function __$styleInject(css, returnValue) {
if (typeof document === 'undefined') {
return returnValue;
}
css = css || '';
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
head.appendChild(style);
if (style.styleSheet){
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
return returnValue;
}
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/*!
* tinyemitter.js v1.0.1
* https://github.com/lmk123/tinyemitter
* Released under the MIT License.
*/
var TinyEmitter = /** @class */ (function () {
function TinyEmitter() {
this.e = {};
}
TinyEmitter.prototype.on = function (name, handle) {
var e = this.e;
(e[name] || (e[name] = [])).push(handle);
};
TinyEmitter.prototype.off = function (name, handle) {
var e = this.e;
if (!handle) {
delete e[name];
return;
}
var events = e[name];
if (!events)
{ return; }
var i = events.indexOf(handle);
if (i >= 0) {
if (events.length === 1) {
delete e[name];
}
else {
// 使用新数组替代原本的数组,
// 这是为了避免在回调函数内调用 off 方法时改变了数组导致前面的回调函数被跳过
e[name] = events.filter(function (h) { return h !== handle; });
}
}
};
TinyEmitter.prototype.emit = function (name) {
var arguments$1 = arguments;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments$1[_i];
}
var events = this.e[name];
if (!events)
{ return; }
events.forEach(function (handle) {
handle.apply(null, args);
});
};
return TinyEmitter;
}());
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
var template = "<div class=scroll-container><table><thead><tr></tr></thead><tbody></tbody></table></div><div class=modal><div class=modal-content></div></div>";
/******/ // Flag the module as loaded
/******/ module.loaded = true;
__$styleInject(".datagrid{position:relative}.datagrid .modal{display:none;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:absolute;top:0;left:0;right:0;bottom:0;background-color:#fff}.datagrid.show-modal .modal{display:-webkit-box;display:-ms-flexbox;display:flex}.datagrid .scroll-container{height:100%;overflow:scroll}.datagrid table{min-width:100%;border-collapse:collapse;border-spacing:0}.datagrid td{word-wrap:break-word;word-break:break-all}",undefined);
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/**
* @fileOverview 输出一个最基本的、仅包含核心功能的表格类。
*/
function defaultThRenderer(column) {
return column.key;
}
function defaultTdRenderer(column, row) {
return row[column.key];
}
/**
* 根据内容的类型选择不同的方式填充节点。
* @param node 需要填充的节点。
* @param content 内容可以是字符串或者一个节点。如果有多个节点,可以传入一个 Fragment 对象。
*/
function fillNode(node, content) {
if (typeof content === 'string') {
node.innerHTML = content;
}
else {
node.appendChild(content);
}
}
var fragment = document.createDocumentFragment();
// 下面的一些 protected 关键字是因为一个 bug 才被注释掉的,
// @see https://github.com/Microsoft/TypeScript/issues/17744
var BaseGrid = (function (TinyEmitter$$1) {
function BaseGrid(options) {
if ( options === void 0 ) options = {};
TinyEmitter$$1.call(this);
/* tslint:disable:member-ordering */
this.el = document.createElement('div');
/* protected */ this.ui = {};
this.options = Object.assign({
td: defaultTdRenderer,
th: defaultThRenderer
}, options);
this.parent = options && options.parent;
var ref = this;
var el = ref.el;
el.className = 'datagrid';
el.innerHTML = template;
var thead = el.getElementsByTagName('thead')[0];
Object.assign(this.ui, {
scrollContainer: el.getElementsByClassName('scroll-container')[0],
table: el.getElementsByTagName('table')[0],
thead: thead,
theadRow: thead.firstElementChild,
tbody: el.getElementsByTagName('tbody')[0],
modal: el.getElementsByClassName('modal-content')[0]
});
}
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
if ( TinyEmitter$$1 ) BaseGrid.__proto__ = TinyEmitter$$1;
BaseGrid.prototype = Object.create( TinyEmitter$$1 && TinyEmitter$$1.prototype );
BaseGrid.prototype.constructor = BaseGrid;
/** 根据数据生成表格内容。 */
BaseGrid.prototype.setData = function setData (data) {
var this$1 = this;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
var columns = data.columns; if ( columns === void 0 ) columns = [];
var rows = data.rows; if ( rows === void 0 ) rows = [];
this.curData = {
columns: columns,
rows: rows
};
var ref = this.ui;
var theadRow = ref.theadRow;
var tbody = ref.tbody;
// 首先重新渲染表头
if (columns.length) {
columns.forEach(function (column, index) {
if (typeof column === 'string') {
column = {
key: column
};
}
var th = document.createElement('th');
fillNode(th, this$1.options.th(column, index));
this$1.emit('after th render', th, column, index);
fragment.appendChild(th);
});
theadRow.textContent = '';
theadRow.appendChild(fragment);
}
else {
theadRow.textContent = '';
}
// 然后渲染表格
if (rows.length) {
rows.forEach(function (row, rowIndex) {
var tr = document.createElement('tr');
columns.forEach(function (column, columnIndex) {
if (typeof column === 'string') {
column = {
key: column
};
}
var td = document.createElement('td');
fillNode(td, this$1.options.td(column, row, columnIndex, rowIndex));
this$1.emit('after td render', td, column, row, rowIndex, columnIndex);
tr.appendChild(td);
});
fragment.appendChild(tr);
});
tbody.textContent = '';
tbody.appendChild(fragment);
this.hideModal();
}
else {
tbody.textContent = '';
this.showModal();
}
};
/** 显示一段消息。默认会显示“暂无数据” */
BaseGrid.prototype.showModal = function showModal (html) {
if ( html === void 0 ) html = '暂无数据';
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
this.ui.modal.innerHTML = html;
this.el.classList.add('show-modal');
};
/** 隐藏消息。 */
BaseGrid.prototype.hideModal = function hideModal () {
this.el.classList.remove('show-modal');
};
/**
* 销毁对象。
* @param remove 如果为 true,则从 DOM 中删除元素。
*/
BaseGrid.prototype.destroy = function destroy (remove) {
if (remove) {
var ref = this;
var el = ref.el;
var parentElement = el.parentElement;
if (parentElement) {
parentElement.removeChild(el);
}
}
};
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
return BaseGrid;
}(TinyEmitter));
module.exports = __webpack_require__(1)
module.exports.Selection = __webpack_require__(12)
module.exports.Paging = __webpack_require__(15)
module.exports.Sorting = __webpack_require__(19)
module.exports.ColumnMove = __webpack_require__(22)
module.exports.ColumnFixed = __webpack_require__(25)
/**
* 在事件目标上注册一个事件,并返回取消事件的函数。
* @param target 事件目标
* @param event 事件名称
* @param handler 事件处理函数
*/
var addEvent = function (target, event, handler) {
target.addEventListener(event, handler);
return function () {
target.removeEventListener(event, handler);
};
};
// https://caniuse.com/#feat=requestanimationframe
var raf = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
// @ts-ignore
window.mozRequestAnimationFrame ||
function (cb) {
setTimeout(cb, 1000 / 60);
};
/**
* 返回一个基于 requestAnimationFrame 的节流函数。
* @param cb 要执行的函数
* @see https://css-tricks.com/debouncing-throttling-explained-examples/#article-header-id-7
*/
var rafThrottle = function (cb) {
var running = false;
return function () {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
if (!running) {
running = true;
raf(function () {
cb.apply(null, args);
running = false;
});
}
};
};
__webpack_require__(2)
var containerTemplate = __webpack_require__(6)
var Event = __webpack_require__(7)
var addEvent = __webpack_require__(8)
var extend = __webpack_require__(9)
var findParent = __webpack_require__(10)
var debounce = __webpack_require__(11)
/** 默认情况下使用 join 将参数转换成一个字符串作为唯一的缓存键 */
function generate(args) {
return args.join();
}
/**
* 返回一个能记住函数返回值的函数,避免重复计算
* @param fn 执行计算的函数
* @param generateKey 根据函数参数计算唯一的缓存键的函数
*/
var memory = function (fn, generateKey) {
if ( generateKey === void 0 ) generateKey = generate;
var DefaultWidth = 100
var CssClassNamespace = 'data-grid'
var caches = {};
return function () {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
function defaultThRenderer (columnDef) {
return columnDef.name
}
var cacheKey = generateKey(args);
return caches[cacheKey] || (caches[cacheKey] = fn.apply(null, args));
};
};
function defaultTdRenderer (columnDef, rowData) {
return rowData[columnDef.key]
}
var ref = document.createElement('div');
var style$1 = ref.style;
var vd;
/**
* 获取一个 CSS 属性在当前浏览器中可用的名字。
* @param property 属性的标准名称。
*/
var getCSSProperty = memory(function (property) {
if (property in style$1)
{ return property; }
var camelCase = property[0].toUpperCase() + property.slice(1);
var getVendorProperty = function (vendor) {
var vendorProperty = (vendor + camelCase);
if (vendorProperty in style$1) {
return vendorProperty;
}
};
if (vd) {
return getVendorProperty(vd);
}
var result;
['webkit', 'ms', 'moz', 'o'].some(function (vendor) {
var vendorProperty = getVendorProperty(vendor);
if (vendorProperty) {
result = vendorProperty;
vd = vendor;
return true;
}
return false;
});
return result;
});
var hooks = []
__$styleInject(".datagrid .fixed-header{position:absolute;top:0;left:0;right:0;background-color:#fff;overflow:hidden}",undefined);
/**
* 构造函数
* @param {HTMLElement} ele
* @param {Object} [options]
*/
function DataGrid (ele, options) {
Event.call(this)
var el = this.el = document.createElement('div')
this.options = extend({}, {
height: ele.offsetHeight // 表格的总高度
}, options)
var fixedHeader = function (Base) {
return (function (Base) {
function anonymous() {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
if (true) {
if (!ele.parentElement) {
throw new Error('Element must have a parentElement')
}
}
Base.apply(this, args);
this.fixedTHead = document.createElement('thead');
this.fixedTheadRow = document.createElement('tr');
this.fixedHeaderTable = document.createElement('table');
this.colGroup = document.createElement('colgroup');
this.unbindEvents = [];
var ref = this;
var el = ref.el;
var ui = ref.ui;
ui.thead.style.visibility = 'hidden';
// 创建一个包含表头的 div,通过 CSS 固定在滚动区域上方
var fixedHeaderWrapper = document.createElement('div');
fixedHeaderWrapper.className = 'fixed-header';
// 创建一个仅包含 thead 的表格作为固定表头
// 使用 colgroup 保持原本的表格与固定表头的单元格宽度一致
var ref$1 = this;
var fixedHeaderTable = ref$1.fixedHeaderTable;
var colGroup = ref$1.colGroup;
var fixedTHead = ref$1.fixedTHead;
var fixedTheadRow = ref$1.fixedTheadRow;
ui.fixedThead = fixedTHead;
ui.fixedTheadRow = fixedTheadRow;
fixedHeaderTable.appendChild(colGroup);
fixedTHead.appendChild(fixedTheadRow);
fixedHeaderTable.appendChild(fixedTHead);
fixedHeaderWrapper.appendChild(fixedHeaderTable);
el.appendChild(fixedHeaderWrapper);
if (!this.parent) {
var scrollContainer = ui.scrollContainer;
this.unbindEvents.push(
// 窗口大小变化后重新同步表格的宽度
// TODO: 窗口大小变化后表格的宽度似乎没有变化?
// addEvent(
// window,
// 'resize',
// rafThrottle(() => {
// this.syncFixedHeader()
// })
// ),
// 表格滚动时,使用 transform 移动固定表头的位置以获得更平滑的效果
addEvent(scrollContainer, 'scroll', rafThrottle(function () {
// 使用 transform 会比同步 scrollLeft 流畅很多
fixedHeaderTable.style[
// @ts-ignore
getCSSProperty('transform')] = "translate3d(-" + (scrollContainer.scrollLeft) + "px,0,0)";
})));
}
}
// 从 document 里删除原本的节点并保存下来,供实例销毁之后重新显示出来
this.origin = ele.parentElement.replaceChild(el, ele)
if ( Base ) anonymous.__proto__ = Base;
anonymous.prototype = Object.create( Base && Base.prototype );
anonymous.prototype.constructor = anonymous;
/** 同步表头中单元格的宽度。 */
anonymous.prototype.syncFixedHeader = function syncFixedHeader () {
var ref = this.ui;
var table = ref.table;
var theadRow = ref.theadRow;
this.colGroup.innerHTML = Array.prototype.reduce.call(theadRow.children, function (result, th) {
return (result += "<col width=\"" + (th.offsetWidth) + "\">");
}, '');
this.fixedHeaderTable.style.width = table.offsetWidth + 'px';
// 同步表头的高度
this.fixedTheadRow.style.height = theadRow.offsetHeight + 'px';
};
/** 重载 setData 方法,在渲染完表格后同步表头的内容。 */
anonymous.prototype.setData = function setData (data) {
var this$1 = this;
hooks.forEach(function (fn) { fn(this) }, this)
this._init()
}
Base.prototype.setData.call(this, data);
this.fixedTheadRow.innerHTML = this.ui.theadRow.innerHTML;
// 需要等到 fixedTable 中的 syncFixedWidth 更新完之后再同步宽度,
// 不然会出现 header 宽度不一致的问题
raf(function () {
this$1.syncFixedHeader();
});
};
anonymous.prototype.destroy = function destroy () {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
/**
* 保存插件
* @param {Function} plugin
*/
DataGrid.use = function (plugin) {
if (true) {
if (typeof plugin !== 'function') {
throw new TypeError('.use(plugin) 参数类型错误: plugin 必需是一个函数。')
}
if (plugin._installed) return
plugin._installed = true
}
plugin(DataGrid)
}
this.unbindEvents.forEach(function (unbind) { return unbind(); });
Base.prototype.destroy.apply(this, args);
};
/**
* 每次创建新的实例时都会触发这个函数
* @param {Function} fn
* @return {function()}
*/
DataGrid.hook = function (fn) {
hooks.push(fn)
return function () {
var i = hooks.indexOf(fn)
if (i >= 0) hooks.splice(i, 1)
}
}
return anonymous;
}(Base));
};
var dp = DataGrid.prototype = Object.create(Event.prototype)
dp.constructor = DataGrid
var prototype = Element.prototype;
// https://caniuse.com/#feat=matchesselector
var matches = prototype.matches ||
prototype.webkitMatchesSelector ||
prototype.msMatchesSelector;
// https://caniuse.com/#feat=element-closest
var closest = prototype.closest ||
function (s) {
var el = this;
do {
if (matches.call(el, s))
{ return el; }
el = el.parentElement;
} while (el);
return null;
};
dp._init = function () {
var _unbindEvents = this._unbindEvents = []
this.emit('beforeInit')
var el = this.el
el.classList.add(CssClassNamespace)
el.innerHTML = containerTemplate
__$styleInject(".fixed-grid{position:absolute;top:0;background:#fff}.fixed-grid .scroll-container{overflow:hidden}.fixed-grid-left{left:0}.fixed-grid-right{right:0}",undefined);
var ui = {
$gridWrapper: '.grid-wrapper',
$columnsWrapper: '.grid-columns-wrapper',
$columns: '.grid-columns',
$columnsColGroup: '.grid-columns colgroup',
$columnsThead: '.grid-columns thead',
$bodyWrapper: '.grid-body-wrapper',
$body: '.grid-body',
$bodyColGroup: '.grid-body colgroup',
$bodyTbody: '.grid-body tbody',
$noData: '.grid-no-data'
}
var ref$1 = Array.prototype;
var some = ref$1.some;
var forEach = ref$1.forEach;
var indexOf = ref$1.indexOf;
var fixedTable = function (Base) {
return (function (Base) {
function anonymous() {
var this$1 = this;
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
for (var key in ui) {
ui[key] = el.querySelector(ui[key])
}
Base.apply(this, args);
this.fixedTableEvents = [];
var ref = this.ui;
var scrollContainer = ref.scrollContainer;
if (!this.parent) {
this.fixedTableEvents.push(
// 同步表格的滚动条位置
addEvent(scrollContainer, 'scroll', rafThrottle(function () {
var ref = this$1;
var fixedTables = ref.fixedTables;
if (!fixedTables)
{ return; }
for (var place in fixedTables) {
fixedTables[place].ui.table.style[
// @ts-ignore
getCSSProperty('transform')] = "translate3d(0,-" + (scrollContainer.scrollTop) + "px,0)";
}
})),
// 同步表格的 hover 状态
addEvent(this.el, 'mouseover', function (e) {
var tr = closest.call(e.target, '.datagrid tbody tr');
if (!tr)
{ return; }
var trs = tr.parentElement.children;
var ref = this$1;
var lastHoverIndex = ref.lastHoverIndex;
var index = indexOf.call(trs, tr);
if (lastHoverIndex === index)
{ return; }
this$1.lastHoverIndex = index;
var setHover = function (grid) {
var trs = grid.ui.tbody.children;
var lastHoverTr = trs[lastHoverIndex];
if (lastHoverTr) {
lastHoverTr.classList.remove('hover-row');
}
trs[index].classList.add('hover-row');
};
setHover(this$1);
var ref$1 = this$1;
var children = ref$1.children;
if (children) {
children.forEach(setHover);
}
}));
}
}
ui.$gridWrapper.style.height = this.options.height + 'px'
if ( Base ) anonymous.__proto__ = Base;
anonymous.prototype = Object.create( Base && Base.prototype );
anonymous.prototype.constructor = anonymous;
/**
* 创建或更新固定在左侧或右侧的表格。
* @param count 固定表格的列数。
* @param place 固定表格的位置,默认为左侧。
*/
anonymous.prototype.setFixed = function setFixed (count, place) {
if ( place === void 0 ) place = 'left';
var that = this
_unbindEvents.push(
// body 横向滚动时, 也要调整 columns 的左边距
addEvent(ui.$bodyWrapper, 'scroll', function () {
ui.$columns.style.left = '-' + ui.$bodyWrapper.scrollLeft + 'px'
}),
// 鼠标移入或移出的时候,给 tr 加上 hover 状态。
// 之所以不用 css 实现,是因为 fixedGrid 需要能用 js 设置 tr 的 hover 状态
addEvent(ui.$bodyWrapper, 'mouseover', function (e) {
var tr = findParent('tr', e.target)
if (!tr) return
var trIndex = tr.getAttribute('data-index')
if (trIndex) {
that.trHover(true, Number(trIndex))
}
}),
addEvent(ui.$bodyWrapper, 'mouseout', function (e) {
var tr = findParent('tr', e.target)
if (!tr) return
var trIndex = tr.getAttribute('data-index')
if (trIndex) {
that.trHover(false, Number(trIndex))
}
}),
// 点击 cell 的时候给出一个事件
addEvent(ui.$bodyWrapper, 'click', function (e) {
var td = findParent('td', e.target)
if (!td) return
var tr = findParent('tr', td)
if (!tr) return
var tdIndex = td.getAttribute('data-index')
var trIndex = tr.getAttribute('data-index')
var renderData = that.renderData
that.emit('cellClick', renderData.columnsDef[tdIndex], that.empty ? null : renderData.rows[trIndex])
}),
// 双击 cell 的时候给出一个事件
addEvent(ui.$bodyWrapper, 'dblclick', function (e) {
var td = findParent('td', e.target)
if (!td) return
var tr = findParent('tr', td)
if (!tr) return
var tdIndex = td.getAttribute('data-index')
var trIndex = tr.getAttribute('data-index')
var renderData = that.renderData
that.emit('cellDoubleClick', renderData.columnsDef[tdIndex], that.empty ? null : renderData.rows[trIndex])
})
)
var ref = this;
var fixedTables = ref.fixedTables;
var fixedTable = fixedTables && fixedTables[place];
if (!count) {
if (fixedTable) {
fixedTable.el.style.display = 'none';
}
return;
}
if (!fixedTable) {
fixedTable = this.createFixedGrid(place);
}
var ref$1 = this;
var curData = ref$1.curData;
fixedTable.fixedColumns = count;
fixedTable.setData({
columns: place === 'left'
? curData.columns.slice(0, count)
: curData.columns.slice(-count),
rows: curData.rows
});
fixedTable.el.style.display = '';
this.syncFixedWidth(place);
};
/**
* 同步一个固定表格的宽度、高度等状态。
* @param place 要同步宽度的表格的位置。
*/
anonymous.prototype.syncFixedWidth = function syncFixedWidth (place) {
var ref = this;
var fixedTables = ref.fixedTables;
var fixedTable = fixedTables && fixedTables[place];
if (!fixedTable)
{ return; }
var fixed = fixedTable.fixedColumns;
// 同步 table 和 th 的宽度
var colHtml = '';
// let width = 0
var ths = this.ui.theadRow.children;
var thsLength = ths.length - 1;
var getTh = place === 'left'
? function (index) { return ths[index]; }
: function (index) { return ths[thsLength - index]; };
some.call(ths, function (th, index) {
if (index === fixed)
{ return true; }
var ref = getTh(index);
var offsetWidth = ref.offsetWidth;
colHtml += "<col width=\"" + offsetWidth + "\">";
// width += offsetWidth
});
// 在使用默认主题(给 th 加了右 border)的情况下,
// 给容器固定这个宽度可以让固定表格两侧的 border 不显示出来
// fixedTable.el.style.width = `${width}px`
fixedTable.ui.colgroup.innerHTML = colHtml;
// 同步表头的高度
fixedTable.ui.theadRow.style.height = this.ui.theadRow.offsetHeight + 'px';
// 同步 tr 的高度
var trs = fixedTable.ui.tbody.children;
forEach.call(this.ui.tbody.children, function (tr, index) {
trs[index].style.height =
tr.offsetHeight + 'px';
});
};
/**
* 创建固定在两侧的表格实例的方法。
* @param place 表格的位置
*/
anonymous.prototype.createFixedGrid = function createFixedGrid (place) {
var innerTable = new this.constructor(Object.assign({
parent: this
}, this.options));
innerTable.fixedPlace = place;
(this.children || (this.children = [])).push(innerTable);
(this.fixedTables || (this.fixedTables = {}))[place] = innerTable;
innerTable.el.classList.add('fixed-grid', 'fixed-grid-' + place);
var ui = innerTable.ui;
var colgroup = (ui.colgroup = document.createElement('colgroup'));
ui.table.appendChild(colgroup);
this.el.appendChild(innerTable.el);
return innerTable;
};
this.ui = ui
return anonymous;
}(Base));
};
if (this.options.fit) {
_unbindEvents.push(
addEvent(window, 'resize', debounce(function () {
that.setWidth()
}))
)
}
__$styleInject(".datagrid th.sortable{cursor:pointer}.datagrid .asc,.datagrid .desc{display:none}.datagrid .sort-by-1 .asc,.datagrid .sort-by-2 .desc{display:inline-block}",undefined);
this.emit('afterInit')
}
/* tslint:enable:no-unused-variable */
// const DESC = -1, // 降序
// ASC = 1, // 升序
// NONE = 0 // 不排序
var orderLength = 3;
var ref$2 = Array.prototype;
var indexOf$1 = ref$2.indexOf;
function defaultSortBlock() {
var fd = document.createDocumentFragment();
[
{
className: 'asc',
innerHTML: '&#8593;'
},
{
className: 'desc',
innerHTML: '&#8595;'
}
].forEach(function (element) {
var span = document.createElement('span');
Object.assign(span, element);
fd.appendChild(span);
});
return fd;
}
var sort = function (Base) {
return (function (Base) {
function anonymous() {
var this$1 = this;
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
/**
* 处理 tr 元素的 hover 状态
* @param {Boolean} inOrOut - 此元素需要添加(true)还是移除(false) hover 状态
* @param {Number} index - 元素的 index
* @param {Boolean} emit - 设为 false 则不触发相关事件
*/
dp.trHover = function (inOrOut, index, emit) {
var tbody = this.ui.$bodyTbody
var hoverToTR = tbody.querySelector('tr[data-index="' + index + '"]')
hoverToTR.classList[inOrOut ? 'add' : 'remove']('hover')
if (emit !== false) this.emit(inOrOut ? 'trHoverTo' : 'clearHover', index, hoverToTR, this.rows && this.rows[index])
}
Base.apply(this, args);
this.sortOrderIndex = 0;
var sortBlock = this.options.sortBlock || defaultSortBlock;
var appendSortBlock = typeof sortBlock === 'string'
? function (th) {
th.innerHTML += sortBlock;
}
: function (th) {
th.appendChild(sortBlock());
};
this.on('after th render', function (th, column, index) {
if (index === this$1.sortColumnIndex && this$1.sortOrderIndex) {
th.classList.add('sort-by-' + this$1.sortOrderIndex);
}
// TODO: 后期增加只针对某些 column 开启排序的功能
th.classList.add('sortable');
appendSortBlock(th);
});
if (!this.parent) {
addEvent(this.el, 'click', function (e) {
var th = closest.call(e.target, '.datagrid th');
if (!th)
{ return; }
var ths = th.parentElement.children;
var thIndex = indexOf$1.call(ths, th);
var newSortColumnIndex;
var isRightFixed = closest.call(th, '.fixed-grid-right');
if (isRightFixed) {
newSortColumnIndex =
this$1.curData.columns.length -
(this$1.fixedTables.right.fixedColumns - thIndex);
}
else {
newSortColumnIndex = thIndex;
}
var newOrderIndex;
var oldOrderIndex = this$1.sortOrderIndex;
var oldSortColumnIndex = this$1.sortColumnIndex;
if (oldSortColumnIndex !== newSortColumnIndex) {
this$1.sortColumnIndex = newSortColumnIndex;
newOrderIndex = 1;
}
else {
newOrderIndex = this$1.sortOrderIndex + 1;
if (newOrderIndex >= orderLength) {
newOrderIndex -= orderLength;
}
}
this$1.sortOrderIndex = newOrderIndex;
var setSort = function (grid) {
var columnIndex2trIndex = function (columnIndex) {
return grid.fixedPlace === 'right'
? grid.fixedColumns -
(this$1.curData.columns.length - columnIndex)
: columnIndex;
};
var ths = (grid.ui.fixedTheadRow || grid.ui.theadRow).children;
if (oldOrderIndex) {
var oldTh = ths[columnIndex2trIndex(oldSortColumnIndex)];
if (oldTh) {
oldTh.classList.remove('sort-by-' + oldOrderIndex);
}
}
if (newOrderIndex) {
var newTh = ths[columnIndex2trIndex(newSortColumnIndex)];
console.log(grid.fixedPlace === 'right'
? grid.fixedColumns -
(this$1.curData.columns.length - newSortColumnIndex)
: newSortColumnIndex);
if (newTh) {
newTh.classList.add('sort-by-' + newOrderIndex);
}
}
};
setSort(this$1);
var ref = this$1;
var children = ref.children;
if (children) {
children.forEach(setSort);
}
this$1.emit('sort', thIndex, newOrderIndex);
});
}
}
/**
* 给表格填充数据
* @param data
* @param {String[]|Object[]} data.columns - 表格的字段定义
* @param {Object[]} data.rows - 数据
* @param {Number[]} data.width - 每个字段对应的宽度
*/
dp.setData = function (data) {
this.renderData = {}
this.emit('beforeSetData', data)
this.empty = !(data.columns && data.columns.length) || (!(data.rows && data.rows.length))
if (this.empty) {
var ui = this.ui
ui.$body.classList.add('hidden')
ui.$noData.classList.remove('hidden')
} else {
this.setColumns(data.columns)
this.setBody(data.rows)
this.setWidth(data.width)
}
this.emit('afterSetData', data)
}
if ( Base ) anonymous.__proto__ = Base;
anonymous.prototype = Object.create( Base && Base.prototype );
anonymous.prototype.constructor = anonymous;
/**
* 根据用户给的宽度数组计算出实际需要用到的最小宽度数组,
* 因为用户可能不传宽度数组,或者宽度数组的长度比字段数组长或短,
* 所以要处理一遍
* @param {Array} [widthArr]
* @return {Array}
*/
dp.normalizeWidth = function (widthArr) {
var renderData = this.renderData
var columnsDef = renderData.columnsDef
if (!Array.isArray(widthArr)) widthArr = []
var result = []
for (var i = 0; i < columnsDef.length; i++) {
result[i] = widthArr[i] || Math.max((columnsDef[i].name || '').length * 15, DefaultWidth)
}
return result
}
return anonymous;
}(Base));
};
/**
* 设置宽度。
* 默认情况下,用户设置的宽度会成为最终字段的宽度,
* 但如果 fit 设置为 true,则将用户传进来的宽度视为"最小宽度",
* 如果这些最小宽度加起来大于 wrapper 的宽度,则直接使用最小宽度作为 td 的宽度;
* 如果加起来小于 wrapper 的宽度,则用 wrapper 宽度减去最小宽度的差值,除以字段的个数得到平均值,再给每个最小宽度加上这个平均值作为字段的真正宽度
* @param {Number[]} [width]
*/
dp.setWidth = function (width) {
if (this.empty) return
var obj = { width: width }
this.emit('beforeSetWidth', obj)
var renderData = this.renderData
var ref$3 = Array.prototype;
var indexOf$2 = ref$3.indexOf;
var selection = function (Base) {
return (function (Base) {
function anonymous() {
var this$1 = this;
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
var customWidth = obj.width
if (customWidth || !renderData.columnsMinWidth) {
renderData.columnsMinWidth = this.normalizeWidth(customWidth)
}
Base.apply(this, args);
if (!this.parent) {
addEvent(this.el, 'click', function (e) {
var tr = closest.call(e.target, '.datagrid tbody tr');
if (!tr)
{ return; }
var trs = tr.parentElement.children;
var trIndex = indexOf$2.call(trs, tr);
var oldSelectionIndex = this$1.selectionIndex;
if (oldSelectionIndex !== trIndex) {
this$1.selectionIndex = trIndex;
this$1.emit('select', trIndex);
var updateSelected = function (grid) {
var ref = grid.ui.tbody;
var children = ref.children;
var lastSelectedRow = children[oldSelectionIndex];
if (lastSelectedRow) {
lastSelectedRow.classList.remove('selected-row');
}
children[trIndex].classList.add('selected-row');
};
updateSelected(this$1);
var ref = this$1;
var children = ref.children;
if (children) {
children.forEach(updateSelected);
}
}
});
}
}
var columnsMinWidth = renderData.columnsMinWidth
var columnsWidth
if ( Base ) anonymous.__proto__ = Base;
anonymous.prototype = Object.create( Base && Base.prototype );
anonymous.prototype.constructor = anonymous;
if (this.options.fit) {
var sum = columnsMinWidth.reduce(function (w1, w2) {
return w1 + w2
})
var bodyWrapperWidth = this.ui.$bodyWrapper.clientWidth
if (sum >= bodyWrapperWidth) {
columnsWidth = columnsMinWidth
} else {
var diff = (bodyWrapperWidth - sum) / renderData.columnsDef.length
columnsWidth = columnsMinWidth.map(function (w) {
return Math.round(w + diff)
})
}
} else {
columnsWidth = columnsMinWidth
}
renderData.columnsWidth = columnsWidth
var cols = this._colGroupsHTML(columnsWidth)
this._renderCols(cols)
this._resize(columnsWidth)
}
return anonymous;
}(Base));
};
/**
* 计算出表格的 col 元素的 HTML
* @param {Number[]} columnsWidth - 定义字段宽度的数组
* @private
* @return {String[]}
*/
dp._colGroupsHTML = function (columnsWidth) {
return columnsWidth ? columnsWidth.map(function (width) { return '<col style="width:' + width + 'px">' }) : []
}
/* tslint:enable:no-unused-variable */
/* tslint:disable:no-duplicate-imports */
/* tslint:enable:no-duplicate-imports */
// 默认返回一个功能丰富的表格类。
// 这里的繁琐写法是为了让 TypeScript 能正确解析类型。
//
// 注意:由于同时使用了 `export` 和 `export default`,
// CommonJS 和浏览器端要使用 `default` 属性读取到这个输出。
//
// CommonJS: `const DataGrid = require('datagrid').default`
// 浏览器:`const Grid = DataGrid.default`
var index = selection(sort(fixedHeader(fixedTable(BaseGrid))));
/**
* 填充 colsHTML
* @param {String[]} colsHTML
* @private
*/
dp._renderCols = function (colsHTML) {
var ui = this.ui
ui.$columnsColGroup.innerHTML = ui.$bodyColGroup.innerHTML = colsHTML.join('')
}
exports['default'] = index;
exports.BaseGrid = BaseGrid;
exports.fixedHeader = fixedHeader;
exports.fixedTable = fixedTable;
/**
* 调整各种尺寸
* @param {Number[]} columnsWidth
* @private
*/
dp._resize = function (columnsWidth) {
var ui = this.ui
var $columns = ui.$columns
var $noData = ui.$noData
var $body = ui.$body
var _totalWidth = columnsWidth.reduce(function (prev, width) { return prev + width })
$columns.style.width = $body.style.width = _totalWidth + 'px'
if (this.empty) {
$noData.classList.remove('hidden')
} else {
$noData.classList.add('hidden')
}
}
Object.defineProperty(exports, '__esModule', { value: true });
/**
* 渲染表头的方法
* @param {String[]|Object[]} columns
* @private
*/
dp.setColumns = function (columns) {
var columnsDef = this.renderData.columnsDef = this._normalize(columns)
var columnsHTML = this._columnsHTML(columnsDef)
this.emit('beforeRenderColumns', columnsHTML)
this._renderColumns(columnsHTML)
}
/**
* 调整字段定义, 并根据字段定义计算出每个字段的宽度数组
* @param columns
* @private
*/
dp._normalize = function (columns) {
return columns.map(function (columnDef) {
var _def = typeof columnDef === 'string'
? { name: columnDef }
: columnDef
if (!_def.key) _def.key = _def.name
return _def
})
}
/**
* 计算出渲染表头字段的 HTML
* @private
*/
dp._columnsHTML = function (columnsDef) {
var customRenderer = this.options.thRenderer
return columnsDef.map(function (columnDef, index) {
var content
if (columnDef.thRenderer) {
content = columnDef.thRenderer(columnDef)
}
if (content == null) {
if (customRenderer) {
content = customRenderer(columnDef)
}
if (content == null) {
content = defaultThRenderer(columnDef)
}
}
return '<th data-index="' + index + '">' + content + '</th>'
})
}
/**
* 渲染表头
* @param {String[]} columnsHTML
* @private
*/
dp._renderColumns = function (columnsHTML) {
this.ui.$columnsThead.innerHTML = columnsHTML.join('')
}
/**
* 渲染表格的方法
* @param {Object[]} rows
*/
dp.setBody = function (rows) {
var renderData = this.renderData
this.empty = !rows || !rows.length
renderData.rows = rows
this._renderBody(renderData.trsArr = this._bodyHTML(renderData.columnsDef, rows))
}
/**
* 计算出渲染 body 需要的数据
* @private
*/
dp._bodyHTML = function (columnsDef, rows) {
var customRenderer = this.options.tdRenderer
return this.empty ? [] : rows.map(function (row, rowIndex) {
var rowHTML = '<tr data-index="' + rowIndex + '">'
columnsDef.forEach(function (columnDef, columnIndex) {
var content
if (columnDef.tdRenderer) {
content = columnDef.tdRenderer(columnDef, row)
}
if (content == null) {
if (customRenderer) {
content = customRenderer(columnDef, row)
}
if (content == null) {
content = defaultTdRenderer(columnDef, row)
}
}
rowHTML += '<td data-index="' + columnIndex + '">' + content + '</td>'
})
rowHTML += '</tr>'
return rowHTML
})
}
/**
* 渲染数据
* @param {String[]} trsArr
* @private
*/
dp._renderBody = function (trsArr) {
var ui = this.ui
ui.$bodyTbody.innerHTML = trsArr.join('')
ui.$body.classList.remove('hidden')
ui.$noData.classList.add('hidden')
}
/**
* 销毁实例
*/
dp.destroy = function () {
this.emit('beforeDestroy')
this._unbindEvents.forEach(function (unbind) { unbind() })
// 还原原本的 dom 节点
var el = this.el
try {
el.parentElement.replaceChild(this.origin, el)
} catch (e) {}
this.emit('afterDestroy')
}
module.exports = DataGrid
/***/ },
/* 2 */
/***/ function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ },
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */
/***/ function(module, exports) {
module.exports = "<div class=\"grid-wrapper\">\n <div class=\"grid-columns-wrapper\">\n <table class=\"grid-columns\">\n <colgroup></colgroup>\n <thead></thead>\n </table>\n </div>\n <div class=\"grid-body-wrapper\">\n <table class=\"grid-body\">\n <colgroup></colgroup>\n <tbody></tbody>\n </table>\n </div>\n</div>\n<div class=\"grid-no-data hidden\">\n <div class=\"no-data-content\">\n 暂无数据\n </div>\n</div>\n";
/***/ },
/* 7 */
/***/ function(module, exports) {
var slice = Array.prototype.slice
function MyEvent () {
this._callbacks = {}
}
var p = MyEvent.prototype
/**
* 注册事件监听函数
* @param {string} eventName
* @param {function()} handlerFunc
* @return {function()} - 调用此函数可以取消掉监听
*/
p.on = function (eventName, handlerFunc) {
var callbacks = this._callbacks
var eventArr = (callbacks[eventName] || (callbacks[eventName] = []))
eventArr.push(handlerFunc)
return function () {
var i = eventArr.indexOf(handlerFunc)
if (i >= 0) eventArr.splice(i, 1)
}
}
/**
* 注册事件监听函数, 但只监听一次
* @param {string} eventName
* @param {function()} handlerFunc
* @return {function()}
*/
p.once = function (eventName, handlerFunc) {
var unwatch = this.on(eventName, function () {
handlerFunc.apply(null, arguments)
// 等 emit 中的 forEach 执行完后再改变数组
window.setTimeout(unwatch, 0)
})
return unwatch
}
/**
* 发布事件
* @param {string} eventName
*/
p.emit = function (eventName/* , ...args */) {
var eventArr = this._callbacks[eventName]
if (!eventArr || !eventArr.length) return
var args = slice.call(arguments, 1)
eventArr.forEach(function (func) {
func.apply(null, args)
})
}
module.exports = MyEvent
/***/ },
/* 8 */
/***/ function(module, exports) {
/**
* 给元素注册事件, 并返回一个函数用于解绑事件
* @param {EventTarget} element
* @param {String} eventName
* @param {Function} handler
* @param {Boolean} [useCapture]
* @return {function()}
*/
module.exports = function (element, eventName, handler, useCapture) {
element.addEventListener(eventName, handler, useCapture)
return function () {
element.removeEventListener(eventName, handler, useCapture)
}
}
/***/ },
/* 9 */
/***/ function(module, exports) {
var has = Object.prototype.hasOwnProperty
module.exports = function (target) {
for (var i = 1; i < arguments.length; i += 1) {
var d = arguments[i]
if (!d || typeof d !== 'object') continue
for (var key in d) {
if (has.call(d, key)) {
target[key] = d[key]
}
}
}
return target
}
/***/ },
/* 10 */
/***/ function(module, exports) {
/**
* 寻找一个元素指定名称的父元素
* @param {String} tagName - 要寻找的元素名
* @param {HTMLElement} node - 从哪个元素开始寻找
* @param {HTMLElement} [stop] - 碰到这个元素时停止查找
* @return {null|HTMLElement}
*/
module.exports = function (tagName, node, stop) {
if (!stop) stop = document.body
var tag = tagName.toUpperCase()
var parent = node
var tr = null
do {
if (parent.tagName === tag) {
tr = parent
break
}
} while (parent !== stop && (parent = parent.parentElement))
return tr
}
/***/ },
/* 11 */
/***/ function(module, exports) {
/**
* 返回一个延迟执行的函数
* @param {Function} fn
* @param {Number} [timeout]
* @return {Function}
*/
module.exports = function (fn, timeout) {
var timeId
timeout = typeof timeout === 'number' ? timeout : 250
return function () {
if (typeof timeId === 'number') window.clearTimeout(timeId)
var args = arguments
timeId = window.setTimeout(function () {
fn.apply(null, args)
}, timeout)
}
}
/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {
// todo selection 插件的全选功能目前无法与 fixedColumns 插件共同使用
__webpack_require__(13)
var findParent = __webpack_require__(10)
var addEvent = __webpack_require__(8)
var SelectedClassName = 'selected'
module.exports = function (DataGrid) {
DataGrid.prototype.selectRow = function (index, fire) {
var $body = this.ui.$body
var tr = $body.querySelector('tr[data-index="' + index + '"]')
if (!tr) return
// 如果是多选,则判断当前点击的行是否已被选中,
// 如果已被选中,则删除选中状态,
// 否则添加选中状态
var i = this._selectRowsIndex.indexOf(index)
// 多选状态下,如果此行已被选中,则清除此行的选中状态;
// 如果没被选中,则添加选中状态
if (this._isMultipleSelect) {
if (i >= 0) {
this._selectRowsIndex.splice(i, 1)
} else {
this._selectRowsIndex.push(index)
}
} else {
// 单选状态下,如果已被选中则直接返回,不做任何操作;
// 否则删除上次选中状态并给当前行添加选中状态
if (i >= 0) return
var selectedTR = $body.querySelector('tr.' + SelectedClassName)
if (selectedTR) selectedTR.classList.remove(SelectedClassName)
tr.classList.add('selected')
this._selectRowsIndex = [index]
}
if (fire !== false) this.emit('selectedChanged', this._isMultipleSelect ? this._selectRowsIndex : index)
}
DataGrid.prototype.selectAll = function (allOrNone, fire) {
if (!this._isMultipleSelect) return
this._selectRowsIndex = []
var that = this
Array.prototype.forEach.call(this.ui.$bodyWrapper.querySelectorAll('tr[data-index]'), function (tr) {
if (allOrNone) {
var index = Number(tr.getAttribute('data-index'))
that._selectRowsIndex.push(index)
}
tr.querySelector('input[type=checkbox]').checked = allOrNone
})
if (fire !== false) this.emit('selectedChanged', this._selectRowsIndex)
}
DataGrid.hook(function (datagrid) {
var selectionType = datagrid.options.selection
if (!selectionType) return
var isMultiple = datagrid._isMultipleSelect = selectionType === 'multiple'
var unbindEvents = []
unbindEvents.push(datagrid.on('beforeSetData', function () {
datagrid._selectRowsIndex = []
}))
if (isMultiple) {
unbindEvents.push(datagrid.on('beforeSetData', function (data) {
data.columns.unshift({
sortable: false,
thRenderer: function () {
return '<input type="checkbox" class="select-all">'
},
tdRenderer: function () {
return '<input type="checkbox">'
}
})
}))
}
datagrid.once('afterInit', function () {
var $bodyWrapper = datagrid.ui.$bodyWrapper
var $columnsWrapper = datagrid.ui.$columnsWrapper
if (isMultiple) {
// 点击开头的 checkbox 才触发事件
unbindEvents.push(addEvent($bodyWrapper, 'change', function (e) {
if (e.target.tagName !== 'INPUT' || e.target.type !== 'checkbox') return
$columnsWrapper.querySelector('input.select-all').checked = false
var tr = findParent('tr', e.target, $bodyWrapper)
if (!tr) return
var trIndex = Number(tr.getAttribute('data-index'))
if (!Number.isNaN(trIndex)) datagrid.selectRow(trIndex)
// 等 datagrid.selectRow() 方法执行完成后,判断 _selectedRowsIndex 数组的长度是否等于 rows 的长度就知道是否是全选了
$columnsWrapper.querySelector('input[type=checkbox].select-all').checked = !datagrid.empty && datagrid._selectRowsIndex.length === datagrid.renderData.rows.length
}))
// 全选 checkbox
unbindEvents.push(addEvent($columnsWrapper, 'change', function (e) {
var input = e.target
if (input.tagName !== 'INPUT' || input.type !== 'checkbox' || !input.classList.contains('select-all')) return
datagrid.selectAll(input.checked)
}))
} else {
// 点击数据行时, 给出事件提示
unbindEvents.push(addEvent($bodyWrapper, 'click', function (e) {
var tr = findParent('tr', e.target, $bodyWrapper)
if (!tr) return
var trIndex = Number(tr.getAttribute('data-index'))
if (!Number.isNaN(trIndex)) datagrid.selectRow(trIndex)
}))
}
})
datagrid.once('beforeDestroy', function () {
unbindEvents.forEach(function (unbind) {
unbind()
})
})
})
}
/***/ },
/* 13 */
/***/ function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ },
/* 14 */,
/* 15 */
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(16)
var pagerTemplate = __webpack_require__(18)
var addEvent = __webpack_require__(8)
module.exports = function (DataGrid) {
DataGrid.hook(function (datagrid) {
if (!datagrid.options.pagination) return
var pagingTemplate = datagrid.options.pagingTemplate || pagerTemplate
function jumpTo (pageNo) {
if (Number.isNaN(pageNo) || pageNo < 1 || pageNo > pager.totalPage) {
wrapper.querySelector('[data-page]').value = pager.cur
return
}
wrapper.querySelector('[data-page]').value = pager.cur = pageNo
datagrid.emit('switchPage', pageNo)
}
var pager = datagrid.pager = {
cur: 1, // 当前页数
total: null, // 总共有多少条记录
size: null, // 每一页有多少条记录
start: null, // 当前页的数据是从第几条开始的
end: null, // 当前页的数据是在第几条结束的
totalPage: null // 一共有多少页
}
var unbindEvents = []
var wrapper = document.createElement('div')
wrapper.classList.add('grid-pager-wrapper')
unbindEvents.push(
addEvent(wrapper, 'click', function (e) {
var jump = e.target.dataset.jump
if (!jump) return
var pageTo
switch (jump) {
case 'first':
pageTo = 1
break
case 'end':
pageTo = pager.totalPage
break
case 'prev':
pageTo = pager.cur - 1
break
case 'next':
pageTo = pager.cur + 1
break
default:
return
}
jumpTo(pageTo)
}),
addEvent(wrapper, 'keydown', function (e) {
if (e.keyCode !== 13) return
if (e.target.dataset.page === undefined) return
jumpTo(Number(e.target.value))
}),
datagrid.on('beforeSetData', function (data) {
if (!data.rows || !data.rows.length) {
wrapper.classList.add('hidden')
return
}
var size = data.size || 0
var total = data.total || 0
var cur = pager.cur
var dataLength = data.rows.length
pager.total = total
pager.size = size
pager.start = (cur - 1) * size + 1
pager.end = pager.start + dataLength - 1
pager.total = total
pager.totalPage = Math.ceil(total / size) || 0
wrapper.innerHTML = pagingTemplate.replace(/\{\{(\w+)\}\}/g, function (word, group) {
return pager.hasOwnProperty(group) ? pager[group] : word
})
wrapper.classList.remove('hidden')
})
)
datagrid.once('afterInit', function () {
datagrid.ui.$gridWrapper.appendChild(wrapper)
datagrid.ui.$pagerWrapper = wrapper
})
datagrid.once('beforeDestroy', function () {
unbindEvents.forEach(function (unbind) { unbind() })
})
})
}
/***/ },
/* 16 */
/***/ function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ },
/* 17 */,
/* 18 */
/***/ function(module, exports) {
module.exports = "<div class=\"grid-pager\">\n <div>显示第 {{start}} - {{end}} 条数据, 共 {{total}} 条数据</div>\n <div>\n <span data-jump=\"first\">首页</span>\n <span data-jump=\"prev\">上一页</span>\n <span>第 <input type=\"text\" data-page value=\"{{cur}}\"> 页, 共 {{totalPage}} 页</span>\n <span data-jump=\"next\">下一页</span>\n <span data-jump=\"end\">尾页</span>\n </div>\n</div>\n";
/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(20)
var findParent = __webpack_require__(10)
var addEvent = __webpack_require__(8)
var DESC = -1 // 降序
var ASC = 1 // 升序
var NONE_ORDER = 0 // 不排序
var CLASS_ASC = 'order-by-asc'
var CLASS_DESC = 'order-by-desc'
module.exports = function (DataGrid) {
DataGrid.prototype.sortBy = function (index, fire) {
var columnDef = this.renderData.columnsDef[index]
if (!columnDef || columnDef.sortable === false) return
var sort = this.sort || (this.sort = {})
var $columnsWrapper = this.ui.$columnsWrapper
var lastSortIndex = sort.index
if (index !== lastSortIndex) {
if (typeof lastSortIndex === 'number') {
var lastTH = $columnsWrapper.querySelector('th[data-index="' + lastSortIndex + '"]')
if (lastTH) lastTH.classList.remove(CLASS_ASC, CLASS_DESC)
}
sort.index = index
sort.direction = NONE_ORDER
}
var th = $columnsWrapper.querySelector('th[data-index="' + index + '"]')
th.classList.remove(CLASS_ASC, CLASS_DESC)
switch (sort.direction) {
case NONE_ORDER:
sort.direction = ASC
th.classList.add(CLASS_ASC)
break
case ASC:
sort.direction = DESC
th.classList.add(CLASS_DESC)
break
case DESC:
sort.direction = NONE_ORDER
break
}
if (fire !== false) this.emit('sort', columnDef, sort.direction, index, th)
}
DataGrid.hook(function (datagrid) {
if (!datagrid.options.columnSorting) return
var unbindEvents = []
unbindEvents.push(
// 给每个字段内部注入小箭头
datagrid.on('beforeRenderColumns', function (columnsHTMLArr) {
columnsHTMLArr.forEach(function (html, index) {
columnsHTMLArr[index] = html.replace('</th>', '<span class="order-ico"></span></th>')
})
})
)
datagrid.once('afterInit', function () {
// 监听字段的点击事件
var $columnsWrapper = datagrid.ui.$columnsWrapper
unbindEvents.push(
addEvent($columnsWrapper, 'click', function (e) {
var th = findParent('th', e.target, $columnsWrapper)
if (!th) return
if (th.classList.contains('resizing')) return
var index = Number(th.getAttribute('data-index'))
if (!window.isNaN(index)) datagrid.sortBy(index)
}),
datagrid.on('afterSetData', function () {
var lastSortColumnIndex = datagrid.sort && datagrid.sort.index
if (typeof lastSortColumnIndex !== 'number' || lastSortColumnIndex < 0) return
var th = datagrid.ui.$columnsWrapper.querySelector('th[data-index="' + lastSortColumnIndex + '"]')
if (!th) return
switch (datagrid.sort.direction) {
case ASC:
th.classList.add(CLASS_ASC)
break
case DESC:
th.classList.add(CLASS_DESC)
break
}
})
)
})
datagrid.once('beforeDestroy', function () {
unbindEvents.forEach(function (unbind) { unbind() })
})
})
}
/***/ },
/* 20 */
/***/ function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ },
/* 21 */,
/* 22 */
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(23)
var addEvent = __webpack_require__(8)
var findParent = __webpack_require__(10)
var MIN_WIDTH = 100 // 表格的最小宽度
var indexOf = Array.prototype.indexOf
var IS_TOUCH = 'ontouchstart' in window
var MOUSEDOWN = IS_TOUCH ? 'touchstart' : 'mousedown'
var MOUSEMOVE = IS_TOUCH ? 'touchmove' : 'mousemove'
var MOUSEUP = IS_TOUCH ? 'touchend' : 'mouseup'
var getPageX = IS_TOUCH ? function (e) {
return e.pageX || e.changedTouches[0].pageX
} : function (e) {
return e.pageX
}
module.exports = function (DataGrid) {
DataGrid.hook(function (datagrid) {
if (!datagrid.options.columnResize) return
// 拖动时显示的虚线
var dragLine = document.createElement('div')
dragLine.classList.add('dragging-line')
var unbindEvents = []
// 注入虚线
datagrid.once('afterInit', function () {
datagrid.ui.$draggingLine = dragLine
datagrid.el.appendChild(dragLine)
})
var dragging = false // 是否正在拖动中
var draggingTH // 被拖动的 th 元素
var draggingColumnIndex // 被拖动的元素是第几个字段
var startX // 拖动开始时的 pageX 值
var draggingLineInitLeft // 拖动开始时虚线的左编剧
var minLeft // 当往左边拖动时能拖动的最大距离
function showDragLine (th) {
// 显示虚线
var ui = datagrid.ui
var $columnsWrapper = ui.$columnsWrapper
var $bodyWrapper = ui.$bodyWrapper
dragLine.style.height = $columnsWrapper.offsetHeight + $bodyWrapper.offsetHeight + 'px'
draggingLineInitLeft = th.offsetLeft + th.clientWidth - $bodyWrapper.scrollLeft
dragLine.style.left = draggingLineInitLeft + 1 + 'px'
document.documentElement.classList.add('data-grid-dragging')
}
// 在非触摸屏设备上,鼠标移上去的时候就显示拖拽虚线
if (!IS_TOUCH) {
unbindEvents.push(
addEvent(datagrid.el, 'mouseover', function (e) {
if (!e.target.classList.contains('drag-lever')) return
var th = findParent('th', e.target, datagrid.el)
if (!th) return
showDragLine(th)
}),
addEvent(datagrid.el, 'mouseout', function (e) {
if (!e.target.classList.contains('drag-lever') || dragging) return
document.documentElement.classList.remove('data-grid-dragging')
})
)
}
unbindEvents.push(
// 注入供用户拖拽的小方块
datagrid.on('beforeRenderColumns', function (columnsHTMLArr) {
columnsHTMLArr.forEach(function (html, index) {
columnsHTMLArr[index] = html.replace('</th>', '<span class="drag-lever"></span></th>')
})
}),
addEvent(datagrid.el, MOUSEDOWN, function (e) {
if (e.target.classList.contains('drag-lever') && (IS_TOUCH || e.button === 0)) {
var th = findParent('th', e.target, datagrid.el)
if (!th) return
if (IS_TOUCH) showDragLine(th)
// 给 th 加一个状态, 避免触发排序功能
// todo 需要一个临时关闭排序的开关
th.classList.add('resizing')
minLeft = -(th.clientWidth - MIN_WIDTH)
draggingTH = th
dragging = true
startX = getPageX(e)
draggingColumnIndex = indexOf.call(th.parentElement.children, th)
}
}),
addEvent(document, MOUSEMOVE, function (e) {
if (!dragging) return
e.preventDefault() // 阻止在 PC 端拖动鼠标时选中文字或在移动端滑动屏幕
// 调整虚线的 left 值
var moved = getPageX(e) - startX
if (moved > minLeft) {
dragLine.style.left = draggingLineInitLeft + (getPageX(e) - startX) + 'px'
}
}),
addEvent(document, MOUSEUP, function (e) {
if (!dragging) return
// 等 ../sort/index.js 里的 click 事件处理完后再移除这个 CSS 类
setTimeout(function () { draggingTH.classList.remove('resizing') }, 0)
document.documentElement.classList.remove('data-grid-dragging')
dragging = false
var moved = getPageX(e) - startX // 计算移动的距离
if (moved < minLeft) moved = minLeft
var columnsMinWidth = datagrid.renderData.columnsMinWidth
columnsMinWidth[draggingColumnIndex] = columnsMinWidth[draggingColumnIndex] + moved
datagrid.setWidth(columnsMinWidth)
})
)
datagrid.once('beforeDestroy', function () {
unbindEvents.forEach(function (unbind) { unbind() })
})
})
}
/***/ },
/* 23 */
/***/ function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ },
/* 24 */,
/* 25 */
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(26)
var slice = Array.prototype.slice
var addEvent = __webpack_require__(8)
module.exports = function (DataGrid) {
DataGrid.hook(function (datagrid) {
if (!datagrid.options.fixedColumns) return
var unbindEvents = []
var fixedDataGrid
var fixedColumnsLeft
datagrid.on('afterSetData', function (data) {
fixedColumnsLeft = data.fixedColumnsLeft
if (!fixedColumnsLeft) {
if (fixedDataGrid) fixedDataGrid.el.classList.add('hidden')
return
}
if (!fixedDataGrid) initFixedDataGrid(datagrid.el)
fixedDataGrid.el.classList.remove('hidden')
fixedDataGrid.setData({
columns: datagrid.renderData.columnsDef.slice(0, fixedColumnsLeft),
width: datagrid.renderData.columnsWidth.slice(0, fixedColumnsLeft),
rows: datagrid.renderData.rows
})
// 保证 fixedDataGrid 中每一行的高度都与原 datagrid 的高度一致
var fixedGridTrs = slice.call(fixedDataGrid.ui.$columnsWrapper.querySelectorAll('tr')).concat(slice.call(fixedDataGrid.ui.$bodyWrapper.querySelectorAll('tr')))
var gridTrs = slice.call(datagrid.ui.$columnsWrapper.querySelectorAll('tr')).concat(slice.call(datagrid.ui.$bodyWrapper.querySelectorAll('tr')))
fixedGridTrs.forEach(function (tr, index) {
var dTr = gridTrs[index]
if (tr.clientHeight !== dTr.clientHeight) {
tr.style.height = dTr.clientHeight + 'px'
}
})
})
datagrid.once('beforeDestroy', function () {
unbindEvents.forEach(function (unbind) {
unbind()
})
})
function initFixedDataGrid () {
var datagridContainer = document.createElement('div')
datagridContainer.classList.add('fixed-datagrid')
var div = document.createElement('div')
div.classList.add('hidden')
datagridContainer.appendChild(div)
datagrid.el.appendChild(datagridContainer)
fixedDataGrid = new DataGrid(div, {
height: datagrid.ui.$columnsWrapper.offsetHeight + datagrid.ui.$bodyWrapper.offsetHeight,
columnSorting: datagrid.options.columnSorting,
columnResize: datagrid.options.columnResize,
selection: datagrid.options.selection
})
// 修改一个元素的 scrollTop 属性值会触发这个元素的 onscroll 事件,
// 为了避免两个 datagrid 相互之间循环触发 onscroll 事件,
// 所以加了下面的一堆标识位。
// 循环触发 onscroll 事件会导致在快速滑动时两个表格的 scrollTop 不同步,
// 造成"撕裂"现象
var dataGridBodyScrolling = false
var dataGridBodyScrollingTimeId
var fixedDataGridBodyScrolling = false
var fixedDataGridBodyScrollingTimeId
unbindEvents.push(
addEvent(datagrid.ui.$bodyWrapper, 'scroll', function () {
if (fixedDataGridBodyScrolling) return
dataGridBodyScrolling = true
dataGridBodyScrollingTimeId && clearTimeout(dataGridBodyScrollingTimeId)
dataGridBodyScrollingTimeId = setTimeout(function () {
dataGridBodyScrolling = false
}, 250)
fixedDataGrid.ui.$bodyWrapper.scrollTop = this.scrollTop
}),
addEvent(fixedDataGrid.ui.$bodyWrapper, 'scroll', function () {
if (dataGridBodyScrolling) return
fixedDataGridBodyScrolling = true
fixedDataGridBodyScrollingTimeId && clearTimeout(fixedDataGridBodyScrollingTimeId)
fixedDataGridBodyScrollingTimeId = setTimeout(function () {
fixedDataGridBodyScrolling = false
}, 250)
datagrid.ui.$bodyWrapper.scrollTop = this.scrollTop
})
)
unbindEvents.push(
datagrid.on('trHoverTo', syncHoverIn),
fixedDataGrid.on('trHoverTo', syncHoverIn),
datagrid.on('clearHover', syncHoverOut),
fixedDataGrid.on('clearHover', syncHoverOut)
)
function syncHoverIn (index, trElement) {
var to = fixedDataGrid.el.contains(trElement) ? datagrid : fixedDataGrid
to.trHover(true, index, false)
}
function syncHoverOut (index, trElement) {
var to = fixedDataGrid.el.contains(trElement) ? datagrid : fixedDataGrid
to.trHover(false, index, false)
}
if (datagrid.options.selection) {
datagrid.on('selectedChanged', function (index) {
fixedDataGrid.selectRow(index, false)
})
fixedDataGrid.on('selectedChanged', function (index) {
datagrid.selectRow(index)
})
}
if (datagrid.options.columnSorting) {
fixedDataGrid.on('sort', function (columnDef, direction, index) {
datagrid.sortBy(index)
})
datagrid.on('sort', function (columnDef, direction, index) {
if (index < fixedColumnsLeft) return
var lastSortIndex = fixedDataGrid.sort && fixedDataGrid.sort.index
if (typeof lastSortIndex === 'number') {
fixedDataGrid.sort.direction = 0
var lastTh = fixedDataGrid.ui.$columnsWrapper.querySelector('th[data-index="' + lastSortIndex + '"]')
if (lastTh) lastTh.classList.remove('order-by-asc', 'order-by-desc')
}
})
}
}
})
}
/***/ },
/* 26 */
/***/ function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }
/******/ ])
});
;
})));
{
"name": "datagrid",
"version": "0.3.6",
"description": "Datagrid.",
"main": "./src/index.js",
"keywords": [
"datagrid"
],
"files": [
"src",
"dist"
],
"version": "0.4.0",
"description": "插件式表格组件。",
"repository": {
"type": "git",
"url": "git+https://github.com/lmk123/datagrid.git"
"url": "https://github.com/lmk123/datagrid.git"
},
"main": "dist/datagrid.common.js",
"module": "dist/datagrid.esm.js",
"unpkg": "dist/datagrid.js",
"types": "declaration/index.d.ts",
"files": [
"dist",
"declaration"
],
"scripts": {
"prepublish": "npm run build",
"start": "webpack-dev-server --inline --config build/webpack.dev.server.config.js",
"build": "webpack --config build/webpack.dev.config.js && webpack --config build/webpack.build.config.js",
"lint": "eslint --ignore-pattern '/dist/' \"**/*.{js,vue}\"",
"pub": "npm run lint && npm build && npm publish"
"start": "node build/dev.js",
"lint": "tslint -p tsconfig.json -t verbose",
"build": "node build/build.js",
"prepublishOnly": "npm run lint && npm run build"
},
"dependencies": {
"tinyemitter": "^1.0.1"
},
"devDependencies": {
"openpack": "1.0.0",
"file-loader": "0.9.0",
"postcss-loader": "1.1.1",
"autoprefixer": "6.5.3",
"html-loader": "0.4.4",
"node-sass": "3.11.2",
"sass-loader": "4.0.2",
"css-loader": "0.25.0",
"style-loader": "0.13.1",
"html-webpack-plugin": "2.24.1",
"extract-text-webpack-plugin": "1.0.1",
"webpack-dev-server": "1.16.2",
"webpack": "1.13.3",
"eslint": "3.9.1",
"eslint-plugin-html": "1.5.3",
"eslint-config-standard": "6.2.1",
"eslint-plugin-promise": "3.3.1",
"eslint-plugin-standard": "2.0.1"
"autoprefixer": "^7.2.1",
"cssnano": "^3.10.0",
"fs-extra": "^4.0.2",
"postcss-cssnext": "^3.0.2",
"rollup": "^0.50.1",
"rollup-plugin-buble": "^0.18.0",
"rollup-plugin-html": "^0.2.1",
"rollup-plugin-livereload": "^0.6.0",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-postcss": "^0.5.5",
"rollup-plugin-serve": "^0.4.2",
"rollup-plugin-typescript2": "^0.8.1",
"rollup-watch": "^4.3.1",
"tslint": "^5.8.0",
"tslint-config-prettier": "^1.6.0",
"tslint-config-standard": "^7.0.0",
"typescript": "^2.6.1",
"uglify-js": "^3.1.10"
},
"author": "Milk Lee <milk.lee@qq.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/lmk123/datagrid/issues"
},
"homepage": "https://github.com/lmk123/datagrid#readme"
"license": "MIT"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc