如何通过从 json 文件中获取数据来创建 editable table?

how can I create an editable table by taking the data from a json file?

我需要从现有的 json 创建一个 table 并由用户制作后者的 editable。

这是我的 json 文件:

[{"a" : 0, "b" : 7, "c": "/", "d" : 5, "e" : "/", "f" : 5,  "g" : "/"},
{"a" : 0.1, "b" : 15, "c": 30, "d" : 10, "e" : 30, "f" : 10,  "g" : 30},
{"a" : 0.2, "b" : 15, "c": 30, "d" : 10, "e" : 30, "f" : 10,  "g" : 30},
{"a" : 0.3, "b" : 15, "c": 30, "d" : 10, "e" : 30, "f" : 10,  "g" : 30},
{"a" : 0.4, "b" : 15, "c": 30, "d" : 10, "e" : 30, "f" : 10,  "g" : 30},
{"a" : 0.5, "b" : 15, "c": 30, "d" : 10, "e" : 30, "f" : 10,  "g" : 30},
{"a" : 0.6, "b" : 20, "c": 30, "d" : 20, "e" : 30, "f" : 15,  "g" : 30},
{"a" : 0.7, "b" : 20, "c": 30, "d" : 20, "e" : 30, "f" : 15,  "g" : 30}]

最后我需要更新 json 文件并将其发送回控制器。 有什么想法吗?

您可以将 JSON 转换为 editable table。

let data = [{ a : 1, b : 2, c : 3 }, { a : 4, b : 5, c : 6 }, { a : 7, b : 8, c : 9 }];

updateJsonView(data);

document.body.appendChild(jsonToTable(data, { class : 'json-table' }));
document.body.appendChild(createExportButton({
  click : e => {
    updateJsonView(tableToJson(document.querySelector('.json-table')));
  }
}));

function updateJsonView(data) {
  document.querySelector('.json-view').textContent = JSON.stringify(data, null, 2);
}

function tableToJson(table, options={}) {
  let fields = Array.from(table.querySelectorAll('thead tr th')).map(th => th.textContent);
  return Array.from(table.querySelectorAll('tbody tr')).map(tr => {
    return Array.from(tr.querySelectorAll('td')).reduce((record, td, index) => {
      return Object.assign(record, { [fields[index]] : formatValue(td.textContent) });
    }, {});
  });
}

function formatValue(value) {
  if (typeof value === 'string' && isNumeric(value)) {
    return parseInt(value, 10);
  }
  return value;
}

function jsonToTable(json, opts={}) {
  let headers = Object.keys(json[0]);
  let table = document.createElement('table');
  let thead = document.createElement('thead');
  let tbody = document.createElement('tbody');
  let thead_tr = document.createElement('tr');
  if (opts.class) table.classList.add(opts.class);
  headers.forEach(header => {
    let th = document.createElement('th');
    th.textContent = header;
    thead_tr.appendChild(th);
  });
  json.forEach(record => {
    let tr = document.createElement('tr');
    headers.forEach(field => {
      let td = document.createElement('td');
      td.textContent = record[field];
      td.setAttribute('contenteditable', true);
      tr.appendChild(td);
    });
    tbody.append(tr);
  });
  thead.appendChild(thead_tr);
  table.appendChild(thead);
  table.appendChild(tbody);
  return table;
}

function createExportButton(handlers) {
  let btn = document.createElement('button');
  btn.textContent = 'Update JSON';
  btn.classList.add('export-btn');
  btn.addEventListener('click', handlers.click);
  return btn;
}

function isNumeric(num){
  return !isNaN(num)
}
table { border-collapse: collapse; }
table, th, td { border: thin solid grey; }
th, td { padding: 0.25em 0.5em; }

.export-btn { margin-top: 1em; }

.json-view {
  position: absolute;
  min-width: 12em;
  min-height: 4em;
  z-index : 100;
  right: 1em;
  border: thin solid grey;
  font-family: monospace;
  white-space: pre;
  padding: 0.25em;
  font-size: smaller;
}
<div class="json-view"></div>