sky.js/sky.tables.js

234 lines
5.3 KiB
JavaScript

(function(SKY,$){
var defaultOptions = {
url: null,
rows: [],
columns: [],
pagification: {
rows: 25,
},
select: null,
};
var defaultColumn = {
type: "string",
};
class HTML {
constructor(skyTable, table){
this.skyTable = skyTable;
this.table = table;
this.head = $("<thead></thead>").appendTo(table);
this.body = $("<tbody></tbody>").appendTo(table);
this.footer = $("<tfooter></tfooter>").appendTo(table);
this.rowCache = [];
this.usedRows = {};
}
createRow(){
var self = this;
var row = $("<tr></tr>")
.addClass("skytable skytable-row")
.on("click", function(){
self.skyTable.fireRowClick($(this));
})
.on("dblclick", function(){
self.skyTable.fireRowDblClick($(this));
});
for (var n=0;n<this.skyTable.columns.length;n++){
$("<td></td>")
.addClass("skytable skytable-cell")
.appendTo(row);
}
return row.get(0);
}
attachDataRow(iRow){
if (this.rowCache.length == 0)
this.rowCache.push(this.createRow());
var row = this.skyTable.data.rows[iRow];
var htmlRow = $(this.rowCache.pop());
htmlRow.data( "data-row", row );
htmlRow.data( "data-row-index", iRow );
var cells = $("td", htmlRow);
for (var n=0;n<this.skyTable.columns.length;n++){
$(cells[n])
.text( this.skyTable.columns[n].type.render( row[this.skyTable.columns[n].key] ) );
}
htmlRow.appendTo(this.body);
this.usedRows[iRow] = htmlRow;
}
detachDataRow(iRow){
if (this.usedRows[iRow])
{
$(this.usedRows[iRow]).detach();
this.rowCache.push(this.usedRows[iRow]);
}
}
get(iRow){
return this.usedRows[iRow];
}
empty(){
for (var iRow in this.usedRows){
var htmlRow = me.html.usedRows[iRow];
$(htmlRow).detach();
this.rowCache.push(htmlRow);
}
this.usedRows = {};
}
initializeHeader(){
this.columnHeader = $("<tr></tr>")
.addClass("skytable skytable-head")
.appendTo(this.head);
for (var n=0;n<this.skyTable.columns.length;n++){
$("<td></td>")
.text(this.skyTable.columns[n].label)
.addClass("skytable skytable-head")
.appendTo(this.columnHeader);
}
}
}
class DATA {
constructor(skyTable){
this.skyTable = skyTable;
this.rows= skyTable.options.rows;
this.firstrow = 0;
this.selectedRows = [];
}
getLastRow(){
var lastRow = this.firstrow + this.skyTable.options.pagification.rows;
if (lastRow > this.rows.length)
lastRow = this.rows.length;
return lastRow;
}
deselect(iRow){
var si = this.selectedRows.indexOf(iRow);
if (si != -1)
{
this.selectedRows.splice(si,1);
var htmlRow = this.skyTable.html.get(iRow);
if (htmlRow)
$(htmlRow).removeClass("selected");
this.skyTable.fire("deselect", { index: iRow, row: this.rows[iRow] } );
}
}
select(iRow){
if (!this.selectedRows.includes(iRow)){
this.selectedRows.push(iRow);
var htmlRow = this.skyTable.html.get(iRow);
if (htmlRow)
$(htmlRow).addClass("selected");
this.skyTable.fire("select", { index: iRow, row: this.rows[iRow] } );
}
}
toggleSelect(iRow){
if (this.skyTable.options.select == "single")
{
var doSelection = (!this.selectedRows.includes(iRow));
while (this.selectedRows.length)
this.deselect(this.selectedRows[0]);
if (doSelection)
this.select(iRow);
} else if (this.skyTable.options.select == "multi")
{
if (!this.selectedRows.includes(iRow))
this.select(iRow);
else
this.deselect(iRow);
}
}
}
$.fn.skyTable = function(opt){
if (this.length != 1)
throw "SkyTable must be constructed on exactly one <table>";
var self = this.get(0);
if (self.tagName != "TABLE")
self = this.parents("table").get(0);
if (!self)
throw "can't identify skyTable Element";
var skyTable = $(self).data( "sky.skyTable");
if (skyTable){
if (arguments.length)
throw "can't reinitialize SkyTable without prior destroy()";
return skyTable;
}
class SkyTable extends SKY.prototypes.SKYBase{
constructor(t){
super();
var me = this;
this.options = Object.assign( {}, defaultOptions, opt );
this.columns = []
t = $(t);
t .data( "sky.skyTable", this)
.addClass("skytable");
this.html = new HTML(this, t);
this.data = new DATA(this);
for (var key in this.options.columns){
var column = this.options.columns[key];
var skyColumn = Object.assign( {}, defaultColumn, column );
skyColumn.type = SKY.controls.getControl(skyColumn.type);
this.columns.push( skyColumn );
}
this.html.initializeHeader();
this.refresh();
}
reset(){
me.html.empty();
}
rows(rows){
if (arguments.length == 0)
return me.currentRows;
me.reset();
}
refresh(){
this.html.empty();
var lastRow = this.data.getLastRow();
for (var n = this.data.firstrow;n < lastRow; n++){
this.html.attachDataRow( n );
}
return this;
}
fireRowClick(row){
if (this.options.select)
this.data.toggleSelect( row.data("data-row-index") );
else
this.fire( "click", { index: row.data("data-row-index") , row: row.data("data-row") });
}
fireRowDblClick(row){
this.fire( "dblclick", { index: row.data("data-row-index") , row: row.data("data-row") });
}
}
return new SkyTable(self);
};
}(SKY,jQuery));