179 lines
4.2 KiB
JavaScript

import Control from './Control';
import UI from './Manager';
/**
* 数据表格
* @author tengge / https://github.com/tengge1
* @param {*} options
*/
function DataTable(options = {}) {
Control.call(this, options);
this.cols = options.cols || []; // 结构: { field: 'name', title: '姓名', width: 100 }
this.rows = options.rows || []; // 结构: { name: '小明', age: 18 }
this.url = options.url || null; // 返回数据格式:{ total: 100, rows: [{ name: '小明', age: 18 }, ...] }
this.cls = options.cls || 'Table';
this.style = options.style || null;
this.selected = null;
}
DataTable.prototype = Object.create(Control.prototype);
DataTable.prototype.constructor = DataTable;
DataTable.prototype.render = function () {
this.dom = document.createElement('div');
this.parent.appendChild(this.dom);
if (this.cls) {
this.dom.className = this.cls;
}
if (this.style) {
Object.assign(this.dom.style, this.style);
}
// 计算列的总宽度
this.totalWidth = 0;
this.cols.forEach(n => {
this.totalWidth += n.width || 100;
});
// 表格头
this.head = document.createElement('table');
this.head.className = 'head';
this.dom.appendChild(this.head);
var tr = document.createElement('tr');
var th = document.createElement('th'); // 序号列
th.innerHTML = '#';
Object.assign(th.style, {
width: '60px',
textAlign: 'center'
});
tr.appendChild(th);
this.cols.forEach(n => { // 数据列
var th = document.createElement('th');
th.innerHTML = n.title || ' ';
Object.assign(th.style, {
width: `${this.dom.clientWidth / this.totalWidth * (n.width || 100)}px`
});
tr.appendChild(th);
});
this.head.appendChild(tr);
this.reload();
};
DataTable.prototype.reload = function () {
this.clear();
if (this.url) {
fetch(url).then(response => {
if (response.ok) {
response.json().then(json => {
this.rows = json.rows;
this._renderData();
});
}
});
} else {
this._renderData();
}
};
DataTable.prototype._renderData = function () {
// 表格体
this.body = document.createElement('table');
this.body.className = 'body';
this.dom.appendChild(this.body);
if (!this.rows) {
return;
}
this.rows.forEach((n, i) => {
var tr = document.createElement('tr');
var td = document.createElement('td'); // 序号列
td.innerHTML = `${i + 1}`;
Object.assign(td.style, {
width: '60px',
textAlign: 'center'
});
tr.appendChild(td);
this.cols.forEach(m => { // 数据列
var td = document.createElement('td');
if (n[m.field]) {
td.innerHTML = n[m.field];
}
Object.assign(td.style, {
width: `${this.dom.clientWidth / this.totalWidth * (n.width || 100)}px`
});
tr.appendChild(td);
});
tr.setAttribute('data-index', i);
tr.addEventListener('click', this._clickRow.bind(this));
this.body.appendChild(tr);
});
};
DataTable.prototype._clickRow = function (event) {
var tr = event.target.parentNode;
var index = tr.getAttribute('data-index'); // tr
this.selected = this.rows[index];
var tds = tr.parentNode.children;
for (var i = 0; i < tds.length; i++) {
Object.assign(tds[i].style, {
backgroundColor: '',
color: ''
});
}
Object.assign(tds[index].style, {
backgroundColor: '#08f',
color: '#fff'
});
};
DataTable.prototype.getSelected = function () {
return this.selected;
};
DataTable.prototype.clear = function () {
if (!this.body) {
return;
}
var body = this.body;
while (body.children.length) {
var tr = body.children[0];
tr.removeEventListener('click', this._clickRow);
body.removeChild(tr);
}
this.dom.removeChild(body);
this.body = null;
this.selected = null;
};
UI.addXType('datatable', DataTable);
export default DataTable;