Comparing version 0.1.0 to 0.2.0
@@ -79,7 +79,7 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
function defaultColumnRender (columnDef) { | ||
function defaultThRenderer (columnDef) { | ||
return columnDef.name | ||
} | ||
function defaultDataRender (columnDef, rowData) { | ||
function defaultTdRenderer (columnDef, rowData) { | ||
return rowData[columnDef.key] | ||
@@ -178,2 +178,4 @@ } | ||
}), | ||
// 鼠标移入或移出的时候,给 tr 加上 hover 状态。 | ||
// 之所以不用 css 实现,是因为 fixedGrid 需要能用 js 设置 tr 的 hover 状态 | ||
addEvent(ui.$bodyWrapper, 'mouseover', function (e) { | ||
@@ -194,2 +196,13 @@ var tr = findParent('tr', e.target) | ||
} | ||
}), | ||
// 点击 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]) | ||
}) | ||
@@ -370,4 +383,18 @@ ) | ||
dp._columnsHTML = function (columnsDef) { | ||
return columnsDef.map(function (columnDef) { | ||
return '<th>' + (columnDef.th || defaultColumnRender)(columnDef) + '</th>' | ||
var customRenderer = this.options.thRenderer | ||
return columnsDef.map(function (columnDef, index) { | ||
let content | ||
if (customRenderer) { | ||
content = customRenderer(columnDef) | ||
} | ||
if (content == null) { | ||
if (columnDef.thRenderer) { | ||
content = columnDef.thRenderer(columnDef) | ||
} | ||
if (content == null) { | ||
content = defaultThRenderer(columnDef) | ||
} | ||
} | ||
return '<th data-index="' + index + '">' + content + '</th>' | ||
}) | ||
@@ -401,6 +428,19 @@ } | ||
dp._bodyHTML = function (columnsDef, rows) { | ||
return this.empty ? [] : rows.map(function (row, index) { | ||
var rowHTML = '<tr data-index="' + index + '">' | ||
columnsDef.forEach(function (columnDef) { | ||
rowHTML += '<td>' + (columnDef.td || defaultDataRender)(columnDef, row) + '</td>' | ||
var customRenderer = this.options.tdRenderer | ||
return this.empty ? [] : rows.map(function (row, rowIndex) { | ||
var rowHTML = '<tr data-index="' + rowIndex + '">' | ||
columnsDef.forEach(function (columnDef, columnIndex) { | ||
let content | ||
if (customRenderer) { | ||
content = customRenderer(columnDef, row) | ||
} | ||
if (content == null) { | ||
if (columnDef.tdRenderer) { | ||
content = columnDef.tdRenderer(columnDef, row) | ||
} | ||
if (content == null) { | ||
content = defaultTdRenderer(columnDef, row) | ||
} | ||
} | ||
rowHTML += '<td data-index="' + columnIndex + '">' + content + '</td>' | ||
}) | ||
@@ -407,0 +447,0 @@ rowHTML += '</tr>' |
@@ -1,1 +0,1142 @@ | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Datagrid=e():t.Datagrid=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}(function(t){for(var e in t)if(Object.prototype.hasOwnProperty.call(t,e))switch(typeof t[e]){case"function":break;case"object":t[e]=function(e){var n=e.slice(1),o=t[e[0]];return function(t,e,r){o.apply(this,[t,e,r].concat(n))}}(t[e]);break;default:t[e]=t[t[e]]}return t}([function(t,e,n){t.exports=n(11),t.exports.Selection=n(15),t.exports.Paging=n(14),t.exports.Sorting=n(16),t.exports.ColumnMove=n(12),t.exports.ColumnFixed=n(13)},function(t,e){t.exports=function(t,e,n,o){return t.addEventListener(e,n,o),function(){t.removeEventListener(e,n,o)}}},function(t,e){t.exports=function(t,e,n){n||(n=document.body);var o=t.toUpperCase(),r=e,i=null;do if(r.tagName===o){i=r;break}while(r!==n&&(r=r.parentElement));return i}},function(t,e){},3,3,3,3,3,function(t,e){t.exports='<div class=grid-wrapper> <div class=grid-columns-wrapper> <table class=grid-columns> <colgroup></colgroup> <thead></thead> </table> </div> <div class=grid-body-wrapper> <table class=grid-body> <colgroup></colgroup> <tbody></tbody> </table> </div> </div> <div class="grid-no-data hidden"> <div class=no-data-content> 暂无数据 </div> </div> '},function(t,e){t.exports="<div class=grid-pager> <div>显示第 {{start}} - {{end}} 条数据, 共 {{total}} 条数据</div> <div> <span data-jump=first>首页</span> <span data-jump=prev>上一页</span> <span>第 <input type=text data-page value={{cur}}> 页, 共 {{totalPage}} 页</span> <span data-jump=next>下一页</span> <span data-jump=end>尾页</span> </div> </div> "},function(t,e,n){function o(t){return t.name}function r(t,e){return e[t.key]}function i(t,e){s.call(this);var n=this.el=document.createElement("div");this.options=u({},{height:t.offsetHeight},e),this.origin=t.parentElement.replaceChild(n,t),f.forEach(function(t){t(this)},this),this._init()}n(3);var a=n(9),s=n(17),c=n(1),u=n(19),d=n(2),l=n(18),p=100,f=[];i.use=function(t){t(i)},i.hook=function(t){return f.push(t),function(){var e=f.indexOf(t);e>=0&&f.splice(e,1)}};var h=i.prototype=Object.create(s.prototype);h.constructor=i,h._init=function(){var t=this._unbindEvents=[];this.emit("beforeInit");var e=this.el;e.classList.add("datagrid"),e.innerHTML=a;var n={$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"};for(var o in n)n[o]=e.querySelector(n[o]);n.$gridWrapper.style.height=this.options.height+"px";var r=this;t.push(c(n.$bodyWrapper,"scroll",function(){n.$columns.style.left="-"+n.$bodyWrapper.scrollLeft+"px"}),c(n.$bodyWrapper,"mouseover",function(t){var e=d("tr",t.target);if(e){var n=e.getAttribute("data-index");n&&r.trHover(!0,Number(n))}}),c(n.$bodyWrapper,"mouseout",function(t){var e=d("tr",t.target);if(e){var n=e.getAttribute("data-index");n&&r.trHover(!1,Number(n))}})),this.ui=n,this.options.fit&&t.push(c(window,"resize",l(function(){r.setWidth()}))),this.emit("afterInit")},h.trHover=function(t,e,n){var o=this.ui.$bodyWrapper.querySelector("tbody"),r=o.querySelector('[data-index="'+e+'"]');r.classList[t?"add":"remove"]("hover"),n!==!1&&this.emit(t?"trHoverTo":"clearHover",e,r,this.rows&&this.rows[e])},h.setData=function(t){this.emit("beforeSetData",t),this.renderData={},this.setColumns(t.columns),this.setBody(t.rows),this.setWidth(t.width),this.emit("afterSetData",t)},h.normalizeWidth=function(t){var e=this.renderData,n=e.columnsDef;Array.isArray(t)||(t=[]);for(var o=[],r=0;r<n.length;r++)o[r]=t[r]||Math.max(15*n[r].name.length,p);return o},h.setWidth=function(t){var e=this.renderData;!t&&e.columnsMinWidth||(e.columnsMinWidth=this.normalizeWidth(t));var n,o=e.columnsMinWidth;if(this.options.fit){var r=o.reduce(function(t,e){return t+e}),i=this.ui.$bodyWrapper.clientWidth;if(r>=i)n=o;else{var a=(i-r)/e.columnsDef.length;n=o.map(function(t){return t+a})}}else n=o;e.columnsWidth=n;var s=this._colGroupsHTML(n);this._renderCols(s),this._resize(n)},h._colGroupsHTML=function(t){return t?t.map(function(t){return'<col style="width:'+t+'px">'}):[]},h._renderCols=function(t){var e=this.ui;e.$columnsColGroup.innerHTML=e.$bodyColGroup.innerHTML=t.join("")},h._resize=function(t){var e=this.ui,n=e.$columns,o=e.$noData,r=e.$body,i=t.reduce(function(t,e){return t+e});n.style.width=r.style.width=i+"px",this.empty?o.classList.remove("hidden"):o.classList.add("hidden")},h.setColumns=function(t){var e=this.renderData.columnsDef=this._normalize(t),n=this._columnsHTML(e);this.emit("beforeRenderColumns",n),this._renderColumns(n)},h._normalize=function(t){return t.map(function(t){var e="string"==typeof t?{name:t}:t;return e.key||(e.key=e.name),e})},h._columnsHTML=function(t){return t.map(function(t){return"<th>"+(t.th||o)(t)+"</th>"})},h._renderColumns=function(t){this.ui.$columnsThead.innerHTML=t.join("")},h.setBody=function(t){var e=this.renderData;this.empty=!t||!t.length,e.rows=t,this._renderBody(e.trsArr=this._bodyHTML(e.columnsDef,t))},h._bodyHTML=function(t,e){return this.empty?[]:e.map(function(e,n){var o='<tr data-index="'+n+'">';return t.forEach(function(t){o+="<td>"+(t.td||r)(t,e)+"</td>"}),o+="</tr>"})},h._renderBody=function(t){var e=this.ui,n=e.$body,o=e.$noData,r=e.$bodyTbody;return this.empty?(n.classList.add("hidden"),void o.classList.remove("hidden")):(r.innerHTML=t.join(""),n.classList.remove("hidden"),void o.classList.add("hidden"))},h.destroy=function(){this.emit("beforeDestroy"),this._unbindEvents.forEach(function(t){t()});var t=this.el;try{t.parentElement.replaceChild(this.origin,t)}catch(e){}this.emit("afterDestroy")},t.exports=i},function(t,e,n){n(4);var o=n(1),r=n(2),i=100,a=Array.prototype.indexOf,s="ontouchstart"in window,c=s?"touchstart":"mousedown",u=s?"touchmove":"mousemove",d=s?"touchend":"mouseup";t.exports=function(t){t.hook(function(t){if(t.options.columnResize){var e=document.createElement("div");e.classList.add("dragging-line");var n=[];t.once("afterInit",function(){t.ui.$draggingLine=e,t.el.appendChild(e)});var s,l,p,f,h,v,m=!1;n.push(t.on("beforeRenderColumns",function(t){t.forEach(function(e,n){t[n]=e.replace("</th>",'<span class="drag-lever"></span></th>')})}),o(t.el,c,function(n){if(n.target.classList.contains("drag-lever")&&0===n.button){var o=r("th",n.target,t.el);if(!o)return;o.classList.add("resizing"),l=o,v=-(o.clientWidth-i);var c=t.ui,u=c.$columnsWrapper,d=c.$bodyWrapper;e.style.height=u.offsetHeight+d.offsetHeight+"px",h=o.offsetLeft+o.clientWidth-d.scrollLeft,e.style.left=h+"px",e.classList.add("show"),m=!0,s=n.target,s.classList.add("dragging"),f=n.pageX,p=a.call(o.parentElement.children,o)}}),o(document,u,function(t){if(m){t.preventDefault();var n=t.pageX-f;n>v&&(e.style.left=h+(t.pageX-f)+"px")}}),o(document,d,function(n){if(m){setTimeout(function(){l.classList.remove("resizing")},0),e.classList.remove("show"),m=!1,s.classList.remove("dragging");var o=n.pageX-f;o<v&&(o=v);var r=t.renderData.columnsMinWidth;r[p]=r[p]+o,t.setWidth(r)}})),t.once("beforeDestroy",function(){n.forEach(function(t){t()})})}})}},function(t,e,n){n(5);var o=n(1);t.exports=function(t){t.hook(function(e){function n(){function n(t,n){var o=r.el.contains(n)?e:r;o.trHover(!0,t,!1)}function a(t,n){var o=r.el.contains(n)?e:r;o.trHover(!1,t,!1)}var s=document.createElement("div");s.classList.add("fixed-datagrid");var c=document.createElement("div");c.classList.add("hidden"),s.appendChild(c),e.el.appendChild(s),r=new t(c,{height:e.ui.$columnsWrapper.offsetHeight+e.ui.$bodyWrapper.offsetHeight,columnSorting:e.options.columnSorting,columnResize:e.options.columnResize,selection:e.options.selection});var u,d,l=!1,p=!1;i.push(o(e.ui.$bodyWrapper,"scroll",function(){p||(l=!0,u&&clearTimeout(u),u=setTimeout(function(){l=!1},250),r.ui.$bodyWrapper.scrollTop=this.scrollTop)}),o(r.ui.$bodyWrapper,"scroll",function(){l||(p=!0,d&&clearTimeout(d),d=setTimeout(function(){p=!1},250),e.ui.$bodyWrapper.scrollTop=this.scrollTop)})),i.push(e.on("trHoverTo",n),r.on("trHoverTo",n),e.on("clearHover",a),r.on("clearHover",a)),e.options.selection&&(e.on("selectedChanged",function(t){r.selectRow(t,!1)}),r.on("selectedChanged",function(t){e.selectRow(t)}))}if(e.options.fixedColumns){var r,i=[];e.on("afterSetData",function(t){var o=t.fixedColumnsLeft;return o?(r||n(e.el),r.el.classList.remove("hidden"),void r.setData({columns:e.renderData.columnsDef.slice(0,o),width:e.renderData.columnsWidth.slice(0,o),rows:e.renderData.rows})):void(r&&r.el.classList.add("hidden"))}),e.once("beforeDestroy",function(){i.forEach(function(t){t()})})}})}},function(t,e,n){n(6);var o=n(10),r=n(1);t.exports=function(t){t.hook(function(t){function e(e){return Number.isNaN(e)||e<1||e>i.totalPage?void(s.querySelector("[data-page]").value=i.cur):(s.querySelector("[data-page]").value=i.cur=e,void t.emit("switchPage",e))}if(t.options.pagination){var n=t.options.pagingTemplate||o,i=t.pager={cur:1,total:null,size:null,start:null,end:null,totalPage:null},a=[],s=document.createElement("div");s.classList.add("grid-pager-wrapper"),a.push(r(s,"click",function(t){var n=t.target.dataset.jump;if(n){var o;switch(n){case"first":o=1;break;case"end":o=i.totalPage;break;case"prev":o=i.cur-1;break;case"next":o=i.cur+1;break;default:return}e(o)}}),r(s,"keydown",function(t){13===t.keyCode&&void 0!==t.target.dataset.page&&e(Number(t.target.value))}),t.on("beforeSetData",function(t){if(!t.rows||!t.rows.length)return void s.classList.add("hidden");var e=t.size||0,o=t.total||0,r=i.cur,a=t.rows.length;i.total=o,i.size=e,i.start=(r-1)*e+1,i.end=i.start+a-1,i.total=o,i.totalPage=Math.ceil(o/e)||0,s.innerHTML=n.replace(/\{\{(\w+)\}\}/g,function(t,e){return i.hasOwnProperty(e)?i[e]:t}),s.classList.remove("hidden")})),t.once("afterInit",function(){t.ui.$gridWrapper.appendChild(s),t.ui.$pagerWrapper=s}),t.once("beforeDestroy",function(){a.forEach(function(t){t()})})}})}},function(t,e,n){n(7);var o=n(2),r=n(1);t.exports=function(t){t.prototype.selectRow=function(t,e){var n=this.ui.$body,o=n.querySelector('tr[data-index="'+t+'"]');if(o){var r=n.querySelector("tr.selected");r&&r.classList.remove("selected"),o.classList.add("selected"),this._selectRowIndex=t,e!==!1&&this.emit("selectedChanged",t)}},t.hook(function(t){if(t.options.selection){var e=[];e.push(t.on("beforeSetData",function(){t._selectRowIndex=null})),t.once("afterInit",function(){var n=t.ui.$body;e.push(r(n,"click",function(e){var r=o("tr",e.target,n);if(r){var i=Number(r.dataset.index);Number.isNaN(i)||t._selectRowIndex===i||t.selectRow(i)}}))}),t.once("beforeDestroy",function(){e.forEach(function(t){t()})})}})}},function(t,e,n){n(8);var o=n(2),r=n(1),i=Array.prototype.indexOf,a=-1,s=1,c=0,u="order-by-asc",d="order-by-desc";t.exports=function(t){t.hook(function(t){function e(){if("number"==typeof n){var e=t.ui.$columnsWrapper.querySelector("th:nth-child("+(n+1)+")");e&&e.classList.remove(u,d)}}if(t.options.columnSorting){var n,l=[],p=c;l.push(t.on("beforeRenderColumns",function(t){t.forEach(function(e,n){t[n]=e.replace("</th>",'<span class="order-ico"></span></th>')})})),t.once("afterInit",function(){var f=t.ui.$columnsWrapper;l.push(r(f,"click",function(r){var l=o("th",r.target,f);if(l&&!l.classList.contains("resizing")){var h=i.call(l.parentElement.children,l),v=t.renderData.columnsDef[h];if(v.sortable!==!1){switch(h!==n&&(e(),n=h,p=c),l.classList.remove(u,d),p){case c:p=s,l.classList.add(u);break;case s:p=a,l.classList.add(d);break;case a:p=c}t.emit("sort",v,p,l)}}}))}),t.once("beforeDestroy",function(){l.forEach(function(t){t()})})}})}},function(t,e){function n(){this._callbacks={}}var o=Array.prototype.slice,r=n.prototype;r.on=function(t,e){var n=this._callbacks,o=n[t]||(n[t]=[]);return o.push(e),function(){var t=o.indexOf(e);t>=0&&o.splice(t,1)}},r.once=function(t,e){var n=this.on(t,function(){e.apply(null,arguments),window.setTimeout(n,0)});return n},r.emit=function(t){var e=this._callbacks[t];if(e&&e.length){var n=o.call(arguments,1);e.forEach(function(t){t.apply(null,n)})}},t.exports=n},function(t,e){t.exports=function(t,e){var n;return e="number"==typeof e?e:250,function(){"number"==typeof n&&window.clearTimeout(n);var o=arguments;n=window.setTimeout(function(){t.apply(null,o)},e)}}},function(t,e){var n=Object.prototype.hasOwnProperty;t.exports=function(t){for(var e=1;e<arguments.length;e+=1){var o=arguments[e];if(o&&"object"==typeof o)for(var r in o)n.call(o,r)&&(t[r]=o[r])}return t}}]))}); | ||
(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 = {}; | ||
/******/ | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
/******/ | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) | ||
/******/ return installedModules[moduleId].exports; | ||
/******/ | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ exports: {}, | ||
/******/ id: moduleId, | ||
/******/ loaded: false | ||
/******/ }; | ||
/******/ | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
/******/ | ||
/******/ // Flag the module as loaded | ||
/******/ module.loaded = true; | ||
/******/ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
/******/ | ||
/******/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
/******/ | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
/******/ | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
/******/ | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(0); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ((function(modules) { | ||
// Check all modules for deduplicated modules | ||
for(var i in modules) { | ||
if(Object.prototype.hasOwnProperty.call(modules, i)) { | ||
switch(typeof modules[i]) { | ||
case "function": break; | ||
case "object": | ||
// Module can be created from a template | ||
modules[i] = (function(_m) { | ||
var args = _m.slice(1), fn = modules[_m[0]]; | ||
return function (a,b,c) { | ||
fn.apply(this, [a,b,c].concat(args)); | ||
}; | ||
}(modules[i])); | ||
break; | ||
default: | ||
// Module is a copy of another module | ||
modules[i] = modules[modules[i]]; | ||
break; | ||
} | ||
} | ||
} | ||
return modules; | ||
}([ | ||
/* 0 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
module.exports = __webpack_require__(11) | ||
module.exports.Selection = __webpack_require__(15) | ||
module.exports.Paging = __webpack_require__(14) | ||
module.exports.Sorting = __webpack_require__(16) | ||
module.exports.ColumnMove = __webpack_require__(12) | ||
module.exports.ColumnFixed = __webpack_require__(13) | ||
/***/ }, | ||
/* 1 */ | ||
/***/ 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) | ||
} | ||
} | ||
/***/ }, | ||
/* 2 */ | ||
/***/ 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 | ||
} | ||
/***/ }, | ||
/* 3 */ | ||
/***/ function(module, exports) { | ||
// removed by extract-text-webpack-plugin | ||
/***/ }, | ||
/* 4 */ | ||
3, | ||
/* 5 */ | ||
3, | ||
/* 6 */ | ||
3, | ||
/* 7 */ | ||
3, | ||
/* 8 */ | ||
3, | ||
/* 9 */ | ||
/***/ function(module, exports) { | ||
module.exports = "<div class=grid-wrapper> <div class=grid-columns-wrapper> <table class=grid-columns> <colgroup></colgroup> <thead></thead> </table> </div> <div class=grid-body-wrapper> <table class=grid-body> <colgroup></colgroup> <tbody></tbody> </table> </div> </div> <div class=\"grid-no-data hidden\"> <div class=no-data-content> 暂无数据 </div> </div> "; | ||
/***/ }, | ||
/* 10 */ | ||
/***/ function(module, exports) { | ||
module.exports = "<div class=grid-pager> <div>显示第 {{start}} - {{end}} 条数据, 共 {{total}} 条数据</div> <div> <span data-jump=first>首页</span> <span data-jump=prev>上一页</span> <span>第 <input type=text data-page value={{cur}}> 页, 共 {{totalPage}} 页</span> <span data-jump=next>下一页</span> <span data-jump=end>尾页</span> </div> </div> "; | ||
/***/ }, | ||
/* 11 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
__webpack_require__(3) | ||
var containerTemplate = __webpack_require__(9) | ||
var Event = __webpack_require__(17) | ||
var addEvent = __webpack_require__(1) | ||
var extend = __webpack_require__(19) | ||
var findParent = __webpack_require__(2) | ||
var debounce = __webpack_require__(18) | ||
var DefaultWidth = 100 | ||
function defaultThRenderer (columnDef) { | ||
return columnDef.name | ||
} | ||
function defaultTdRenderer (columnDef, rowData) { | ||
return rowData[columnDef.key] | ||
} | ||
var hooks = [] | ||
/** | ||
* 构造函数 | ||
* @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) | ||
if (false) { | ||
if (!ele.parentElement) { | ||
throw new Error('Element must have a parentElement') | ||
} | ||
} | ||
// 从 document 里删除原本的节点并保存下来,供实例销毁之后重新显示出来 | ||
this.origin = ele.parentElement.replaceChild(el, ele) | ||
hooks.forEach(function (fn) { fn(this) }, this) | ||
this._init() | ||
} | ||
/** | ||
* 保存插件 | ||
* @param {Function} plugin | ||
*/ | ||
DataGrid.use = function (plugin) { | ||
if (false) { | ||
if (typeof plugin !== 'function') { | ||
throw new TypeError('.use(plugin) 参数类型错误: plugin 必需是一个函数。') | ||
} | ||
if (plugin._installed) return | ||
plugin._installed = true | ||
} | ||
plugin(DataGrid) | ||
} | ||
/** | ||
* 每次创建新的实例时都会触发这个函数 | ||
* @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) | ||
} | ||
} | ||
var dp = DataGrid.prototype = Object.create(Event.prototype) | ||
dp.constructor = DataGrid | ||
dp._init = function () { | ||
var _unbindEvents = this._unbindEvents = [] | ||
this.emit('beforeInit') | ||
var el = this.el | ||
el.classList.add('datagrid') | ||
el.innerHTML = containerTemplate | ||
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' | ||
} | ||
for (var key in ui) { | ||
ui[key] = el.querySelector(ui[key]) | ||
} | ||
ui.$gridWrapper.style.height = this.options.height + 'px' | ||
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]) | ||
}) | ||
) | ||
this.ui = ui | ||
if (this.options.fit) { | ||
_unbindEvents.push( | ||
addEvent(window, 'resize', debounce(function () { | ||
that.setWidth() | ||
})) | ||
) | ||
} | ||
this.emit('afterInit') | ||
} | ||
/** | ||
* 处理 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.$bodyWrapper.querySelector('tbody') | ||
var hoverToTR = tbody.querySelector('[data-index="' + index + '"]') | ||
hoverToTR.classList[inOrOut ? 'add' : 'remove']('hover') | ||
if (emit !== false) this.emit(inOrOut ? 'trHoverTo' : 'clearHover', index, hoverToTR, this.rows && this.rows[index]) | ||
} | ||
/** | ||
* 给表格填充数据 | ||
* @param data | ||
* @param {String[]|Object[]} data.columns - 表格的字段定义 | ||
* @param {Object[]} data.rows - 数据 | ||
* @param {Number[]} data.width - 每个字段对应的宽度 | ||
*/ | ||
dp.setData = function (data) { | ||
this.emit('beforeSetData', data) | ||
this.renderData = {} | ||
this.setColumns(data.columns) | ||
this.setBody(data.rows) | ||
this.setWidth(data.width) | ||
this.emit('afterSetData', data) | ||
} | ||
/** | ||
* 根据用户给的宽度数组计算出实际需要用到的最小宽度数组, | ||
* 因为用户可能不传宽度数组,或者宽度数组的长度比字段数组长或短, | ||
* 所以要处理一遍 | ||
* @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 | ||
} | ||
/** | ||
* 设置宽度。 | ||
* 默认情况下,用户设置的宽度会成为最终字段的宽度, | ||
* 但如果 fit 设置为 true,则将用户传进来的宽度视为"最小宽度", | ||
* 如果这些最小宽度加起来大于 wrapper 的宽度,则直接使用最小宽度作为 td 的宽度; | ||
* 如果加起来小于 wrapper 的宽度,则用 wrapper 宽度减去最小宽度的差值,除以字段的个数得到平均值,再给每个最小宽度加上这个平均值作为字段的真正宽度 | ||
* @param {Number[]} [customWidth] | ||
*/ | ||
dp.setWidth = function (customWidth) { | ||
var renderData = this.renderData | ||
if (customWidth || !renderData.columnsMinWidth) { | ||
renderData.columnsMinWidth = this.normalizeWidth(customWidth) | ||
} | ||
var columnsMinWidth = renderData.columnsMinWidth | ||
var columnsWidth | ||
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 w + diff | ||
}) | ||
} | ||
} else { | ||
columnsWidth = columnsMinWidth | ||
} | ||
renderData.columnsWidth = columnsWidth | ||
var cols = this._colGroupsHTML(columnsWidth) | ||
this._renderCols(cols) | ||
this._resize(columnsWidth) | ||
} | ||
/** | ||
* 计算出表格的 col 元素的 HTML | ||
* @param {Number[]} columnsWidth - 定义字段宽度的数组 | ||
* @private | ||
* @return {String[]} | ||
*/ | ||
dp._colGroupsHTML = function (columnsWidth) { | ||
return columnsWidth ? columnsWidth.map(function (width) { return '<col style="width:' + width + 'px">' }) : [] | ||
} | ||
/** | ||
* 填充 colsHTML | ||
* @param {String[]} colsHTML | ||
* @private | ||
*/ | ||
dp._renderCols = function (colsHTML) { | ||
var ui = this.ui | ||
ui.$columnsColGroup.innerHTML = ui.$bodyColGroup.innerHTML = colsHTML.join('') | ||
} | ||
/** | ||
* 调整各种尺寸 | ||
* @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') | ||
} | ||
} | ||
/** | ||
* 渲染表头的方法 | ||
* @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) { | ||
let content | ||
if (customRenderer) { | ||
content = customRenderer(columnDef) | ||
} | ||
if (content == null) { | ||
if (columnDef.thRenderer) { | ||
content = columnDef.thRenderer(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) { | ||
let content | ||
if (customRenderer) { | ||
content = customRenderer(columnDef, row) | ||
} | ||
if (content == null) { | ||
if (columnDef.tdRenderer) { | ||
content = columnDef.tdRenderer(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 | ||
var $body = ui.$body | ||
var $noData = ui.$noData | ||
var $bodyTbody = ui.$bodyTbody | ||
if (this.empty) { | ||
$body.classList.add('hidden') | ||
$noData.classList.remove('hidden') | ||
return | ||
} | ||
$bodyTbody.innerHTML = trsArr.join('') | ||
$body.classList.remove('hidden') | ||
$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 | ||
/***/ }, | ||
/* 12 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
__webpack_require__(4) | ||
var addEvent = __webpack_require__(1) | ||
var findParent = __webpack_require__(2) | ||
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' | ||
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 draggingLever // 被拖动的那个小方块 | ||
var draggingTH // 被拖动的 th 元素 | ||
var draggingColumnIndex // 被拖动的元素是第几个字段 | ||
var startX // 拖动开始时的 pageX 值 | ||
var draggingLineInitLeft // 拖动开始时虚线的左编剧 | ||
var minLeft // 当往左边拖动时能拖动的最大距离 | ||
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') && e.button === 0) { | ||
var th = findParent('th', e.target, datagrid.el) | ||
if (!th) return | ||
// 给 th 加一个状态, 避免触发排序功能 | ||
// todo 需要一个临时关闭排序的开关 | ||
th.classList.add('resizing') | ||
draggingTH = th | ||
minLeft = -(th.clientWidth - MIN_WIDTH) | ||
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 + 'px' | ||
dragLine.classList.add('show') | ||
dragging = true | ||
draggingLever = e.target | ||
draggingLever.classList.add('dragging') | ||
startX = e.pageX | ||
draggingColumnIndex = indexOf.call(th.parentElement.children, th) | ||
} | ||
}), | ||
addEvent(document, MOUSEMOVE, function (e) { | ||
if (!dragging) return | ||
e.preventDefault() // 阻止在 PC 端拖动鼠标时选中文字或在移动端滑动屏幕 | ||
// 调整虚线的 left 值 | ||
var moved = e.pageX - startX | ||
if (moved > minLeft) { | ||
dragLine.style.left = draggingLineInitLeft + (e.pageX - startX) + 'px' | ||
} | ||
}), | ||
addEvent(document, MOUSEUP, function (e) { | ||
if (!dragging) return | ||
// 等 ../sort/index.js 里的 click 事件处理完后再移除这个 CSS 类 | ||
setTimeout(function () { draggingTH.classList.remove('resizing') }, 0) | ||
dragLine.classList.remove('show') | ||
dragging = false | ||
draggingLever.classList.remove('dragging') | ||
var moved = e.pageX - 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() }) | ||
}) | ||
}) | ||
} | ||
/***/ }, | ||
/* 13 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
__webpack_require__(5) | ||
var addEvent = __webpack_require__(1) | ||
module.exports = function (DataGrid) { | ||
DataGrid.hook(function (datagrid) { | ||
if (!datagrid.options.fixedColumns) return | ||
var unbindEvents = [] | ||
var fixedDataGrid | ||
datagrid.on('afterSetData', function (data) { | ||
var 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 | ||
}) | ||
}) | ||
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) | ||
}) | ||
} | ||
} | ||
}) | ||
} | ||
/***/ }, | ||
/* 14 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
__webpack_require__(6) | ||
var pagerTemplate = __webpack_require__(10) | ||
var addEvent = __webpack_require__(1) | ||
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() }) | ||
}) | ||
}) | ||
} | ||
/***/ }, | ||
/* 15 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
__webpack_require__(7) | ||
var findParent = __webpack_require__(2) | ||
var addEvent = __webpack_require__(1) | ||
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 selectedTR = $body.querySelector('tr.selected') | ||
if (selectedTR) selectedTR.classList.remove('selected') | ||
tr.classList.add('selected') | ||
this._selectRowIndex = index | ||
if (fire !== false) this.emit('selectedChanged', index) | ||
} | ||
DataGrid.hook(function (datagrid) { | ||
if (!datagrid.options.selection) return | ||
var unbindEvents = [] | ||
unbindEvents.push(datagrid.on('beforeSetData', function () { | ||
datagrid._selectRowIndex = null | ||
})) | ||
datagrid.once('afterInit', function () { | ||
var $body = datagrid.ui.$body | ||
// 点击数据行时, 给出事件提示 | ||
unbindEvents.push(addEvent($body, 'click', function (e) { | ||
var tr = findParent('tr', e.target, $body) | ||
if (!tr) return | ||
var trIndex = Number(tr.dataset.index) | ||
if (!Number.isNaN(trIndex) && datagrid._selectRowIndex !== trIndex) datagrid.selectRow(trIndex) | ||
})) | ||
}) | ||
datagrid.once('beforeDestroy', function () { | ||
unbindEvents.forEach(function (unbind) { | ||
unbind() | ||
}) | ||
}) | ||
}) | ||
} | ||
/***/ }, | ||
/* 16 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
__webpack_require__(8) | ||
var findParent = __webpack_require__(2) | ||
var addEvent = __webpack_require__(1) | ||
var indexOf = Array.prototype.indexOf | ||
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.hook(function (datagrid) { | ||
if (!datagrid.options.columnSorting) return | ||
var unbindEvents = [] | ||
var lastSortColumnIndex | ||
var sortType = NONE_ORDER | ||
unbindEvents.push( | ||
// 给每个字段内部注入小箭头 | ||
datagrid.on('beforeRenderColumns', function (columnsHTMLArr) { | ||
columnsHTMLArr.forEach(function (html, index) { | ||
columnsHTMLArr[index] = html.replace('</th>', '<span class="order-ico"></span></th>') | ||
}) | ||
}) | ||
) | ||
function clearLastSort () { | ||
if (typeof lastSortColumnIndex === 'number') { | ||
var lastTH = datagrid.ui.$columnsWrapper.querySelector('th:nth-child(' + (lastSortColumnIndex + 1) + ')') | ||
if (lastTH) lastTH.classList.remove(CLASS_ASC, CLASS_DESC) | ||
} | ||
} | ||
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 = indexOf.call(th.parentElement.children, th) | ||
var columnDef = datagrid.renderData.columnsDef[index] | ||
if (columnDef.sortable === false) return | ||
if (index !== lastSortColumnIndex) { | ||
clearLastSort() | ||
lastSortColumnIndex = index | ||
sortType = NONE_ORDER | ||
} | ||
th.classList.remove(CLASS_ASC, CLASS_DESC) | ||
switch (sortType) { | ||
case NONE_ORDER: | ||
sortType = ASC | ||
th.classList.add(CLASS_ASC) | ||
break | ||
case ASC: | ||
sortType = DESC | ||
th.classList.add(CLASS_DESC) | ||
break | ||
case DESC: | ||
sortType = NONE_ORDER | ||
break | ||
} | ||
datagrid.emit('sort', columnDef, sortType, th) | ||
}) | ||
) | ||
}) | ||
datagrid.once('beforeDestroy', function () { | ||
unbindEvents.forEach(function (unbind) { unbind() }) | ||
}) | ||
}) | ||
} | ||
/***/ }, | ||
/* 17 */ | ||
/***/ 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 | ||
/***/ }, | ||
/* 18 */ | ||
/***/ 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) | ||
} | ||
} | ||
/***/ }, | ||
/* 19 */ | ||
/***/ 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 | ||
} | ||
/***/ } | ||
/******/ ]))) | ||
}); | ||
; |
{ | ||
"name": "datagrid", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Datagrid.", | ||
@@ -5,0 +5,0 @@ "main": "./src/index.js", |
@@ -11,7 +11,7 @@ require('./index.scss') | ||
function defaultColumnRender (columnDef) { | ||
function defaultThRenderer (columnDef) { | ||
return columnDef.name | ||
} | ||
function defaultDataRender (columnDef, rowData) { | ||
function defaultTdRenderer (columnDef, rowData) { | ||
return rowData[columnDef.key] | ||
@@ -110,2 +110,4 @@ } | ||
}), | ||
// 鼠标移入或移出的时候,给 tr 加上 hover 状态。 | ||
// 之所以不用 css 实现,是因为 fixedGrid 需要能用 js 设置 tr 的 hover 状态 | ||
addEvent(ui.$bodyWrapper, 'mouseover', function (e) { | ||
@@ -126,2 +128,13 @@ var tr = findParent('tr', e.target) | ||
} | ||
}), | ||
// 点击 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]) | ||
}) | ||
@@ -302,4 +315,18 @@ ) | ||
dp._columnsHTML = function (columnsDef) { | ||
return columnsDef.map(function (columnDef) { | ||
return '<th>' + (columnDef.th || defaultColumnRender)(columnDef) + '</th>' | ||
var customRenderer = this.options.thRenderer | ||
return columnsDef.map(function (columnDef, index) { | ||
let content | ||
if (customRenderer) { | ||
content = customRenderer(columnDef) | ||
} | ||
if (content == null) { | ||
if (columnDef.thRenderer) { | ||
content = columnDef.thRenderer(columnDef) | ||
} | ||
if (content == null) { | ||
content = defaultThRenderer(columnDef) | ||
} | ||
} | ||
return '<th data-index="' + index + '">' + content + '</th>' | ||
}) | ||
@@ -333,6 +360,19 @@ } | ||
dp._bodyHTML = function (columnsDef, rows) { | ||
return this.empty ? [] : rows.map(function (row, index) { | ||
var rowHTML = '<tr data-index="' + index + '">' | ||
columnsDef.forEach(function (columnDef) { | ||
rowHTML += '<td>' + (columnDef.td || defaultDataRender)(columnDef, row) + '</td>' | ||
var customRenderer = this.options.tdRenderer | ||
return this.empty ? [] : rows.map(function (row, rowIndex) { | ||
var rowHTML = '<tr data-index="' + rowIndex + '">' | ||
columnsDef.forEach(function (columnDef, columnIndex) { | ||
let content | ||
if (customRenderer) { | ||
content = customRenderer(columnDef, row) | ||
} | ||
if (content == null) { | ||
if (columnDef.tdRenderer) { | ||
content = columnDef.tdRenderer(columnDef, row) | ||
} | ||
if (content == null) { | ||
content = defaultTdRenderer(columnDef, row) | ||
} | ||
} | ||
rowHTML += '<td data-index="' + columnIndex + '">' + content + '</td>' | ||
}) | ||
@@ -339,0 +379,0 @@ rowHTML += '</tr>' |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
108589
2957