Use more standard sticky headers approach
parent
5848c14701
commit
12bac78cc2
296
stickyheaders.js
296
stickyheaders.js
|
@ -1,296 +0,0 @@
|
|||
// Simple Sticky Header and Column implementation for HTML tables
|
||||
// (c) Vitaliy Filippov 2016
|
||||
// License: MPL 2.0+
|
||||
// Version: 2016-12-06
|
||||
|
||||
// USAGE:
|
||||
// makeStickyHeaders(table): add sticky header and footer to table
|
||||
// table.parentNode is assumed to be the scroll container
|
||||
// checkStickyHeaders(table): call this after making table visible
|
||||
// (if you've hidden it before)
|
||||
// initStickyRows(table, trs): initialise table rows (trs = array[TableRow]) if not yet
|
||||
// fixStickyRows(table, trs): fix table row (trs = array[TableRow]) after modifications
|
||||
// fixStickyHeader(table): fix table header after modifications
|
||||
// fixStickyColumnSizes(table, force): adjust column sizes if something is modified
|
||||
// if force == true, reposition all fixed cells (header row and column)
|
||||
|
||||
// WARNING 1: after using this plugin all columns and rows except 0th ones become shifted by 1.
|
||||
// table.rows[1] and table.rows[*].cells[1] become special invisible rows/cells with copies of first
|
||||
// row and column content inside.
|
||||
|
||||
// WARNING 2: this plugin does NOT support border-collapse because it is implemented by non-integer border
|
||||
// sizes O_o and slightly differently in different browsers which leads to problems calculating cell positions.
|
||||
|
||||
// WARNING 3: for these hacks to work correctly, you need 'position: relative' on your table and table rows.
|
||||
|
||||
// WARNING 4: all table cells should obviously have non-transparent background
|
||||
// because fixed ones are positioned over normal.
|
||||
|
||||
// WARNING 5: make sure you have no CSS rules that will differ on the original header row/column and cloned one,
|
||||
// and that min/max width/height rules apply to the second row/column, not the first header one.
|
||||
|
||||
;(function() {
|
||||
|
||||
var _scri = 0;
|
||||
|
||||
function getOffsetRect(e)
|
||||
{
|
||||
var b = e.getBoundingClientRect();
|
||||
return {
|
||||
left: Math.round(b.left*100)/100,
|
||||
top: Math.round(b.top*100)/100,
|
||||
width: Math.round((b.right-b.left)*100)/100,
|
||||
height: Math.round((b.bottom-b.top)*100)/100
|
||||
};
|
||||
}
|
||||
|
||||
window.makeStickyHeaders = function(table)
|
||||
{
|
||||
if (!table._scrstyle)
|
||||
{
|
||||
table._scrstyle = document.createElement('style');
|
||||
(document.head||document.getElementsByTagName('head')[0]).appendChild(table._scrstyle);
|
||||
table._scri = _scri++;
|
||||
}
|
||||
if (!table.rows.length || !table.rows[0].children.length)
|
||||
return;
|
||||
var w = [], l = [], h = table.rows[0].offsetHeight;
|
||||
var sr = table.rows[0].cloneNode();
|
||||
sr.appendChild(document.createElement('td'));
|
||||
sr.children[0].style.width = '0';
|
||||
sr.children[0].style.display = 'block';
|
||||
sr.children[0].style.position = 'absolute';
|
||||
sr.children[0].style.padding = '0';
|
||||
sr.style.visibility = 'hidden';
|
||||
table._widths = [];
|
||||
table._sizerow = sr;
|
||||
table.rows[0].style.height = '0';
|
||||
table.rows[0].style.display = 'block';
|
||||
table.rows[0].style.position = 'absolute';
|
||||
table.rows[0].parentNode.insertBefore(sr, table.rows[0].nextSibling);
|
||||
fixStickyHeader(table, true);
|
||||
table._fixPending = true;
|
||||
checkStickyHeaders(table);
|
||||
var row0top = getOffsetRect(table.rows[0]).top-getOffsetRect(table.rows[0].offsetParent).top;
|
||||
addListener(table.parentNode, 'scroll', function(e)
|
||||
{
|
||||
var l = this.scrollLeft, t = this.scrollTop;
|
||||
table.rows[0].style.top = (t+row0top)+'px';
|
||||
if (!table._scrlastleft || table._scrlastleft != l)
|
||||
{
|
||||
table._scrstyle.innerHTML = l > 0 ? '._scri'+table._scri+' { left: '+l+'px; }' : '';
|
||||
table._scrlastleft = l;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// should be called after showing table to recalculate fixed cell sizes
|
||||
window.checkStickyHeaders = function(table)
|
||||
{
|
||||
if (table._fixPending)
|
||||
{
|
||||
delete table._fixPending;
|
||||
var rows = [];
|
||||
for (var i = 2; i < table.rows.length; i++)
|
||||
rows.push(table.rows[i]);
|
||||
fixStickyRows(table, rows);
|
||||
}
|
||||
}
|
||||
|
||||
// check if row(s) are not yet initialised and fix them
|
||||
window.initStickyRows = function(table, trs, nocols)
|
||||
{
|
||||
var ntrs = [];
|
||||
for (var i = 0; i < trs.length; i++)
|
||||
if (trs[i].children[0].className.indexOf(' _scri'+table._scri) < 0)
|
||||
ntrs.push(trs[i]);
|
||||
if (ntrs.length)
|
||||
fixStickyRows(table, ntrs, nocols);
|
||||
}
|
||||
|
||||
// handle non-header row(s) change with O(1) reflow count
|
||||
window.fixStickyRows = function(table, trs, nocols)
|
||||
{
|
||||
// (1) make some changes
|
||||
var e, d;
|
||||
for (var i = 0; i < trs.length; i++)
|
||||
{
|
||||
e = trs[i].children[0];
|
||||
if (e.className.indexOf(' _scri'+table._scri) >= 0)
|
||||
{
|
||||
// refix
|
||||
trs[i].removeChild(trs[i].children[1]);
|
||||
d = e.cloneNode(true);
|
||||
d.className = d.className.replace(' _scri'+table._scri, '');
|
||||
d.style.visibility = 'hidden';
|
||||
d.style.width = e._oldWidth;
|
||||
d.style.height = '';
|
||||
d.style.position = '';
|
||||
d.style.display = '';
|
||||
d.style.zIndex = '';
|
||||
e.parentNode.insertBefore(d, e.nextSibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fix new
|
||||
d = e.cloneNode(true);
|
||||
d.style.visibility = 'hidden';
|
||||
e.style.position = 'absolute';
|
||||
if (e.rowSpan > 1)
|
||||
e.rowSpan = 1;
|
||||
if (e.style.display == 'none')
|
||||
e.style.visibility = 'hidden';
|
||||
e.style.display = 'block';
|
||||
e.style.zIndex = '1';
|
||||
trs[i].insertBefore(d, e.nextSibling);
|
||||
e.className += ' _scri'+table._scri;
|
||||
}
|
||||
}
|
||||
if (table.offsetParent)
|
||||
{
|
||||
// (2) <REFLOW> caused by offsetWidth/offsetHeight
|
||||
// (3) remember sizes
|
||||
var w = [], h = [], b;
|
||||
for (var i = 0; i < trs.length; i++)
|
||||
{
|
||||
e = trs[i].children[1];
|
||||
b = getOffsetRect(e);
|
||||
w[i] = b.width;
|
||||
h[i] = b.height;
|
||||
}
|
||||
// (4) apply sizes
|
||||
for (var i = 0; i < trs.length; i++)
|
||||
{
|
||||
e = trs[i].children[0];
|
||||
e.style.width = w[i]+'px';
|
||||
e.style.height = h[i]+'px';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// table is invisible
|
||||
table._fixPending = true;
|
||||
}
|
||||
if (!nocols)
|
||||
fixStickyColumnSizes(table);
|
||||
}
|
||||
|
||||
window.fixStickyColumnSizes = function(table, force)
|
||||
{
|
||||
if (!table.offsetParent)
|
||||
{
|
||||
// table is invisible
|
||||
table._fixPending = true;
|
||||
return;
|
||||
}
|
||||
// check&fix column sizes
|
||||
var changed = false, resizeFixed = false;
|
||||
for (var i = 1; i < table._sizerow.children.length; i++)
|
||||
{
|
||||
var ne = table._sizerow.children[i];
|
||||
var nw = getOffsetRect(ne).width;
|
||||
var cw = table._widths[i-1];
|
||||
if (nw != cw || force)
|
||||
{
|
||||
table._widths[i-1] = nw;
|
||||
changed = true;
|
||||
if (i == 1)
|
||||
resizeFixed = true;
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
// reposition fixed header
|
||||
var w = [], h = [], l = [], b, pb = getOffsetRect(table._sizerow);
|
||||
for (var i = 0; i < table._sizerow.children.length; i++)
|
||||
{
|
||||
b = getOffsetRect(table._sizerow.children[i]);
|
||||
w[i] = b.width;
|
||||
h[i] = b.height;
|
||||
l[i] = b.left-pb.left;
|
||||
}
|
||||
b = table.rows[0].children[0];
|
||||
b.style.width = w[1]+'px';
|
||||
b.style.height = h[1]+'px';
|
||||
for (var i = 1; i < table._sizerow.children.length; i++)
|
||||
{
|
||||
b = table.rows[0].children[i];
|
||||
b.style.left = l[i]+'px';
|
||||
b.style.width = w[i]+'px';
|
||||
b.style.height = h[i]+'px';
|
||||
}
|
||||
if (resizeFixed)
|
||||
{
|
||||
// resize fixed column
|
||||
var h = [];
|
||||
for (var i = 0; i < table.rows.length; i++)
|
||||
h[i] = getOffsetRect(table.rows[i].children[1]).height;
|
||||
for (var i = 0; i < table.rows.length; i++)
|
||||
{
|
||||
if (i != 1)
|
||||
{
|
||||
table.rows[i].children[0].style.width = w[1]+'px';
|
||||
table.rows[i].children[0].style.height = h[i == 0 ? 1 : i]+'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle header row change
|
||||
window.fixStickyHeader = function(table, nocols)
|
||||
{
|
||||
var tr = table.rows[0];
|
||||
var sr = table._sizerow;
|
||||
while (sr.children[1])
|
||||
sr.removeChild(sr.children[1]);
|
||||
var b, e, renew = false;
|
||||
for (var i = 0; i < tr.children.length; i++)
|
||||
{
|
||||
b = tr.children[i];
|
||||
e = b.cloneNode(true);
|
||||
if (b._sticky)
|
||||
{
|
||||
if (i == 0)
|
||||
e.className = e.className.replace(' _scri'+table._scri, '');
|
||||
e.style.position = '';
|
||||
e.style.width = b._oldWidth;
|
||||
e.style.height = '';
|
||||
e.style.left = '';
|
||||
e.style.display = '';
|
||||
e.style.zIndex = '';
|
||||
if (i == 0)
|
||||
i++;
|
||||
}
|
||||
else
|
||||
renew = true;
|
||||
sr.appendChild(e);
|
||||
}
|
||||
if (renew)
|
||||
{
|
||||
for (var i = 0; i < tr.children.length; i++)
|
||||
{
|
||||
var e = tr.children[i];
|
||||
if (!e._sticky)
|
||||
{
|
||||
e.style.position = 'absolute';
|
||||
e.style.display = 'block';
|
||||
e.style.zIndex = '1';
|
||||
if (i == 0)
|
||||
{
|
||||
var d = e.cloneNode(true);
|
||||
d.style.visibility = 'hidden';
|
||||
tr.insertBefore(d, e.nextSibling);
|
||||
i++;
|
||||
e.className += ' _scri'+table._scri;
|
||||
e.style.zIndex = '2';
|
||||
}
|
||||
}
|
||||
}
|
||||
table._widths = [];
|
||||
}
|
||||
if (!nocols)
|
||||
fixStickyColumnSizes(table);
|
||||
}
|
||||
|
||||
})();
|
105
treegrid.css
105
treegrid.css
|
@ -6,30 +6,14 @@ img { vertical-align: middle; }
|
|||
body { -moz-text-size-adjust: none; } /* do not scale fonts in mobile firefox */
|
||||
/*table { border-collapse: collapse; }*/
|
||||
|
||||
/* scroll div styles */
|
||||
.scroller
|
||||
{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scroller > .inner
|
||||
{
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* fixed header table styles */
|
||||
table.grid tbody tr:hover, table.grid tbody tr:hover td
|
||||
table.grid tbody tr.hover, table.grid tbody tr.hover td
|
||||
{
|
||||
background-color: #e2eff8;
|
||||
}
|
||||
|
||||
table.grid tr.selected, table.grid td.selected, table.grid tr.selected:hover,
|
||||
table.grid tr.selected:hover td, table.grid tr:hover td.selected
|
||||
table.grid tr.selected, table.grid td.selected, table.grid tr.selected.hover,
|
||||
table.grid tr.selected.hover td, table.grid tr.hover td.selected
|
||||
{
|
||||
background-color: #c1ddf1;
|
||||
box-shadow: inset 0 0 0 1px #3d91cf;
|
||||
|
@ -50,7 +34,6 @@ table.grid
|
|||
{
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
border-left: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table.grid > *:first-child > tr:first-child > *, table.grid > tr:first-child > *
|
||||
|
@ -58,6 +41,14 @@ table.grid > *:first-child > tr:first-child > *, table.grid > tr:first-child > *
|
|||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table.grid > * > tr > td:first-child,
|
||||
table.grid > * > tr > th:first-child,
|
||||
table.grid > tr > td:first-child,
|
||||
table.grid > tr > th:first-child
|
||||
{
|
||||
border-left: 1px solid #ccc;
|
||||
}
|
||||
|
||||
table.grid, table.grid tr, table.grid td, table.grid th
|
||||
{
|
||||
box-sizing: border-box;
|
||||
|
@ -124,6 +115,12 @@ table.grid .celleditor
|
|||
position: relative;
|
||||
}
|
||||
|
||||
table.grid .celleditor div
|
||||
{
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
table.grid .celleditor input
|
||||
{
|
||||
box-shadow: inset 0 0 0 1px #3d91cf;
|
||||
|
@ -141,3 +138,71 @@ table.grid .celleditor input
|
|||
-moz-box-sizing: border-box;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.grid-wrapper
|
||||
{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grid-body-wrapper
|
||||
{
|
||||
position: absolute;
|
||||
padding-left: 200px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow: auto;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.grid-fixed-cell
|
||||
{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 200px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.grid-fixed-col-wrapper2
|
||||
{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 200px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.grid-fixed-col-wrapper
|
||||
{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.grid-fixed-row-wrapper
|
||||
{
|
||||
position: absolute;
|
||||
padding-left: 200px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
overflow: hidden;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
table.grid.grid-fixed-col > *:first-child > tr:first-child > *, table.grid.grid-fixed-col > tr:first-child > *
|
||||
{
|
||||
border-top: 0;
|
||||
}
|
||||
|
|
391
treegrid.js
391
treegrid.js
|
@ -1,13 +1,21 @@
|
|||
/**
|
||||
* Very simple and fast tree grid/table, compatible with dynamic loading and stickyheaders.js
|
||||
* Very simple and fast tree grid/table, with support for fixed header and column, compatible with dynamic loading
|
||||
*
|
||||
* License: MPL 2.0+, (c) Vitaliy Filippov 2016+
|
||||
* Version: 2016-12-06
|
||||
* Version: 2017-01-24
|
||||
*/
|
||||
|
||||
/**
|
||||
* USAGE:
|
||||
*
|
||||
* var TG = new TreeGrid({ items: items, header: header, renderer: renderer });
|
||||
* var TG = new TreeGrid({
|
||||
* items: items,
|
||||
* header: header,
|
||||
* renderer: renderer,
|
||||
* stickyHeaders: true|false,
|
||||
* stickyColumnWidth: '25%'|'200px',
|
||||
* stickyBorderWidth: 1
|
||||
* });
|
||||
* document.body.appendChild(TG.table);
|
||||
*
|
||||
* // renderer is a function that generates cell HTML properties for a node
|
||||
|
@ -83,11 +91,88 @@ function TreeGrid(options)
|
|||
this.table.appendChild(this.thead);
|
||||
this.table.appendChild(this.tbody);
|
||||
this.thead.appendChild(document.createElement('tr'));
|
||||
var self = this;
|
||||
if (options.stickyHeaders)
|
||||
{
|
||||
this.stickyHeaders = true;
|
||||
this.toSync = [];
|
||||
this.wrapper = document.createElement('div');
|
||||
// table for fixed cell
|
||||
this.fixedCell = document.createElement('table');
|
||||
this.fixedCell.className = 'grid grid-fixed-cell';
|
||||
this.fixedCell.appendChild(document.createElement('thead'));
|
||||
this.fixedCell.firstChild.appendChild(document.createElement('tr'));
|
||||
this.wrapper.appendChild(this.fixedCell);
|
||||
// table for fixed row
|
||||
this.fixedRow = document.createElement('table');
|
||||
this.fixedRow.className = 'grid grid-fixed-row';
|
||||
this.fixedRow.appendChild(this.thead);
|
||||
this.table.insertBefore(document.createElement('thead'), this.tbody);
|
||||
this.sizeRow = document.createElement('tr');
|
||||
this.table.firstChild.appendChild(this.sizeRow);
|
||||
this.fixedRowWrapper = document.createElement('div');
|
||||
this.fixedRowWrapper.className = 'grid-fixed-row-wrapper';
|
||||
this.fixedRowWrapper.appendChild(this.fixedRow);
|
||||
this.wrapper.appendChild(this.fixedRowWrapper);
|
||||
// table for fixed column
|
||||
this.fixedCol = document.createElement('table');
|
||||
this.fixedCol.className = 'grid grid-fixed-col';
|
||||
this.fixedColBody = document.createElement('tbody');
|
||||
this.fixedCol.appendChild(this.fixedColBody);
|
||||
this.fixedColWrapper = document.createElement('div');
|
||||
this.fixedColWrapper.className = 'grid-fixed-col-wrapper';
|
||||
this.fixedColWrapper.appendChild(this.fixedCol);
|
||||
this.fixedColWrapper2 = document.createElement('div');
|
||||
this.fixedColWrapper2.className = 'grid-fixed-col-wrapper2';
|
||||
this.fixedColWrapper2.appendChild(this.fixedColWrapper);
|
||||
this.wrapper.appendChild(this.fixedColWrapper2);
|
||||
// table body wrapper
|
||||
this.wrapper.className = 'grid-wrapper';
|
||||
this.tableWrapper = document.createElement('div');
|
||||
this.tableWrapper.className = 'grid-body-wrapper';
|
||||
this.tableWrapper.appendChild(this.table);
|
||||
this.wrapper.appendChild(this.tableWrapper);
|
||||
// sticky column width
|
||||
this.stickyBorderWidth = options.stickyBorderWidth || 1;
|
||||
if (options.stickyColumnWidth)
|
||||
this.setStickyColumnWidth(options.stickyColumnWidth);
|
||||
// scroll and resize handlers
|
||||
if (!options.noStickyResizeHandler)
|
||||
{
|
||||
addListener(window, 'resize', function()
|
||||
{
|
||||
self.syncStickyHeaders(true);
|
||||
});
|
||||
}
|
||||
addListener(this.tableWrapper, 'scroll', function()
|
||||
{
|
||||
if (self.scrolling != 2)
|
||||
{
|
||||
self.fixedRowWrapper.scrollLeft = self.tableWrapper.scrollLeft;
|
||||
self.fixedColWrapper.scrollTop = self.tableWrapper.scrollTop;
|
||||
self.scrolling = 1;
|
||||
}
|
||||
else
|
||||
self.scrolling = 0;
|
||||
});
|
||||
addListener(this.fixedColWrapper, 'scroll', function()
|
||||
{
|
||||
if (self.scrolling != 1)
|
||||
{
|
||||
self.tableWrapper.scrollTop = self.fixedColWrapper.scrollTop;
|
||||
self.scrolling = 2;
|
||||
}
|
||||
else
|
||||
self.scrolling = 0;
|
||||
});
|
||||
}
|
||||
addListener(this.wrapper||this.table, 'mouseover', function(ev) { self.nodeOnHover(true, ev); });
|
||||
addListener(this.wrapper||this.table, 'mouseout', function(ev) { self.nodeOnHover(false, ev); });
|
||||
this.setHeader(options.header);
|
||||
new TreeGridNode({ children: options.items }, this);
|
||||
}
|
||||
|
||||
function TreeGridNode(node, grid, level, insertBefore, startHidden)
|
||||
function TreeGridNode(node, grid, level, insertBeforeNode, startHidden, skipSync)
|
||||
{
|
||||
this.grid = grid;
|
||||
this.level = level;
|
||||
|
@ -101,6 +186,7 @@ function TreeGridNode(node, grid, level, insertBefore, startHidden)
|
|||
{
|
||||
this.leaf = node.leaf;
|
||||
this.collapsed = node.collapsed || !node.leaf && (!node.children || !node.children.length);
|
||||
this._oldCells = [];
|
||||
this.tr = [];
|
||||
for (var i = 0; i < (node.rows || 1); i++)
|
||||
{
|
||||
|
@ -110,87 +196,188 @@ function TreeGridNode(node, grid, level, insertBefore, startHidden)
|
|||
tr._node = this;
|
||||
this.tr.push(tr);
|
||||
}
|
||||
this._oldCells = [];
|
||||
if (grid.stickyHeaders)
|
||||
{
|
||||
this.col_tr = [];
|
||||
for (var i = 0; i < (node.rows || 1); i++)
|
||||
{
|
||||
var tr = document.createElement('tr');
|
||||
if (startHidden)
|
||||
tr.style.display = 'none';
|
||||
tr._node = this;
|
||||
this.col_tr.push(tr);
|
||||
}
|
||||
}
|
||||
this.render(undefined, undefined, false, true);
|
||||
for (var i = 0; i < this.tr.length; i++)
|
||||
{
|
||||
insertBefore ? grid.tbody.insertBefore(this.tr[i], insertBefore) : grid.tbody.appendChild(this.tr[i]);
|
||||
insertBeforeNode ? grid.tbody.insertBefore(this.tr[i], insertBeforeNode.tr[0]) : grid.tbody.appendChild(this.tr[i]);
|
||||
}
|
||||
if (grid.stickyHeaders)
|
||||
{
|
||||
for (var i = 0; i < this.col_tr.length; i++)
|
||||
{
|
||||
insertBeforeNode ? grid.fixedColBody.insertBefore(this.col_tr[i], insertBeforeNode.col_tr[0]) : grid.fixedColBody.appendChild(this.col_tr[i]);
|
||||
}
|
||||
grid.toSync.push(this);
|
||||
}
|
||||
}
|
||||
this.children = [];
|
||||
this.childrenByKey = {};
|
||||
if (node.children)
|
||||
{
|
||||
var trs = [];
|
||||
for (var i = 0; i < node.children.length; i++)
|
||||
{
|
||||
var child = new TreeGridNode(node.children[i], grid, this.level+1, insertBefore, this.collapsed);
|
||||
var child = new TreeGridNode(node.children[i], grid, this.level+1, insertBeforeNode, this.collapsed, true);
|
||||
child._index = i;
|
||||
this.children.push(child);
|
||||
if (child.key !== undefined)
|
||||
this.childrenByKey[child.key] = child;
|
||||
if (grid.stickyInit && !this.collapsed)
|
||||
trs.push.apply(trs, child.tr);
|
||||
}
|
||||
if (trs.length)
|
||||
fixStickyRows(grid.table, trs);
|
||||
}
|
||||
if (!skipSync)
|
||||
this.grid.syncStickyHeaders();
|
||||
}
|
||||
|
||||
(function() {
|
||||
|
||||
TreeGrid.prototype.initStickyHeaders = function(options)
|
||||
function htmlspecialchars(text)
|
||||
{
|
||||
this.sticky = true;
|
||||
this.noStickyResize = options.noWindowResize;
|
||||
if (this.header && this.header.length)
|
||||
this._makeStickyHeaders();
|
||||
return (''+text).replace(/&/g, '&')
|
||||
.replace(/'/g, ''') // '
|
||||
.replace(/"/g, '"') // "
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
TreeGrid.prototype.checkStickyHeaders = function()
|
||||
TreeGrid.prototype.nodeOnHover = function(hover, ev)
|
||||
{
|
||||
if (this.stickyInit)
|
||||
checkStickyHeaders(this.table);
|
||||
}
|
||||
|
||||
TreeGrid.prototype._makeStickyHeaders = function()
|
||||
{
|
||||
var self = this;
|
||||
this.table.className += ' stickyheaders';
|
||||
makeStickyHeaders(this.table);
|
||||
this.stickyInit = true;
|
||||
if (!this.noStickyResize)
|
||||
ev = ev||window.event;
|
||||
var e = ev.target||ev.srcElement;
|
||||
while (e.nodeName != 'TR' && e && e != this.wrapper && e != this.table)
|
||||
e = e.parentNode;
|
||||
if (!e._node)
|
||||
return;
|
||||
var subrow = 0;
|
||||
while (e.previousSibling && e.previousSibling._node == e._node)
|
||||
{
|
||||
addListener(window, 'resize', function()
|
||||
{
|
||||
if (self.stickyInit)
|
||||
fixStickyColumnSizes(self.table);
|
||||
});
|
||||
e = e.previousSibling;
|
||||
subrow++;
|
||||
}
|
||||
if (hover)
|
||||
e._node.tr[subrow].className += ' hover';
|
||||
else
|
||||
e._node.tr[subrow].className = e._node.tr[subrow].className.replace(/ hover/g, '');
|
||||
if (e._node.col_tr)
|
||||
{
|
||||
if (hover)
|
||||
e._node.col_tr[subrow].className += ' hover';
|
||||
else
|
||||
e._node.col_tr[subrow].className = e._node.col_tr[subrow].className.replace(/ hover/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
TreeGrid.prototype.setStickyColumnWidth = function(w)
|
||||
{
|
||||
this.fixedColWrapper2.style.width = w;
|
||||
if (!this.fixedColWrapper2.offsetWidth)
|
||||
return;
|
||||
w = this.fixedColWrapper2.offsetWidth;
|
||||
this.fixedColWrapper.style.width = (w+this.fixedColWrapper.offsetWidth-this.fixedColWrapper.clientWidth)+'px';
|
||||
this.tableWrapper.style.paddingLeft = (w-this.stickyBorderWidth)+'px';
|
||||
this.fixedRowWrapper.style.paddingLeft = (w-this.stickyBorderWidth)+'px';
|
||||
this.fixedCell.style.width = w+'px';
|
||||
}
|
||||
|
||||
TreeGrid.prototype.syncStickyHeaders = function(sync_all)
|
||||
{
|
||||
if (!this.stickyHeaders || !this.wrapper.offsetParent)
|
||||
return;
|
||||
if (this.fixedCol.offsetWidth)
|
||||
this.setStickyColumnWidth(this.fixedCol.offsetWidth+'px');
|
||||
var h1, h2, h = [];
|
||||
if (sync_all)
|
||||
{
|
||||
for (var i = 0; i < this.table.rows.length-1; i++)
|
||||
{
|
||||
h1 = this.table.rows[i+1].offsetHeight;
|
||||
h2 = this.fixedCol.rows[i].offsetHeight;
|
||||
if (h1 && h2)
|
||||
h[i] = h1 < h2 ? h2 : h1;
|
||||
}
|
||||
for (var i = 0; i < this.table.rows.length-1; i++)
|
||||
{
|
||||
if (h[i])
|
||||
{
|
||||
this.table.rows[i+1].style.height = h[i]+'px';
|
||||
this.fixedCol.rows[i].style.height = h[i]+'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < this.toSync.length; i++)
|
||||
{
|
||||
for (var k = 0; k < this.toSync[i].tr.length; k++)
|
||||
{
|
||||
h1 = this.toSync[i].tr[k].offsetHeight;
|
||||
h2 = this.toSync[i].col_tr[k].offsetHeight;
|
||||
h.push(h1 && h2 && (h1 < h2 ? h2 : h1));
|
||||
}
|
||||
}
|
||||
for (var i = 0, j = 0; i < this.toSync.length; i++)
|
||||
{
|
||||
for (var k = 0; k < this.toSync[i].tr.length; k++, j++)
|
||||
{
|
||||
if (h[j])
|
||||
{
|
||||
this.toSync[i].tr[k].style.height = h[j]+'px';
|
||||
this.toSync[i].col_tr[k].style.height = h[j]+'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.toSync = [];
|
||||
var trh = this.fixedRow.rows[0], w = [];
|
||||
for (var i = 0; i < trh.cells.length; i++)
|
||||
w[i] = this.sizeRow.cells[i] && this.sizeRow.cells[i].offsetWidth || 0;
|
||||
this.fixedRow.style.width = this.table.offsetWidth+'px';
|
||||
for (var i = 0; i < trh.cells.length; i++)
|
||||
trh.cells[i].style.width = w[i]+'px';
|
||||
this.tableWrapper.style.paddingTop = (this.fixedRow.offsetHeight-this.sizeRow.offsetHeight)+'px';
|
||||
this.fixedColWrapper2.style.bottom = (this.tableWrapper.offsetHeight-this.tableWrapper.clientHeight)+'px';
|
||||
this.fixedRowWrapper.style.right = (this.tableWrapper.offsetWidth-this.tableWrapper.clientWidth)+'px';
|
||||
this.fixedColWrapper.style.paddingTop = this.fixedRow.offsetHeight+'px';
|
||||
this.fixedCell.rows[0].cells[0].style.height = (this.fixedRow.offsetHeight)+'px';
|
||||
}
|
||||
|
||||
TreeGrid.prototype.setHeader = function(newHeader)
|
||||
{
|
||||
var tr = this.thead.rows[0];
|
||||
tr.innerHTML = '';
|
||||
if (this.stickyHeaders)
|
||||
{
|
||||
this.sizeRow.innerHTML = '';
|
||||
this.fixedCell.rows[0].innerHTML = '';
|
||||
}
|
||||
for (var i = 0; i < newHeader.length; i++)
|
||||
{
|
||||
var th = document.createElement('th');
|
||||
this._setProps(th, newHeader[i]);
|
||||
tr.appendChild(th);
|
||||
if (this.stickyHeaders && i == 0)
|
||||
this.fixedCell.rows[0].appendChild(th);
|
||||
else
|
||||
{
|
||||
tr.appendChild(th);
|
||||
if (this.stickyHeaders)
|
||||
this.sizeRow.appendChild(th.cloneNode(true));
|
||||
}
|
||||
}
|
||||
this.header = newHeader;
|
||||
this.editedCells = [];
|
||||
// header change clears the whole grid by now
|
||||
if (this.root)
|
||||
this.root.setChildren(false, []);
|
||||
if (this.sticky)
|
||||
{
|
||||
if (!this.stickyInit)
|
||||
this._makeStickyHeaders();
|
||||
else
|
||||
fixStickyHeader(this.table);
|
||||
}
|
||||
}
|
||||
|
||||
TreeGrid.prototype.onExpand = function(node)
|
||||
|
@ -231,11 +418,15 @@ TreeGrid.prototype._setProps = function(el, props)
|
|||
|
||||
TreeGrid.prototype._getCellIndex = function(n, sticky)
|
||||
{
|
||||
var i = 0;
|
||||
while ((n = n.previousSibling))
|
||||
i += (n.nodeType != 3 ? 1 : 0);
|
||||
if (sticky && this.stickyInit)
|
||||
i = (i > 0 ? i-1 : i);
|
||||
var i = 0, p = n;
|
||||
while ((p = p.previousSibling))
|
||||
i += (p.nodeType != 3 ? 1 : 0);
|
||||
if (sticky && this.stickyHeaders)
|
||||
{
|
||||
p = n.parentNode.parentNode.parentNode;
|
||||
if (p == this.table || p == this.fixedRow)
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -260,7 +451,7 @@ TreeGrid.prototype.initCellEditing = function()
|
|||
var td = evt.target||evt.srcElement;
|
||||
while (td.nodeName != 'TABLE' && td.nodeName != 'TD')
|
||||
td = td.parentNode;
|
||||
if (td.nodeName == 'TD' && td.parentNode._node && td.previousSibling && td.className.indexOf('celleditor') < 0)
|
||||
if (td.nodeName == 'TD' && td.parentNode._node && td.className.indexOf('celleditor') < 0)
|
||||
{
|
||||
var params = self.onStartCellEdit &&
|
||||
self.onStartCellEdit(td.parentNode._node, self._getSubrow(td), self._getCellIndex(td, true), td) || {};
|
||||
|
@ -381,7 +572,7 @@ function initMultiCellSelection(self)
|
|||
|
||||
self.table.className += ' disable-text-select';
|
||||
|
||||
addListener(self.table, 'mousedown', function(evt)
|
||||
addListener(self.wrapper||self.table, 'mousedown', function(evt)
|
||||
{
|
||||
evt = getEventCoord(evt);
|
||||
if (!evt.shiftKey)
|
||||
|
@ -531,7 +722,7 @@ TreeGridNode.prototype._addCollapser = function()
|
|||
collapser.className = this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
|
||||
addListener(collapser, 'click', this._getToggleHandler());
|
||||
}
|
||||
var c0 = this.tr[0].cells[0];
|
||||
var c0 = (this.col_tr || this.tr)[0].cells[0];
|
||||
c0.childNodes.length ? c0.insertBefore(collapser, c0.firstChild) : c0.appendChild(collapser);
|
||||
if (this.grid._initialPadding === undefined)
|
||||
{
|
||||
|
@ -558,10 +749,8 @@ TreeGridNode.prototype._hashEqual = function(a, b)
|
|||
|
||||
TreeGridNode.prototype._renderCell = function(rowIndex, colIndex, cell, force)
|
||||
{
|
||||
// this may be the first render of a row inside a stickyheaders grid
|
||||
var tr = this.tr[rowIndex];
|
||||
var isFix = tr.cells.length && tr.cells[0].className.indexOf(' _scri') >= 0;
|
||||
var ri = isFix ? (colIndex > 0 ? colIndex+1 : 0) : colIndex;
|
||||
var tr = (this.grid.stickyHeaders && colIndex == 0 ? this.col_tr : this.tr)[rowIndex];
|
||||
var ri = (this.grid.stickyHeaders && colIndex > 0 ? colIndex-1 : 0);
|
||||
while (!tr.cells[ri])
|
||||
tr.appendChild(document.createElement('td'));
|
||||
// virtualDOM-like approach: compare old HTML properties
|
||||
|
@ -569,7 +758,7 @@ TreeGridNode.prototype._renderCell = function(rowIndex, colIndex, cell, force)
|
|||
cell && !this._hashEqual(this._oldCells[rowIndex][colIndex], cell))
|
||||
{
|
||||
var old;
|
||||
if (isFix && colIndex == 0 && rowIndex == 0)
|
||||
if (colIndex == 0 && rowIndex == 0)
|
||||
{
|
||||
old = {
|
||||
width: tr.cells[ri].style.width,
|
||||
|
@ -583,17 +772,7 @@ TreeGridNode.prototype._renderCell = function(rowIndex, colIndex, cell, force)
|
|||
if (colIndex == 0)
|
||||
{
|
||||
if (rowIndex == 0)
|
||||
{
|
||||
this._addCollapser();
|
||||
if (isFix)
|
||||
{
|
||||
// FIXME: this is rather ugly :-( we need to restore stickyheaders styles
|
||||
tr.cells[ri]._oldWidth = tr.cells[ri].style.width;
|
||||
for (var i in old)
|
||||
tr.cells[ri].style[i] = old[i];
|
||||
tr.cells[ri].className += ' _scri'+this.grid.table._scri;
|
||||
}
|
||||
}
|
||||
else
|
||||
tr.cells[ri].style.paddingLeft = (this.grid._initialPadding + this.grid.levelIndent * this.level + 20) + 'px';
|
||||
}
|
||||
|
@ -602,7 +781,7 @@ TreeGridNode.prototype._renderCell = function(rowIndex, colIndex, cell, force)
|
|||
return false;
|
||||
}
|
||||
|
||||
TreeGridNode.prototype.render = function(colidx, rowidx, force, skipStickyFix)
|
||||
TreeGridNode.prototype.render = function(colidx, rowidx, force, skipSync)
|
||||
{
|
||||
var cells = this.grid.renderer(this, colidx, rowidx);
|
||||
if (this.tr.length == 1)
|
||||
|
@ -643,8 +822,12 @@ TreeGridNode.prototype.render = function(colidx, rowidx, force, skipStickyFix)
|
|||
modified = this._renderCell(i, j, cells[i] && cells[i][j], force) || modified;
|
||||
this._oldCells = cells;
|
||||
}
|
||||
if (modified && this.grid.stickyInit && !skipStickyFix)
|
||||
fixStickyColumnSizes(this.grid.table);
|
||||
if (modified && this.grid.stickyHeaders)
|
||||
{
|
||||
this.grid.toSync.push(this);
|
||||
if (!skipSync)
|
||||
this.grid.syncStickyHeaders();
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
@ -668,7 +851,8 @@ TreeGridNode.prototype.toggle = function()
|
|||
if (this.leaf)
|
||||
return;
|
||||
this.collapsed = !this.collapsed;
|
||||
this.tr[0].cells[0].firstChild.className = this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
|
||||
(this.col_tr || this.tr)[0].cells[0].firstChild.className =
|
||||
this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
|
||||
if (this.collapsed)
|
||||
{
|
||||
// collapse all children
|
||||
|
@ -678,6 +862,15 @@ TreeGridNode.prototype.toggle = function()
|
|||
c.style.display = 'none';
|
||||
c = c.nextSibling;
|
||||
}
|
||||
if (this.col_tr)
|
||||
{
|
||||
c = this.col_tr[this.col_tr.length-1].nextSibling;
|
||||
while (c && c._node.level > this.level)
|
||||
{
|
||||
c.style.display = 'none';
|
||||
c = c.nextSibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -690,17 +883,17 @@ TreeGridNode.prototype.toggle = function()
|
|||
for (var i = 0; i < e.tr.length; i++)
|
||||
{
|
||||
e.tr[i].style.display = '';
|
||||
if (this.grid.stickyInit)
|
||||
trs.push(e.tr[i]);
|
||||
if (this.grid.stickyHeaders)
|
||||
{
|
||||
e.col_tr[i].style.display = '';
|
||||
this.grid.toSync.push(e);
|
||||
}
|
||||
}
|
||||
if (!e.collapsed)
|
||||
st = st.concat(e.children);
|
||||
}
|
||||
if (trs.length && this.grid.stickyInit)
|
||||
fixStickyRows(this.grid.table, trs);
|
||||
}
|
||||
if (this.grid.stickyInit)
|
||||
fixStickyColumnSizes(this.grid.table);
|
||||
this.grid.syncStickyHeaders();
|
||||
}
|
||||
|
||||
TreeGridNode.prototype.setChildren = function(isLeaf, newChildren)
|
||||
|
@ -709,23 +902,32 @@ TreeGridNode.prototype.setChildren = function(isLeaf, newChildren)
|
|||
{
|
||||
// root node
|
||||
this.grid.tbody.innerHTML = '';
|
||||
if (this.grid.fixedColBody)
|
||||
this.grid.fixedColBody.innerHTML = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
var tr = this.tr[this.tr.length-1];
|
||||
while (tr.nextSibling && tr.nextSibling._node.level > this.level)
|
||||
this.grid.tbody.removeChild(tr.nextSibling);
|
||||
tr.parentNode.removeChild(tr.nextSibling);
|
||||
if (this.col_tr)
|
||||
{
|
||||
tr = this.col_tr[this.col_tr.length-1];
|
||||
while (tr.nextSibling && tr.nextSibling._node.level > this.level)
|
||||
tr.parentNode.removeChild(tr.nextSibling);
|
||||
}
|
||||
if (this.leaf != isLeaf)
|
||||
{
|
||||
var collapser = (this.col_tr || this.tr)[0].cells[0].firstChild;
|
||||
if (isLeaf)
|
||||
{
|
||||
this.tr[0].cells[0].firstChild.className = 'collapser collapser-inactive';
|
||||
removeListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
|
||||
collapser.className = 'collapser collapser-inactive';
|
||||
removeListener(collapser, 'click', this._getToggleHandler());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.tr[0].cells[0].firstChild.className = this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
|
||||
addListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
|
||||
collapser.className = this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
|
||||
addListener(collapser, 'click', this._getToggleHandler());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -746,20 +948,32 @@ TreeGridNode.prototype.removeChild = function(nodeOrIndex)
|
|||
}
|
||||
if (!this.children[nodeOrIndex])
|
||||
return false;
|
||||
var e = this.children[nodeOrIndex].tr[0];
|
||||
var tr = this.children[nodeOrIndex].tr[0];
|
||||
var col_tr = this.children[nodeOrIndex].col_tr && this.children[nodeOrIndex].col_tr[0];
|
||||
var l = this.children[nodeOrIndex].level;
|
||||
if (this.children[nodeOrIndex].key !== undefined)
|
||||
delete this.childrenByKey[this.children[nodeOrIndex].key];
|
||||
this.children.splice(nodeOrIndex, 1);
|
||||
for (var i = nodeOrIndex; i < this.children.length; i++)
|
||||
this.children[i]._index--;
|
||||
var k;
|
||||
var k, e;
|
||||
e = tr;
|
||||
do
|
||||
{
|
||||
k = e;
|
||||
e = e.nextSibling;
|
||||
k.parentNode.removeChild(k);
|
||||
} while (e && e._node.level > l);
|
||||
if (col_tr)
|
||||
{
|
||||
e = col_tr;
|
||||
do
|
||||
{
|
||||
k = e;
|
||||
e = e.nextSibling;
|
||||
k.parentNode.removeChild(k);
|
||||
} while (e && e._node.level > l);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -772,29 +986,26 @@ TreeGridNode.prototype.addChildren = function(nodes, insertBefore)
|
|||
insertBefore >= this.children.length)
|
||||
{
|
||||
insertBefore = this.children.length;
|
||||
// тут нужно получить следующий узел после текущего...
|
||||
e = this;
|
||||
while (e.children.length)
|
||||
e = e.children[e.children.length-1];
|
||||
e = e.tr ? e.tr[e.tr.length-1].nextSibling : null;
|
||||
e = e.tr && e.tr[e.tr.length-1].nextSibling ? e.tr[e.tr.length-1].nextSibling._node : null;
|
||||
}
|
||||
else
|
||||
e = this.children[insertBefore].tr[0];
|
||||
e = this.children[insertBefore];
|
||||
var trs = [];
|
||||
for (var i = 0; i < nodes.length; i++)
|
||||
{
|
||||
var child = new TreeGridNode(nodes[i], this.grid, this.level+1, e, this.collapsed);
|
||||
var child = new TreeGridNode(nodes[i], this.grid, this.level+1, e, this.collapsed, true);
|
||||
child._index = insertBefore+i;
|
||||
this.children.splice(insertBefore+i, 0, child);
|
||||
if (child.key !== undefined)
|
||||
this.childrenByKey[child.key] = child;
|
||||
// TODO: fix sticky only once per whole node batch, including children
|
||||
if (this.grid.stickyInit && !this.collapsed)
|
||||
trs.push.apply(trs, child.tr);
|
||||
}
|
||||
for (var i = insertBefore+nodes.length; i < this.children.length; i++)
|
||||
this.children[i]._index += nodes.length;
|
||||
if (trs.length)
|
||||
fixStickyRows(this.grid.table, trs);
|
||||
this.grid.syncStickyHeaders();
|
||||
return this.children.slice(insertBefore, nodes.length);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,18 +5,13 @@
|
|||
<link rel="stylesheet" type="text/css" href="treegrid.css" />
|
||||
<script type="text/javascript" src="util.js"></script>
|
||||
<script type="text/javascript" src="treegrid.js"></script>
|
||||
<script type="text/javascript" src="stickyheaders.js"></script>
|
||||
<style>
|
||||
table, tr, td, th { box-sizing: border-box; background: white; }
|
||||
table { border-collapse: separate; border-spacing: 0px; }
|
||||
th, td { border-width: 0 1px 1px 0 !important; }
|
||||
table td:nth-child(1) { width: 25%; }
|
||||
table.stickyheaders td:nth-child(2) { width: 25%; }
|
||||
.scroller { width: 100%; height: 400px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="scroller"><div class="inner" id="scroller"></div></div>
|
||||
<script>
|
||||
<!--
|
||||
(function()
|
||||
|
@ -24,7 +19,7 @@ table.stickyheaders td:nth-child(2) { width: 25%; }
|
|||
var i = {
|
||||
data: [ 'Payment from Gazprom to Shell 2', '4', '5' ]
|
||||
};
|
||||
var TG = new TreeGrid({ header: [], items: [], bind: { rowSpan: true }, renderer: function(node)
|
||||
var TG = window.TG = new TreeGrid({ header: [], items: [], bind: { rowSpan: true }, stickyHeaders: true, stickyColumnWidth: '200px', renderer: function(node)
|
||||
{
|
||||
var cells = [];
|
||||
for (var i = 0; i < node.data.length; i++)
|
||||
|
@ -32,13 +27,12 @@ table.stickyheaders td:nth-child(2) { width: 25%; }
|
|||
if (node.tr.length == 2)
|
||||
{
|
||||
cells = [ cells.slice(0), cells.slice(0) ];
|
||||
cells[0][0].rowSpan = 2;
|
||||
cells[1][0] = { style: 'display: none' };
|
||||
// cells[0][0].rowSpan = 2;
|
||||
// cells[1][0] = { style: 'display: none' };
|
||||
}
|
||||
return cells;
|
||||
} });
|
||||
TG.table.className = 'grid';
|
||||
document.getElementById('scroller').appendChild(TG.table);
|
||||
document.body.appendChild(TG.wrapper);
|
||||
setTimeout(function() {
|
||||
TG.setHeader([ '', '15 фев', '16 фев', '17 фев', '18 фев', '19 фев', '20 фев', '21 фев', '15 фев', '16 фев', '17 фев', '18 фев', '19 фев', '20 фев', '21 фев', '15 фев', '16 фев', '17 фев', '18 фев', '19 фев', '20 фев', '21 фев', '15 фев', '16 фев', '17 фев', '18 фев', '19 фев', '20 фев', '21 фев' ]);
|
||||
TG.root.setChildren(false, [ {
|
||||
|
@ -54,9 +48,6 @@ table.stickyheaders td:nth-child(2) { width: 25%; }
|
|||
data: [ 'Payment from Gazprom to Shell', '2', 'aaaaa' ]
|
||||
} ]);
|
||||
}, 1000);
|
||||
setTimeout(function() {
|
||||
TG.initStickyHeaders({});
|
||||
}, 3000);
|
||||
TG.onExpand = function(node)
|
||||
{
|
||||
// Dynamic loading example
|
||||
|
|
Loading…
Reference in New Issue