daffodil
daffodil

Reputation: 197

How to save table with contenteditable column into local storage

I'm trying to save the content of column 3, with id name = 'edit' in the table, locally. Here is the code:

// Button to save edit
function saveEdits() {
   var table, tr, editElem, userVersion, i, j;
   table    = document.getElementById("mytable");
   tr       = table.getElementByClassName("output");

   editElems = {    
       for (i=0; i< tr.length; i++){
          //get the editable element
          userVersion[i] : tr[i].getElementsById("edit").innerHTML;
       }
   }
   localStorage.setItem('userEdits', JSON.stringify(editElems));
}

// place in the body to reload the changes
function checkEdits() {
    var userEdits = localStorage.getItem('userEdits');
    if (userEdits) {
        userEdits = JSON.parse(userEdits);
        for ( var elementId in userEdits ) {
            document.getElementById(elementId).innerHTML = userEdits[elementId];
        }
    }
 }

I am following tutorial in https://www.developerdrive.com/allowing-users-to-edit-text-content-with-html5/, but I want to apply it to the table, however, it doesn't work.

Here is my html code

<!doctype html>
<html>
<head>
   <title>BOOK LIST</title>
   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css">
   <link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css">
   <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
   <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
   <script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
   <script src=./javascript.js></script>
</head>  

<body onload="checkEdits()">

    <div class="header">
        <h1>BOOK</h1>
    </div>

    <div class="tbody">    
    <table id="mytable" align="center" class="table table-striped table-bordered" cellspacing="0">
        <thead>
            <tr>
                <th width="5%">#</th>
                <th width="20%">BOOK NAME</th>
                <th width="50%">AUTHOR</th>
                <th width="25%">DESCRIPTION</th>
            </tr>
        </thead>
        <tbody>
            <tr class='output'>
                <td>1</td>
                <td>BOOK 1</td>
                <td>John</td>
                <td id='edit' contenteditable='true'>No Description</td>
            </tr>
            <tr class='output'>
                <td>2</td>
                <td>BOOK 2</td>
                <td>Sara</td>
                <td id='edit' contenteditable='true'>No Description</td>
            </tr>
            <tr class='output'>
                <td>3</td>
                <td>BOOK 3</td>
                <td>Mary</td>
                <td id='edit' contenteditable='true'>No Description</td>
            </tr>
            <tr class='output'>
                <td>4</td>
                <td>BOOK 4</td>
                <td>Bob</td>
                <td id='edit' contenteditable='true'>No Description</td>

            <!---- TABLE FILTER AND SORT FUNCTION ---->
            <script>
                $(document).ready(function() {
                    $('#mytable').DataTable( {
                        "pagingType": "full_numbers"
                    });
                });
            </script>

        </tbody>
    </table>


    <!--------------------- EDIT FILE ----------------------------------------------->
    <input id='saveComment' type='button' value='Save' onclick='saveEdits()'>
    <!------------------------------------------------------------------------------->

    </div>

</body>
</html>

Upvotes: 0

Views: 1659

Answers (1)

GAURAV KUMAR JHA
GAURAV KUMAR JHA

Reputation: 190

There are some bugs in the code:

tr = table.getElementByClassName("output"); // it is getElementsByClassName

secondly, I don't know if this style of declaring a JSON is valid or not but since it didn't worked, I changed it and saved the values first to an array and then converted it to a JSON String.

Another thing is that the way you are trying to store key value pairs in JSON you won't be able to get a selector in a JSON String and hence you won't be able to update the values correctly. So, i have used an associative array where it's keys are the row number in which the edit was performed and the value holds the new content of that column. So, while updating you just have to select the desired column from a row in which the values should be updated.

This is working fine:

// Button to save edit
       var TR;
function saveEdits() {
   var table, tr, editElem, userVersion = [], i, j;
   table    = document.getElementById("mytable");
   tr       = table.getElementsByClassName("output"); //element

   TR = tr;
   console.log(tr);
   for (i=0; i< tr.length; i++){

          // This will set a key value pair where key as row number and value as the inner HTML
          // This key will further help us updating the values from localhost
          userVersion[tr[i].sectionRowIndex] = tr[i].getElementsByTagName("td")[3].innerHTML;
    }  

   console.log(userVersion);
   localStorage.setItem('userEdits', JSON.stringify(userVersion));
}

// place in the body to reload the changes
function checkEdits() {
    try{
      var userEdits = localStorage.getItem('userEdits');
      //console.log(JSON.parse(userEdits));
      if (userEdits) {
          userEdits = JSON.parse(userEdits);
          table    = document.getElementById("mytable");
          tr       = table.getElementsByClassName("output"); //element

          for ( var elementId in userEdits ) {
              tr[elementId].getElementsByTagName("td")[3].innerHTML = userEdits[elementId];
          }
      }
    }catch{
      //console.log("Hello");
    }
 }
<!doctype html>
<html>
<head>
   <title>BOOK LIST</title>
   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css">
   <link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css">
   <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
   <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
   <script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
</head>  

<body onload="checkEdits()">

    <div class="header">
        <h1>BOOK</h1>
    </div>

    <div class="tbody">    
    <table id="mytable" align="center" class="table table-striped table-bordered" cellspacing="0">
        <thead>
            <tr>
                <th width="5%">#</th>
                <th width="20%">BOOK NAME</th>
                <th width="50%">AUTHOR</th>
                <th width="25%">DESCRIPTION</th>
            </tr>
        </thead>
        <tbody>
            <tr class='output'>
                <td>1</td>
                <td>BOOK 1</td>
                <td>John</td>
                <td id='edit' contenteditable='true'>No Description</td>
            </tr>
            <tr class='output'>
                <td>2</td>
                <td>BOOK 2</td>
                <td>Sara</td>
                <td id='edit' contenteditable='true'>No Description</td>
            </tr>
            <tr class='output'>
                <td>3</td>
                <td>BOOK 3</td>
                <td>Mary</td>
                <td id='edit' contenteditable='true'>No Description</td>
            </tr>
            <tr class='output'>
                <td>4</td>
                <td>BOOK 4</td>
                <td>Bob</td>
                <td id='edit' contenteditable='true'>No Description</td>

            <!---- TABLE FILTER AND SORT FUNCTION ---->
            <script>
                $(document).ready(function() {
                    $('#mytable').DataTable( {
                        "pagingType": "full_numbers"
                    });
                });
            </script>

        </tbody>
    </table>


    <!--------------------- EDIT FILE ----------------------------------------------->
    <input id='saveComment' type='button' value='Save' onclick='saveEdits()'>
    <!------------------------------------------------------------------------------->

    </div>

</body>
</html>

Upvotes: 1

Related Questions