Search code examples
javascripthtmldomserializationgridstack

How to serialize and load an HTML element's data in gridstack.js?


I have a grid of styled books and their images, created with the gridstack library:

book gallery working

I also have a "save" button that calls a saveGrid() function to save the location of each book on the grid, and loads its serialized data with grid.load(serializedData)

HTML:

<div>
    <h1 class="title">Your Books</h1>
    <button onclick="saveGrid(); grid.load(serializedData)">Save</button>
</div>
<div class="grid-stack"></div>

JS:

saveGrid = () => {
    serializedData = [];
    grid.engine.nodes.forEach((node) => {
      serializedData.push({
        x: node.x,
        y: node.y,
        width: node.width,
        height: node.height,
        noResize: true, 
        el: node.el
      });
    });
  };

The problem is that, when the "save" button is clicked, the positions of the items are saved but not the actual HTML images and content (like buttons), as shown below:

book positions saved, but not images/content


Solution

  • I've figured out the problem and edited my saveGrid() function, as well as made a new loadGrid() function that loads the grid after saving and an addBooks() function that loads books from an array upon page load. Below is the HTML and the full JS code:

    HTML:

    <div class="grid-stack"></div>
    

    JS:

    var booksArray = [
        {"ISBN": '0385504209', "bookURL": "https://images.penguinrandomhouse.com/cover/9780767926034"},
        {"ISBN": '0143039431', "bookURL": "https://upload.wikimedia.org/wikipedia/commons/a/ad/The_Grapes_of_Wrath_%281939_1st_ed_cover%29.jpg"},
        {"ISBN": '0743273567', "bookURL": "https://prodimage.images-bn.com/pimages/9780743273565_p0_v8_s550x406.jpg"},
        {"ISBN": '0743297334', "bookURL": "https://upload.wikimedia.org/wikipedia/commons/8/8b/The_Sun_Also_Rises_%281st_ed._cover%29.jpg"},
        {"ISBN": '0553283685', "bookURL": "http://books.google.com/books/content?id=wDVV6y-8YHEC&printsec=frontcover&img=1&zoom=1&source=gbs_api"}
    ]
    
    var grid = GridStack.init({
        column: 8, 
        animate: true, 
        //kinda wonky -->  float: true,
        removable: true,
        rtl: true
    })
    
    const addBooks = () => {
        grid.batchUpdate()
        booksArray.forEach((book, index) => {
            grid.addWidget(`
            <div>
                <div class="grid-stack-item-content">  
                    <img src="${book.bookURL}" class="book-cover" id=${book.ISBN}></img>
                    <div class="button-group">
                        <a href="something" class="button4" style="background-color:#f21832"><i class="fa fa-minus-circle"></i></a>
    
                        <button class="btn button4" data-toggle="modal" data-target="#exampleModalLong" style="background-color:#4f21cf"><i class="fa fa-info-circle"></i></button>
                        
                        <a href="something" class="button4" style="background-color:#18de54"><i class="fa fa-check"></i></a>  
                    </div>  
                </div>
            </div>`, {
                width: 2,
                height: 3,
                noResize: true,
                staticGrid: true
            })
    
            grid.engine.nodes[index].ISBN = book.ISBN
            grid.engine.nodes[index].bookURL = book.bookURL
    
            console.log(document.querySelector('.book-cover').id)
    
        })
        grid.commit()  
        console.log(grid.engine.nodes)
    }
    
    const saveGrid = () => {
        serializedData = []
        console.log(grid.engine.nodes)
        grid.batchUpdate()
        grid.engine.nodes.forEach((node, index) => {
            console.log(node.el)
            console.log(node.ISBN)
            console.log(node.bookURL)
            serializedData.push({
                    x: node.x,
                    y: node.y,
                    width: 2,
                    height: 3,
                    noResize: true,
                    ISBN: node.ISBN,
                    bookURL: node.bookURL
            })
        })
        serializedData.sort()
        grid.commit()
        console.log(JSON.stringify(serializedData, null, '  '))
        console.log(grid.engine.nodes.length)
      }
    
    const loadGrid = () => {
        // empty the grid first:
        grid.removeAll({detachNode:false}) //{detachNode: false}
        // grid.assign()
        console.log(serializedData)
        var items = GridStack.Utils.sort(serializedData)
        console.log(items)
        grid.batchUpdate()
        items.forEach((node, index) => {
            grid.addWidget(`
            <div>
                <div class="grid-stack-item-content">  
                    <img src="${node.bookURL}" class="book-cover"></img>
                    <div class="button-group">
                        <a href="something" class="button4" style="background-color:#f21832"><i class="fa fa-minus-circle"></i></a>
                        <a href="something" class="button4" style="background-color:#4f21cf"><i class="fa fa-info-circle"></i></a>
                        <a href="something" class="button4" style="background-color:#18de54"><i class="fa fa-check"></i></a>  
                    </div>  
                </div>
            </div>`, node)
    
            grid.engine.nodes[index].ISBN = node.ISBN
            grid.engine.nodes[index].bookURL = node.bookURL
    
            console.log(node)
    
        })
        grid.commit()
        console.log(grid.engine.nodes.length)
        console.log(grid.engine.nodes)
      }
    
    window.onload = addBooks()