Dear Preslav,
Here the code used to manage First/Prev/Next/Last toolbar using Virtual scrolling.
I manage two cases : When grid is hidden or displayed.
The function called to sync
scrollSync : function(){
oTab.oGrid.resize(true);
var rowTop = oTab.oGrid.select().offset().top;
var rowHeight = oTab.oGrid.select().height();
var rowHeightNext = rowHeight
var rowHeightPrev = rowHeight
var rowBottom = rowTop + rowHeight;
var gridTop = oTab.oGrid.wrapper.find('.k-grid-content').offset().top;
var gridBottom = gridTop + oTab.oGrid.wrapper.find('.k-grid-content').height();
if (typeof oTab.oVars.trNext != "undefined"){
if (oTab.oVars.trNext != null){
rowHeightNext = oTab.oVars.trNext.height();
}
}
if (rowHeightNext==null){
rowHeightNext = rowHeight;
}
if (typeof oTab.oVars.trPrev != "undefined"){
if (oTab.oVars.trPrev != null){
rowHeightPrev = oTab.oVars.trPrev.height();
}
}
if (rowHeightPrev==null){
rowHeightPrev = rowHeight;
}
if (rowBottom >= gridBottom){
var vs = oTab.oGrid.wrapper.find('.k-grid-content').data('kendoVirtualScrollable');
var scrollTop = vs.verticalScrollbar.scrollTop();
var scrollTopNew = (rowBottom - gridBottom) + scrollTop + rowHeightNext;
vs.verticalScrollbar.animate({ scrollTop: scrollTopNew}, 250);
}
else if (rowTop <= gridTop){
var vs = oTab.oGrid.wrapper.find('.k-grid-content').data('kendoVirtualScrollable');
var scrollTop = vs.verticalScrollbar.scrollTop();
var scrollTopNew = scrollTop - rowHeightPrev;
if (scrollTopNew >= 0){
vs.verticalScrollbar.animate({ scrollTop: scrollTopNew}, 250);
}
}
}
Here the code for buttons:
first : function () {
oTab.oVars.lScroll=false;
if(oTab.oGrid.dataSource.page() != 1){
oTab.oVars.idproToSelect=null;
oTab.oVars.uidToSelect=null;
oTab.oVars.gotoFirstRow=true;
oTab.oGrid.dataSource.page(1);
}
else {
oTab.oGrid.select("tr:eq('0')");
}
},
prev : function () {
if (oTab.oVars.uidPrev == null){ // No previous record ?
// Grid hidden ? => Load records using datasource.page()
if (oTab.oTabs.select().index()>0){
if (oTab.oGrid.dataSource.page() > 1){
oTab.oVars.uidToSelect = "Prev"; // => Will be processed by databound
oTab.oVars.idproToSelect = "Prev"; // => Will be processed by databound
oTab.oGrid.dataSource.page(oTab.oGrid.dataSource.page() - 1);
}
}
return;
}
oTab.oVars.uidToSelect=oTab.oVars.uidPrev; // => Will be processed by databound
oTab.oVars.idproToSelect=oTab.oVars.idproPrev; // => Will be processed by databound
oTab.oGrid.select("tr[data-uid='"+oTab.oVars.uidPrev+"']");
oTab.oVars.lButton=false;
},
next : function () {
if (oTab.oVars.uidNext == null){
// Grid hidden ? => Load via datasource.page()
if (oTab.oTabs.select().index()>0){
if (oTab.oGrid.dataSource.page() <
oTab.oGrid.dataSource.totalPages
()){
oTab.oVars.uidToSelect
=
"Next"
; // => Will be processed by databound
oTab.oVars.idproToSelect = "Next"; // => Will be processed by databound
oTab.oGrid.dataSource.page(oTab.oGrid.dataSource.page() + 1);
}
return;
}
oTab.oVars.uidToSelect=oTab.oVars.uidNext; // => Will be processed by databound
oTab.oVars.idproToSelect=oTab.oVars.idproNext; // => Will be processed by databound
oTab.oGrid.select("tr[data-uid='"+oTab.oVars.uidNext+"']");
},
last : function () {
if(oTab.oGrid.dataSource.page() <
oTab.oGrid.dataSource.totalPages
()){
oTab.oVars.idproToSelect
=
null
;
oTab.oVars.uidToSelect
=
null
;
oTab.oVars.lScroll
=
false
;
// Grid hidden ?
if (oTab.oTabs.select().index()>0){
oTab.oVars.gotoPrevLastPage=true;
oTab.oVars.uidToSelect = "Last"; // => Will be processed by databound
oTab.oVars.idproToSelect = "Last"; // => Will be processed by databound
oTab.oGrid.dataSource.page(oTab.oGrid.dataSource.totalPages());
}
else{
oTab.oVars.gotoLastRow=true;
var s=oTab.oGrid.wrapper.find(".k-scrollbar-vertical");
var h=$(s).prop('scrollHeight');
$(s).scrollTop(h);
}
}
else {
// Get lastrow
var i=oTab.oGrid.dataSource.view().length - 1;
if (i<0){
i=0;
}
// Select lastrow
oTab.oGrid.select("tr:eq('"+i+"')");
}
}
The change event for the grid :
change: function (e) {
var td;
/*
* Save current, prev and next record informations
*/
oTab.oVars.recordCurrent = this.dataItem(this.select());
oTab.oVars.recordId=oTab.oVars.recordCurrent.id;
oTab.oVars.idproCurrent = oTab.oVars.recordCurrent.idpro;
oTab.oVars.uidCurrent = oTab.oVars.recordCurrent.uid;
oTab.oVars.trCurrent=oTab.oGrid.element.find("tr[data-uid='" + oTab.oVars.uidCurrent + "']");
oTab.oVars.trNext = oTab.oVars.trCurrent.next('tr');
oTab.oVars.uidNext = oTab.oVars.trNext.attr("data-uid");
td = oTab.oVars.trNext.find("td[data-field='idpro']");
oTab.oVars.idproNext=td.html();
oTab.oVars.trPrev = oTab.oVars.trCurrent.prev('tr');
oTab.oVars.uidPrev = oTab.oVars.trPrev.attr("data-uid");
td = oTab.oVars.trPrev.find("td[data-field='idpro']");
oTab.oVars.idproPrev=td.html();
// Sync scrollbar
if (oTab.oVars.lScroll){
oTab.oFuns.scrollSync();
}
else {
oTab.oVars.lScroll=true;
}
},
This is what happens in databound, that is when new records need to be fetched :
dataBound: function(e) {
// Last row required
if (oTab.oVars.gotoLastRow){
oTab.oVars.gotoLastRow=false;
// Refresh scrollbar
oTab.oGrid.resize(true);
// get last row
var i=oTab.oGrid.dataSource.view().length - 1;
// Select last row
oTab.oGrid.select("tr:eq('"+i+"')");
}
// First row required
else if (oTab.oVars.gotoFirstRow){
oTab.oVars.gotoFirstRow=false;
// Refresh scrollbar
oTab.oGrid.resize(true);
// Scroll to top
oTab.oGrid.wrapper.find(".k-scrollbar-vertical").scrollTop(0);
// row
oTab.oGrid.select("tr:eq('0')");
}
// Other row required (Next ou Prev)
else if (oTab.oVars.idproToSelect != null){
var td;
// Nextwhen grid is hidden
if (oTab.oVars.idproToSelect == "Next"){
// Finding first td whith field "idpro" (Progress rowid of the record)
td = oTab.oGrid.element.find("td[data-field='idpro']");
// Finding the row = tr parent of td
oTab.oVars.trNext = td.parent();
oTab.oVars.idproNext=td.html();
// Row uid
oTab.oVars.uidNext = oTab.oVars.trNext.attr("data-uid");
// Grid hidden in thus case => no scroll
oTab.oVars.lScroll=false;
oTab.oGrid.select("tr[data-uid='"+oTab.oVars.uidNext+"']");
// re enable scroll for further oparations
oTab.oVars.lScroll=true;
}
// Prev when grid is hidden
else if (oTab.oVars.idproToSelect == "Prev"){
// td for field idpro
td = oTab.oGrid.element.find("td:last[data-field='idpro']");
// row = tr parent of td
oTab.oVars.trPrev = td.parent();
// Row uid
oTab.oVars.idproPrev=td.html();
oTab.oVars.uidPrev = oTab.oVars.trPrev.attr("data-uid");
// Grid hidden in this case => no scroll
oTab.oVars.lScroll=false;
oTab.oGrid.select("tr[data-uid='"+oTab.oVars.uidPrev+"']");
// re enable scroll
oTab.oVars.lScroll=true;
}
// Next or Prev when grid is displayed (scroll already occured)
else {
// uid to select using idproToSelect
oTab.oGrid.element.find("td[data-field='idpro']").each(function(i, item) {
if($(item).html() == oTab.oVars.idproToSelect) {
oTab.oVars.uidToSelect=$(item).parent().attr('data-uid');
}
});
// Scrollalready occured so disabling it
oTab.oVars.lScroll=false;
oTab.oGrid.select("tr[data-uid='"+oTab.oVars.uidToSelect+"']");
oTab.oVars.lScroll=true;
}
// RAZ
oTab.oVars.uidToSelect=null;
oTab.oVars.idproToSelect=null;
}
// Row selected using mouse
else {
// Finding uid to select using idproCurrent
oTab.oGrid.element.find("td[data-field='idpro']").each(function(i, item) {
if($(item).html() == oTab.oVars.idproCurrent) {
oTab.oVars.uidCurrent=$(item).parent().attr('data-uid');
}
});
oTab.oVars.lScroll=false;
oTab.oGrid.select("tr[data-uid='"+oTab.oVars.uidCurrent+"']");
oTab.oVars.lScroll=true;
}
}
},
To manage the case when grid is hidden, I try to sync grid whe it is displayed using tab event "activate"
var onActivate = function(e) {
// Get main object to get grid
var oTab = window[JSTabsCurrent]["getTab"]();
// Onglet 0 ?
if(oTab.oTabs.select().index()==0){
// Just resize then call scrollSunc
oTab.oGrid.resize(true);
oTab.oFuns.scrollSync();
}
}
I hope it makes it clearer.
I quicly tried the endless mode however, I can figure out how to programmatically scroll as object "kendoVirtualScrollable" does not exist in this mode.
Regards,
André.