javascriptjqueryjsongridstack

Loading Gridstack ID's from JSON


I have a gridstack project I am working on that I can manually add widgets with different content. I can lay them out how I want, and then save the layout. I can load the layout back to the last save point at anytime. Here is a fiddle of it: https://jsfiddle.net/m9rvcsu1/

My problem is that when I load the layout, the coordinates and size is correct, but the content of the widgets is wrong. All widget content gets set back to the default widget.

I believe my issue is caused by this line: myGrid.load(JSON.parse($('#tile-placement-string').val()), '#default-tile');

So to fix this, I imagine I need to load the id of each widget into my json string that I use to save/load positions? How can I do this properly?

This is how my json looks: [{"x":0,"y":0,"width":2,"height":2},{"x":2,"y":0,"width":2,"height":2},{"x":4,"y":0,"width":2,"height":2}]

This is my save function, and the click function that calls it:

function save() {
    return $.makeArray($(id + ' > .grid-stack-item:visible')).map(function (v) {
        var n = $(v).data('_gridstack_node');
        return n ? { x: n.x, y: n.y, width: n.width, height: n.height } : null; //add in ability to store tile id for content loading
    });
}

$('#save-grid').click(function () {
    $('#tile-placement-string').val(JSON.stringify(myGrid.save())); //save tile coordinates as json
});

And here is how I load the data:

function load(data, defaultTile) {
    gridObj.removeAll();
    $.each(data, function (k, v) { addTile(defaultTile, v.x, v.y, v.width, v.height); });
}

$('#load-grid').click(function () {
    myGrid.load(JSON.parse($('#tile-placement-string').val()), '#default-tile'); //load tile coordinates from json string
});

More context can be found in my fiddle.

To reproduce the problem:

Click Edit UI, then click Chart 1, then click Chart 2

Click Edit UI, then click Save

Click Edit UI, then click Load (notice all the tiles contents have been changed to the default tile)

Any help is appreciated!


Solution

  • First of all, let's set data-gs-id attribute according to docs in the addTile method:

    gridObj.addWidget(tile, x, y, w, h, null, null, null, null, null, defaultTile);
    

    Then, let's read and save it in the save method:

    var gsId = $(v).data('gs-id');
    return n ? { x: n.x, y: n.y, width: n.width, height: n.height, id: gsId } : null;
    

    Finally, let's use it for loading in load method:

    $.each(data, function (k, v) { addTile(v.gsId || defaultTile, v.x, v.y, v.width, v.height); });