Как добавить данные JSON в таблицу HTML - PullRequest
0 голосов
/ 23 марта 2019

В настоящее время я получаю данные, которые мне нужно добавить в таблицу HTML, как только я ее получу.

Я пробовал несколько вещей, но я не могу динамически добавлять данные, как толькозагрузка страницы.

Я хочу добавить ее, используя Javascript или jQuery

Вот структура HTML:

<div>
    <table cellspacing="0" cellpadding="0">
        <thead>
          <tr>
            <th scope="col"><span>Email</span></th>
            <th><span>Last Name</span></th>
            <th><span>First Name</span></th>
            <th><span>Role</span></th>
            <th><span>Cell Phone User</span></th>
          </tr>
        </thead>
           <tbody>
              <tr>
                 <td scope="row" data-label="Email"></td>
                 <td data-label="Last Name"></td>
                 <td data-label="First Name"></td>
                 <td data-label="Role"></td>
                 <td data-label="Cell Phone User"></td>
               </tr>
           </tbody> 
    </table>
</div>

Вот пример того, как данные выглядят после того, как ихизвлечено:

[{
    "id": 1,
    "email": "janedoe@example.com",
    "familyName": "Doe",
    "givenName": "Jane",
    "role": "admin",
    "smsUser": true
  },
  {
    "id": 2,
    "email": "johndoe@example.com",
    "familyName": "Doe",
    "givenName": "John",
    "role": "standard",
    "smsUser": false
  }]

Вот что я пробовал до сих пор:

Это мой прослушиватель событий для загрузки данных после загрузки страницы:


window.path = "http://localhost:3000/users";

// getUsers function plus any additional functions go here ...
const getUsers = options => {
  let url = new URL(window.path);
  if (options) {
    url.search = new URLSearchParams(options)
  }
  return Promise.resolve(fetch(url))
}

document.addEventListener('DOMContentLoaded', () => {

 /* SELECT DOM ELEMENTS*/ 
let table = document.querySelector('tbody');

let promise = getUsers({page=2, role:'admin'})

.then(data => {

var html = '<table>';
for( var j in data[0] ) {
    html += '<th>' + j + '</th>';
 }
     html += '</tr>';

     for( var i = 0; i < data.length; i++) {
      html += '<tr>';
      for( var j in data[i] ) {
        html += '<td>' + data[i][j] + '</td>';
      }
     }
     html += '</table>';
     table.appendChild(html)

    return table;
  })
.catch(err => {
    console.log('Error fetching from /users', err);
    return null
  })

})



Любая помощь приветствуется.

Ответы [ 2 ]

1 голос
/ 23 марта 2019

Первая проблема заключается в том, что линия

let promise = getUsers({page=2, role:'admin'})

должно быть

let promise = getUsers({page:2, role:'admin'})

Во-вторых, appendChild не принимает строку, а принимает элемент DOM. Для этого случая используйте вместо этого innerHTML.

В-третьих, вы используете querySelect для поиска элемента '<tbody>', поэтому начните конструирование внутренних тегов html с '<tr>', а не '<table>'

const getUsers = async options => ([
  {
    id: 1,
    email: "janedoe@example.com",
    familyName: "Doe",
    givenName: "Jane",
    role: "admin",
    smsUser: true
  },
  {
    id: 2,
    email: "johndoe@example.com",
    familyName: "Doe",
    givenName: "John",
    role: "standard",
    smsUser: false
  }
]);
  
document.addEventListener('DOMContentLoaded', async () => {
  const table = document.querySelector('tbody');
  const users = await getUsers({ page:2, role:'admin' });
  const userToTableRow = user => [
  { attrs: 'scope="row" data-label="Email"', propName: 'email'},
  { attrs: 'data-label="Last Name"', propName: 'familyName'},
  { attrs: 'data-label="First Name"', propName: 'givenName'},
  { attrs: 'data-label="Role Name"', propName: 'role'},
  { attrs: 'data-label="Cell Phone User"', propName: 'smsUser'},
  ].map(mapper => (
    `<td ${mapper.attrs}>${user[mapper.propName]}</td>`
  )).join('');
  
  const html = users.map(user =>
    `<tr>${userToTableRow(user)}</tr>`
  ).join('');
  table.innerHTML = html;
});
<div>
  <table cellspacing="0" cellpadding="0">
    <thead>
      <tr>
        <th scope="col"><span>Email</span></th>
        <th><span>Last Name</span></th>
        <th><span>First Name</span></th>
        <th><span>Role</span></th>
        <th><span>Cell Phone User</span></th>
      </tr>
    </thead>
    <tbody>
    </tbody> 
  </table>
