Our blazing fast Grid component built with pure JavaScript


Post by carlsvensson »

Hi there!

I'm using a Bryntum Grid through the React wrapper. I would like to set the scroll position of the grid after it has been completely populated, using restoreScroll().

However, I'm not sure when I should call restoreScroll(). I've tried hooking it to the renderRows event, but it seems to fire too early for what I wanto to do and the scroll position ends up wrong (E.G. halfway down the grid even though it should be scrolled to the bottom).

I'm wondering if there's some event I'm missing that I should be using or if there's some other technique I could employ to achieve the desired result.

Thanks in advance!


Post by saki »

How do you reload the grid records? renderRows seems to be good event to hook on but you could also use Promise returned from store.load() call and restore the scroll in its resolve.

In any case a showcase or a steps to reproduce with one of our demos would greatly help.


Post by carlsvensson »

Thanks for the swift reply. It's a tree grid which is populated using the data attribute on the react tag, so there's no AjaxStore. If renderRows is indeed the recommended event I should investigate further, because it's possible we're doing something that introduces an unexpected behavior. I will get back when I know more!


Post by carlsvensson »

I doesn't seem as if renderRows does what I want. I've constructed a simple example (see below). In it, the grid remains at the original position (left 0, top 0) even after using restoreScroll() in renderRows. When pressing the "Restore scroll" button, however, it immediately jumps to the correct position.

<html>
<head>
    <meta charset="utf-8">
    <script src="grid.umd.js"></script>
    <link rel="stylesheet" href="grid.material.css" id="bryntum-theme">
    <style>
    </style>
</head>
<body>
<div id="target" style="height:300px; border:1px solid red;"></div>
<script>
function makeData() {
    const s = "1222222122223123212342121221221222122123323122222222312323122222223".split("");
    const d = [], pp = {}, mr = { title: "", children: [], l: 0, expanded: true };
    let nc = 0, cp = null, pn = null;
    for(let l of s) {
        l = Number(l); ++nc;
        const cn = { title: "Node " + nc, l: l };
        if(!pn) {
            pn = mr; cp = mr; pp[cn.l] = mr;
        }
        if(cn.l === pn.l) {
            if(!cp.children) { cp.children = []; cp.expanded = true };
            cp.children.push(cn);
        } else if (cn.l > pn.l) {
            cp = pn;
            if(!cp.children) { cp.children = []; cp.expanded = true };
            cp.children.push(cn);
            pp[cn.l] = cp;
        } else {
            cp = pp[cn.l];
            if(!cp) cp = mr;
            if(!cp.children) { cp.children = []; cp.expanded = true };
            cp.children.push(cn);
        }
        pn = cn;
    }
    return mr.children;
}

const scrollState = { scrollLeft: { normal: 0 }, scrollTop: 2000 };

const grid = new bryntum.grid.Grid({
    appendTo: 'target',

features: {
    tree: true
},

columns: [
    { type: 'tree', field : 'title', text : 'Title', flex : 1 },
],

data: makeData(),

listeners: {
    renderRows: function(evt) {
        evt.source.restoreScroll(scrollState);
        console.log("rendered rows...",evt.source.storeScroll());
    }
}
});

const restoreScroll = () => grid.restoreScroll(scrollState);
</script>
<input type="button" onclick="restoreScroll()" value="Restore scroll">
</body>
</html>

Post by Maxim Gorkovsky »

Hello.
renderRows is not a good event to restore scroll, because just after this event is triggered, grid will try to restore scroll on its own to [0, 0]. It will work if you change event to paint:

listeners : {
  paint: function(evt) {
    evt.source.restoreScroll(scrollState);
    console.log("rendered rows...",evt.source.storeScroll());
  }
}

Post by carlsvensson »

Thanks, I'll try that!


Post Reply