Forum
17:44
17/09/2011
Hi,
I am working on virtual scrolling with dynamic (changing) row height. I think I have it mostly working. This is how it works:
- calculate average row height from the currently displayed data: divide data table height with number of rows in the table
- use this row height in updatepager() to calculate total div height as well as 'top' div height
- use the same row height for calculating next page to load in pageVisible()
- every time new/updated data is loaded, average row height along with total height and 'top' div height is recalculated. This new row height is used for paging in pageVisible()
- scrollTop is adjusted in updatepager() to account for average row height change as data currently loaded/displayed is changed so the current row appears at the same location as before (this is not working 100% yet)
I tested it with local data only (loadonce is true).
Any comments on this approach? Where can I submit the code?
Thanks,
Erik
16:57
17/09/2011
Hi,
I resolved the issue with scrollTop and it seems to be working correctly. Bellow is the diff against jqGrid 4.1.2:
+++ jquery.jqGrid.src.js 2011-09-22 09:47:03.965509200 -0400
@@ -782,26 +782,39 @@
if (!dh) { return; }
var table = $("table:first", grid.bDiv);
var rows, rh;
- if(table[0].rows.length) {
- try {
- rows = table[0].rows[1];
- rh = rows ? $(rows).outerHeight() || grid.prevRowHeight : grid.prevRowHeight;
- } catch (pv) {
+ if (table[0].rows.length) {
+ if (table[0].rows.length > 1) {
+ try {
+ rh = table.height() / (table[0].rows.length - 1);
+ } catch (pv) {
+ rh = grid.prevRowHeight;
+ }
+ }
+ else {
rh = grid.prevRowHeight;
}
}
if (!rh) { return; }
- grid.prevRowHeight = rh;
+ grid.prevRowHeight = grid.currRowHeight;
+ grid.prevTableHeight = table.height();
var rn = p.rowNum;
var scrollTop = grid.scrollTop = grid.bDiv.scrollTop;
var ttop = Math.round(table.position().top) - scrollTop;
var tbot = ttop + table.height();
var div = rh * rn;
var page, npage, empty;
- if ( tbot < dh && ttop <= 0 &&
- (p.lastpage===undefined||parseInt((tbot + scrollTop + div - 1) / div,10) <= p.lastpage))
- {
- npage = parseInt((dh - tbot + div - 1) / div,10);
+ if (grid.scrollDiff < 0 && ttop > 0 && ttop < dh) {
+ grid.scrollDiff = ttop;
+ }
+ else {
+ if (grid.scrollDiff > 0 && tbot > 0 && tbot < dh)
+ grid.scrollDiff = tbot;
+ else
+ grid.scrollDiff = 0;
+ }
+ if (tbot < dh && ttop <= 0 &&
+ (p.lastpage === undefined || parseInt((tbot + scrollTop + div - 1) / div, 10) <= p.lastpage) ) {
+ npage = parseInt((dh - tbot + div - 1) / div, 10);
if (tbot >= 0 || npage < 2 || p.scroll === true) {
page = Math.round((tbot + scrollTop) / div) + 1;
ttop = -1;
@@ -823,18 +836,21 @@
} else {
p.page = page;
if (empty) {
+ grid.prevTableHeight = 0;
grid.selectionPreserver(table[0]);
grid.emptyRows(grid.bDiv,false, false);
}
grid.populate(npage);
}
}
+ grid.scrollDiff = 0;
},
scrollGrid: function( e ) {
if(p.scroll) {
var scrollTop = grid.bDiv.scrollTop;
if(grid.scrollTop === undefined) { grid.scrollTop = 0; }
if (scrollTop != grid.scrollTop) {
+ grid.scrollDiff = scrollTop - grid.scrollTop;
grid.scrollTop = scrollTop;
if (grid.timer) { clearTimeout(grid.timer); }
grid.timer = setTimeout(grid.populateVisible, p.scrollTimeout);
@@ -1537,19 +1553,45 @@
var cp, last, base, from,to,tot,fmt, pgboxes = "", sppg,
tspg = ts.p.pager ? "_"+$.jgrid.jqID(ts.p.pager.substr(1)) : "",
tspg_t = ts.p.toppager ? "_"+ts.p.toppager.substr(1) : "";
+ if (ts.p.page == 0) { ts.p.page = 1; }
base = parseInt(ts.p.page,10)-1;
if(base < 0) { base = 0; }
base = base*parseInt(ts.p.rowNum,10);
to = base + ts.p.reccount;
if (ts.p.scroll) {
+ if (!grid.scrollDiff) { grid.scrollDiff = 0; }
var rows = $("tbody:first > tr:gt(0)", ts.grid.bDiv);
base = to - rows.length;
ts.p.reccount = rows.length;
- var rh = rows.outerHeight() || ts.grid.prevRowHeight;
+ var th = $("table:first", ts.grid.bDiv).height();
+ var rh = th / rows.length;
+ grid.currRowHeight = rh;
if (rh) {
var top = base * rh;
- var height = parseInt(ts.p.records,10) * rh;
- $(">div:first",ts.grid.bDiv).css({height : height}).children("div:first").css({height:top,display:top?"":"none"});
+ var lpCnt = ts.p.records % ts.p.rowNum;
+ var pgCnt = ts.p.lastpage - ts.p.page - 1;
+ if (pgCnt < 0) { pgCnt = lpCnt = 0; }
+ var height = top + th + (pgCnt * ts.p.rowNum + lpCnt) * rh;
+ if ((top != 0 || (grid.scrollDiff != 0 && ts.p.page == 2)) && grid.prevRowHeight && grid.currRowHeight != grid.prevRowHeight) {
+ if (grid.prevTableHeight) {
+ grid.scrollTop = top + grid.prevTableHeight - grid.scrollDiff;
+ }
+ else {
+ if (grid.scrollDiff) {
+ grid.scrollTop = top - grid.scrollDiff;
+ var cnt = (Math.floor(rows.length / ts.p.rowNum) - 1) * ts.p.rowNum;
+ if (rows.length % ts.p.rowNum != 0) { cnt += ts.p.rowNum; }
+ for (var i = 0; i < cnt; i++) {
+ grid.scrollTop += $(rows[i]).outerHeight();
+ }
+ }
+ else {
+ grid.scrollTop = ts.grid.bDiv.scrollTop * grid.currRowHeight / grid.prevRowHeight;
+ }
+ }
+ }
+ $(">div:first", ts.grid.bDiv).css({ height: height }).children("div:first").css({ height: top, display: top ? "" : "none" });
+ ts.grid.bDiv.scrollTop = grid.scrollTop;
}
ts.grid.bDiv.scrollLeft = ts.grid.hDiv.scrollLeft;
}
Erik
18:27
17/09/2011
Hi,
there was an issue when the record count was exact multiply of rowNum. The fixed code below:
+++ jquery.jqGrid.src.js 2011-09-22 11:22:47.684100300 -0400
@@ -782,26 +782,39 @@
if (!dh) { return; }
var table = $("table:first", grid.bDiv);
var rows, rh;
- if(table[0].rows.length) {
- try {
- rows = table[0].rows[1];
- rh = rows ? $(rows).outerHeight() || grid.prevRowHeight : grid.prevRowHeight;
- } catch (pv) {
+ if (table[0].rows.length) {
+ if (table[0].rows.length > 1) {
+ try {
+ rh = table.height() / (table[0].rows.length - 1);
+ } catch (pv) {
+ rh = grid.prevRowHeight;
+ }
+ }
+ else {
rh = grid.prevRowHeight;
}
}
if (!rh) { return; }
- grid.prevRowHeight = rh;
+ grid.prevRowHeight = grid.currRowHeight;
+ grid.prevTableHeight = table.height();
var rn = p.rowNum;
var scrollTop = grid.scrollTop = grid.bDiv.scrollTop;
var ttop = Math.round(table.position().top) - scrollTop;
var tbot = ttop + table.height();
var div = rh * rn;
var page, npage, empty;
- if ( tbot < dh && ttop <= 0 &&
- (p.lastpage===undefined||parseInt((tbot + scrollTop + div - 1) / div,10) <= p.lastpage))
- {
- npage = parseInt((dh - tbot + div - 1) / div,10);
+ if (grid.scrollDiff < 0 && ttop > 0 && ttop < dh) {
+ grid.scrollDiff = ttop;
+ }
+ else {
+ if (grid.scrollDiff > 0 && tbot > 0 && tbot < dh)
+ grid.scrollDiff = tbot;
+ else
+ grid.scrollDiff = 0;
+ }
+ if (tbot < dh && ttop <= 0 &&
+ (p.lastpage === undefined || parseInt((tbot + scrollTop + div - 1) / div, 10) <= p.lastpage) ) {
+ npage = parseInt((dh - tbot + div - 1) / div, 10);
if (tbot >= 0 || npage < 2 || p.scroll === true) {
page = Math.round((tbot + scrollTop) / div) + 1;
ttop = -1;
@@ -823,18 +836,21 @@
} else {
p.page = page;
if (empty) {
+ grid.prevTableHeight = 0;
grid.selectionPreserver(table[0]);
grid.emptyRows(grid.bDiv,false, false);
}
grid.populate(npage);
}
}
+ grid.scrollDiff = 0;
},
scrollGrid: function( e ) {
if(p.scroll) {
var scrollTop = grid.bDiv.scrollTop;
if(grid.scrollTop === undefined) { grid.scrollTop = 0; }
if (scrollTop != grid.scrollTop) {
+ grid.scrollDiff = scrollTop - grid.scrollTop;
grid.scrollTop = scrollTop;
if (grid.timer) { clearTimeout(grid.timer); }
grid.timer = setTimeout(grid.populateVisible, p.scrollTimeout);
@@ -1537,19 +1553,46 @@
var cp, last, base, from,to,tot,fmt, pgboxes = "", sppg,
tspg = ts.p.pager ? "_"+$.jgrid.jqID(ts.p.pager.substr(1)) : "",
tspg_t = ts.p.toppager ? "_"+ts.p.toppager.substr(1) : "";
+ if (ts.p.page == 0) { ts.p.page = 1; }
base = parseInt(ts.p.page,10)-1;
if(base < 0) { base = 0; }
base = base*parseInt(ts.p.rowNum,10);
to = base + ts.p.reccount;
if (ts.p.scroll) {
+ if (!grid.scrollDiff) { grid.scrollDiff = 0; }
var rows = $("tbody:first > tr:gt(0)", ts.grid.bDiv);
base = to - rows.length;
ts.p.reccount = rows.length;
- var rh = rows.outerHeight() || ts.grid.prevRowHeight;
+ var th = $("table:first", ts.grid.bDiv).height();
+ var rh = th / rows.length;
+ grid.currRowHeight = rh;
if (rh) {
var top = base * rh;
- var height = parseInt(ts.p.records,10) * rh;
- $(">div:first",ts.grid.bDiv).css({height : height}).children("div:first").css({height:top,display:top?"":"none"});
+ var lpCnt = ts.p.records % ts.p.rowNum;
+ var pgCnt = ts.p.lastpage - ts.p.page - 1;
+ if (lpCnt == 0) { pgCnt++; }
+ if (pgCnt < 0) { pgCnt = lpCnt = 0; }
+ var height = top + th + (pgCnt * ts.p.rowNum + lpCnt) * rh;
+ if ((top != 0 || (grid.scrollDiff != 0 && ts.p.page == 2)) && grid.prevRowHeight && grid.currRowHeight != grid.prevRowHeight) {
+ if (grid.prevTableHeight) {
+ grid.scrollTop = top + grid.prevTableHeight - grid.scrollDiff;
+ }
+ else {
+ if (grid.scrollDiff) {
+ grid.scrollTop = top - grid.scrollDiff;
+ var cnt = (Math.floor(rows.length / ts.p.rowNum) - 1) * ts.p.rowNum;
+ if (rows.length % ts.p.rowNum != 0) { cnt += ts.p.rowNum; }
+ for (var i = 0; i < cnt; i++) {
+ grid.scrollTop += $(rows[i]).outerHeight();
+ }
+ }
+ else {
+ grid.scrollTop = grid.scrollTop * grid.currRowHeight / grid.prevRowHeight;
+ }
+ }
+ }
+ $(">div:first", ts.grid.bDiv).css({ height: height }).children("div:first").css({ height: top, display: top ? "" : "none" });
+ ts.grid.bDiv.scrollTop = grid.scrollTop;
}
ts.grid.bDiv.scrollLeft = ts.grid.hDiv.scrollLeft;
}
Erik
Most Users Ever Online: 715
Currently Online:
61 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
OlegK: 1255
markw65: 179
kobruleht: 144
phicarre: 132
YamilBracho: 124
Renso: 118
Member Stats:
Guest Posters: 447
Members: 11373
Moderators: 2
Admins: 1
Forum Stats:
Groups: 1
Forums: 8
Topics: 10592
Posts: 31289
Newest Members:
, razia, Prankie, psky, praveen neelam, greg.valainis@pa-tech.comModerators: tony: 7721, Rumen[Trirand]: 81
Administrators: admin: 66