</div>

EDIT: Мне нравится async / await в первой реализации выше. async - это простой способ заставить функцию обернуть возвращаемое в Promise. await - это просто новый языковой способ разрешения встроенного обещания без использования .then((res) => {...}). await может использоваться только в функции async.

Решение вопросов в комментариях. Я представляю это альтернативное решение, которое:

  • Не использует async и await
  • издевается fetch вместо getusers
  • Использует document.createElement () и appendChild вместо простой установки innerHTML содержимого.

const getUsersUrl = 'http://localhost:3000/users';

function mockFetch(url) {
  const stubbedResponse = JSON.stringify([
    {
      id: 1,
      email: "janedoe@example.com",
      familyName: "Doe",
      givenName: "Jane",
      role: "admin",
      smsUser: true
    },
    {
      id: 2,
      email: "johndoe@example.com",
      familyName: "Doe",
      givenName: "John",
      role: "standard",
      smsUser: false
    }
  ]);

  return Promise.resolve({
    json() {
      return Promise.resolve(JSON.parse(stubbedResponse));
    }
  });
}

const getUsers = options => {
  let url = new URL(getUsersUrl);
  if (options) {
    url.search = new URLSearchParams(options)
  }
  return mockFetch(url);
}

const userToTableRow = user => {
  const tr = document.createElement('tr');
  [
    {
      attrs: {
        scope: 'row',
        'data-label': 'Email'
      },
      propName: 'email'
    },
    {
      attrs: { 'data-label': 'Last Name' },
      propName: 'familyName'
    },
    {
      attrs: { 'data-label': 'First Name' },
      propName: 'givenName'
    },
    {
      attrs: { 'data-label': 'Role Name' },
      propName: 'role'
    },
    {
      attrs: { 'data-label': 'Cell Phone User' },
      propName: 'smsUser'
    },
  ].map(mapper => {
    const td = document.createElement('td');
    for (const [attrName, attrValue] of Object.entries(mapper.attrs)) {
      td.setAttribute(attrName, attrValue);
    }
    td.appendChild(document.createTextNode(user[mapper.propName]));
    return td;
  }).forEach(td => { tr.appendChild(td); });
  return tr;
}
  
document.addEventListener('DOMContentLoaded', () => {
  const table = document.querySelector('tbody');
  getUsers({ page:2, role:'admin' })
    .then(response => response.json())
    .then(users => {
      users
        .map(user => userToTableRow(user))
        .forEach(tr => { table.appendChild(tr); });
  });
});
<div>
  <table cellspacing="0" cellpadding="0">
    <thead>
      <tr>
        <th scope="col"><span>Email</span></th>
        <th><span>Last Name</span></th>
        <th><span>First Name</span></th>
        <th><span>Role</span></th>
        <th><span>Cell Phone User</span></th>
      </tr>
    </thead>
    <tbody>
    </tbody> 
  </table>
</div>
0 голосов
/ 23 марта 2019

Используя jQuery, это очень просто сделать.

Возьмем этот фрагмент в качестве примера, который использует библиотеку jQuery DataTables .

$(document).ready(function() {
    $('#example').DataTable( {
        ajax: {
          url: "https://reqres.in/api/users",
          dataSrc: "data"
        },
        columns: [
            { "data": "id" },
            { "data": "first_name" },
            { "data": "last_name" }
        ]
    } );
} );
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet" />
<table id="example" class="display" style="width:100%">
    <thead>
        <tr>
            <th>Id</th>
            <th>First Name </th>
            <th>Last Name</th>
        </tr>
    </thead>
</table>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

Он также предоставляет различные конфигурации и интеграции, которые, я уверен, вы найдете полезными.

...