简体   繁体   中英

How can I extract multiple KEY:VALUE pairs from JSON in a relevant way

I am in the process of creating a Publicly-Editable Log for Daily Events where a User can Modify certain inputs throughout the Columns of a Table (such as Date, Time, a Checkbox, and User Notes; but where the first column "Day" is hard-coded, ie "Day 1", "Day 2", etc.), which can then be saved via Local Storage. Here is a sample of my present table style:

      <div id="table" class="table-editable table-responsive table-bordered">
<span class="table-add glyphicon glyphicon-plus"></span>
<table class="table">
  <tr class="warning">
    <th>Day</th>
    <th>Date</th>
    <th>Time</th>
    <th>Yes/No</th>
    <th>Notes</th>
  </tr>

  <tr class="active">
    <td contenteditable="true">Day 1</td>
    <td contenteditable="true"><input id="date1" value="" type="date" name="date" onblur="dateConstruct(1)"></td>
    <td contenteditable="true"><input id="time1" value="" type="time" name="usr_time" onblur="timeConstruct(1)"></td>
    <td contenteditable="true">Y <input class="radioBut" type="checkbox" name="1" value="Yes"> / N <input class="radioBut" type="checkbox" name="2" value="No"></td>
    <td contenteditable="true"><input id="note1" value="" type="text" name="notes" onblur="noteConstruct(1)"></td>
    <td>
      <span class="table-remove glyphicon glyphicon-remove"></span>
    </td>
  </tr>

  <tr class="active">
    <td contenteditable="true">Day 2</td>
<td contenteditable="true"><input id="date2" value="" type="date" name="date" onblur="dateConstruct(2)"></td>
    <td contenteditable="true"><input id="time2" value="" type="time" name="usr_time" onblur="timeConstruct(2)"></td>
    <td contenteditable="true">Y <input class="radioBut" type="checkbox" name="1" value="Yes"> / N <input class="radioBut" type="checkbox" name="2" value="No"></td>
    <td contenteditable="true"><input id="note2" value="" type="text" name="notes" onblur="noteConstruct(2)"></td>
    <td>
      <span class="table-remove glyphicon glyphicon-remove"></span>
    </td>
  </tr>
 </table>
 </div>

This is the code I use to save the Data, which works fine:

   var $TABLE = $('#table');
   var $SAVEIT = $('#save-btn');

    $SAVEIT.click(function () {

      var $rows = $TABLE.find('tr:not(:hidden)');
      var headers = [];
      var data = [];
      var VALue = [];
      var keeey = "uSTORE-A";

      var SETData = function(keeey, VALue) {   
       if (!keeey || !VALue) {return;}
       localStorage.setItem(keeey, VALue);
       alert("DATA SAVED! \nYou may now close your browser.");
      };

     // Get the headers (add special header logic here)
     $($rows.shift()).find('th:not(:empty)').each(function () {
      headers.push($(this).text().toLowerCase());
     });

     // Turn all existing rows into a loopable array
     $rows.each(function () {
      var $td = $(this).find('td');
      var h = {};

      // Use the headers from earlier to name our hash keys
      headers.forEach(function (header, i) {
      h[header] = $td.eq(i).text();   
     });

     data.push(h);
    });

   var uSAVE = JSON.stringify(data);

   SETData("uSTORE-B", uSAVE);

   });

Afterwards, such as on the next day for more Logging, the person can load the previously saved data from the JSON which is saved on their Browser in Local Storage via the above code. The saved JSON would look like this (which I, for pen-testing purposes, had displayed to myself via an ' alert() '):

    [{"day":"Day 1","date":"2017-02-24","time":"12:01","yes/no":"Y","notes":"Some notes"},{"day":"Day 2","date":"2017-02-25","time":"06:06","yes/no":"Y","notes":"Another day's notes"},{"day":"Day 3","date":"2017-02-26","time":"","yes/no":"N","notes":""},{"day":"Day 4","date":"2017-02-27","time":"22:00","yes/no":"Y","notes":"Notes for day after no notes"}]

Thus, I am able to Save the Data (as JSON) properly, as well as Load the Data (as JSON). However, I have been unable to figure out how to repopulate the Table with the User's previously saved Data. In other words, I can't figure out how to input the Values of the JSON Key:Value pairs back into the Table so that the User can pick up where they left off. I have tried several methods, but keep ending up with the first Key:Value Pair populating ALL of the values for a column rather than cycling through the separate values. Should I be saving the JSON in a different manner than I have been doing?

Thank you in advance for any help you may be able to offer, or for any fingers that point me in the right direction.

You should be able to loop through the array with a for loop with an iterator, then loop through the object properties with a for...in. Of course, it's hard to tell if I'm heading in the right direction without your actual table structure. Here's an example...

I've edited to include your table structure. It looks like you just need to push the json data into you inputs...

 var json = [{"day":"Day 1","date":"2017-02-24","time":"12:01","yes/no":"Y","notes":"Some notes"},{"day":"Day 2","date":"2017-02-25","time":"06:06","yes/no":"Y","notes":"Another day's notes"},{"day":"Day 3","date":"2017-02-26","time":"","yes/no":"N","notes":""},{"day":"Day 4","date":"2017-02-27","time":"22:00","yes/no":"Y","notes":"Notes for day after no notes"}]; $(document).ready(function() { var $table = $('table'); // set table data genData($table); }); function genData($table) { // loop through array of rows for(var i = 0; i < json.length; i++) { // create a new row var $row = createRow(); // loop through cells for(var cellName in json[i]) { // create a new cell var $cell = $('<td></td>'); var $div; var n = i + 1; // fill appropriate input switch(cellName) { case "date": $div = createDate(json[i][cellName], n); break; case "time": $div = createTime(json[i][cellName], n); break; case "yes/no": $div = createCheckboxes(json[i][cellName]); break; case "notes": $div = createText(json[i][cellName], n); break; default: $div = createStatic(json[i][cellName]); break; } // append the input to the cell $cell.append($div); // append the cell to the row $row.append($cell); } // append the row to the table $table.append($row); } } // create date input function createDate(val, n) { var $input = $('<input type="date" name="date" onblur="dateConstruct(' + n + ')">').attr('id', "date" + n).val(val); return $('<div></div>') .append($input); } // create time input function createTime(val, n) { var $input = $('<input type="time" name="usr_time" onblur="timeConstruct(' + n + ')">') .attr('id', "time" + n) .val(val); return $('<div></div>') .append($input); } // create checkbox inputs function createCheckboxes(val) { var yesInput = $('<input class="radioBut" type="checkbox" name="1" value="Yes">'); var noInput = $('<input class="radioBut" type="checkbox" name="2" value="No">'); if(val == "Y") { yesInput.attr('checked', 'checked'); } else { noInput.attr('checked', 'checked'); } return $('<div></div>') .append($('<span>Y </span>')) .append(yesInput) .append($('<span> / N</span>')) .append(noInput); } // create text input function createText(val, n) { var $input = $('<input type="text" name="notes" onblur="noteConstruct(' + n + ')">') .attr('id', "notes" + n) .val(val); return $('<div></div>') .append($input); } // create static text function createStatic(val) { var $div = $('<div></div>'); $div.text(val); return $div; } function createRow() { return $('<tr class="active"></tr>'); } function createCell(content) { return $('<td contenteditable="true"></td>').text(content); } // dummy functions to remove errors function dateConstruct(n) { } function timeConstruct(n) { } function noteConstruct(n) { } 
 table, th, tr, td { border: 1px solid #000000; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="table" class="table-editable table-responsive table-bordered"> <span class="table-add glyphicon glyphicon-plus"></span> <table class="table"> <tr class="warning"> <th>Day</th> <th>Date</th> <th>Time</th> <th>Yes/No</th> <th>Notes</th> </tr> </table> </div> 

// Parse JSON string into object.
let data = JSON.parse(/* your data variable */);
let table = /* select your table element's tbody */;
updateTable(data, table);


const updateTable = (data, table) => {
  // Iterate over data array to output new rows.
  let rows = data.map((entry) => {
    // Create your element.
    let thisRow = document.createElement('tr');

    // Repeat this next segment for each 'td' element you need
    // you could loop it with a 'for in', but you can't count on loop order 
    // if you do it that way and would need to separate create and append
    // actions
    thisRow.appendChild(createTableCell('day', entry.day));
    thisRow.appendChild(createTableCell('date', entry.date));
    // etc...

    return thisRow;
  });

  // Append new rows
  for (let i = 0; i < rows.length; i++) {
    table.appendChild(rows[i]);
  }
}; 

const createTableCell = (key, value) => {
  // Create td element
  let cell = document.createElement('td');
  // Create textnode
  let content = document.createTextNode(value);
  // Add node to element.
  cell.appendChild(content);

  // Other common way to add options.
  cell.className = key + ' my-awesome-cell-class';

  return cell; 
};

document.createElement()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM