Align data tbody with theady

Asked

Viewed 81 times

-1

I have data consumed by an API to popular a table in html, they are coming OK, but I’m not able to make the alignment between theady and tbody that populate at runtime, you could help me?

She’s getting like this on the screen: inserir a descrição da imagem aqui

Follows low code:

        <table id="table">
            <thead>
                <tr>
                    <th>Username</th>
                    <th>Name</th>
                    <th>E-mail</th>
                    <th>City</th>
                    <!--<th>Ride in group</th>
                    <th>Day of the week</th>
                    <th>Posts</th>-->
                    <th>Albums</th>
                    <!--<th>Photos</th>-->
                </tr>
            </thead>

            <tbody>
                <!--<tr>
                    <td class="td-username"></td>
                    <td class="td-name"></td>
                    <td class="td-mail"></td>
                    <td class="td-city"></td>
                    <td class="td-ride"></td>
                    <td class="td-day"></td>
                    <td class="td-posts"></td>
                    <td class="td-albuns"></td>
                    <td class="td-photos"></td>
                </tr>-->
            </tbody>
        </table>



<script type="text/javascript">
    var vUsers  = [];
    var vAlbums = [];
    var length;


    $(document).ready(function() {
        $.ajax({ url: 'https://jsonplaceholder.typicode.com/users',
            async: false,
            success: function(data1) {
                vUsers = data1;                                
            },
            error: function(xhr, ajaxOptions, thrownError) {
                alert(thrownError);

                return false; 
            }
        });


        $.ajax({url: 'https://jsonplaceholder.typicode.com/photos',
            async: false,
            success: function(data2) {
                vAlbums = data2;            
            },
            error: function(xhr, ajaxOptions, thrownError) {
                alert(thrownError);

                return false; 
            }
        });



        var table = document.getElementById('table');

        function contaAlbums(lineId) {
            length = 0;

            vAlbums.forEach(function(album) {
                if (album.userId == lineId) {
                    length++;
                }
            });

            return length;
        };


        vUsers.forEach((line) => {
          var lineId   = line.id;

          var tr       = document.createElement('tr');
          var username = document.createElement('td').innerHtml = line.username;
          var name     = document.createElement('td').innerHtml = line.name;
          var email    = document.createElement('td').innerHtml = line.email;
          var city     = document.createElement('td').innerHtml = line.address.city;

          var albumCount = contaAlbums(lineId);

          //alert(albumCount)

          var tdAlbums = document.createElement('td').innerHtml = albumCount;


          //$('.td-username').append(name);

          tr.append(username, name, email, city, tdAlbums);
          table.append(tr);
        });     
    }); 
</script>

2 answers

1


There are two reasons for your problem.

First reason is that for each <td> created you are losing your reference. When does:

var username = document.createElement('td').innerHtml = line.username;

It’s the same as doing:

var username = document.createElement('td').innerHtml;
username = line.username;

That is to say the variable username does not even refer to <td> newborn, username receives the value of the property .innerHtml and then starts referencing the string line.username and this is repeated in username, name , email, city and tdAlbums. Implying that by doing:

tr.append(username, name, email, city, tdAlbums);

To add five <td> you are adding in the first cell a string formed by the strings username, name , email, city and tdAlbums.

The second problem occurs when fixing the first:

var username = document.createElement('td');
username.innerHtml = line.username;

When setting the property username.innerHtml you are exchanging the content of the element for a string and again this repeats to username, name , email, city and tdAlbums and again while doing:

tr.append(username, name, email, city, tdAlbums);

You won’t be adding five <td> to <tr> but will be adding once again in the first cell a string formed by the strings username, name , email, city and tdAlbums.

To fix your code just assign the variables your due references:

var username = document.createElement('td');
var name = document.createElement('td');    
var email = document.createElement('td');    
var city = document.createElement('td');
var tdAlbums = document.createElement('td').

And then use the property innerText instead of innerHtml:

username.innerText = line.username;
name.innerText = line.name;
email.innerText = line.email;    
city.innerText = line.address.city;
tdAlbums.innerHtml = albumCount;

Or in your code:

var vUsers = [];
var vAlbums = [];
var length;


$(document).ready(function() {
  $.ajax({
    url: 'https://jsonplaceholder.typicode.com/users',
    async: false,
    success: function(data1) {
      vUsers = data1;
    },
    error: function(xhr, ajaxOptions, thrownError) {
      alert(thrownError);

      return false;
    }
  });


  $.ajax({
    url: 'https://jsonplaceholder.typicode.com/photos',
    async: false,
    success: function(data2) {
      vAlbums = data2;
    },
    error: function(xhr, ajaxOptions, thrownError) {
      alert(thrownError);

      return false;
    }
  });



  var table = document.getElementById('table');


  function contaAlbums(lineId) {
    length = 0;

    vAlbums.forEach(function(album) {
      if (album.userId == lineId) {
        length++;
      }
    });

    return length;
  };


  vUsers.forEach((line) => {
    var lineId = line.id;
    var albumCount = contaAlbums(lineId);

    var tr = document.createElement('tr');

    var username = document.createElement('td');
    var name = document.createElement('td');
    var email = document.createElement('td');
    var city = document.createElement('td');
    var tdAlbums = document.createElement('td');

    username.innerText = line.username;
    name.innerText = line.name;
    email.innerText = line.email;
    city.innerText = line.address.city;
    tdAlbums.innerText = albumCount;



    tr.append(username, name, email, city, tdAlbums);
    table.append(tr);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table">
  <thead>
    <tr>
      <th>Username</th>
      <th>Name</th>
      <th>E-mail</th>
      <th>City</th>
      <th>Albums</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>

  • Good morning Augusto, all right? Cara worked perfectly the table part, but I still have the same counter problem in function contaAlbums() and I have come up with a new problem now too, if you notice, I put in AJAX async: false because of the global variables I need to treat outside of AJAX, but it’s taking too long, there’s another way to GET these variables out of AJAX without having to use ASYNC?

  • Jquery Ajax has the option async: false in case you need to make synchronous request. Take a look at Axios and easier to use than $Ajax.

  • As for the counter I didn’t even analyze the rest of the code I focused on what was in the question that was about table alignment.

  • Looking at the data, I believe that if you take the username and count how many occurrences appear in the list will be the number of albums.

  • Augustus, I’m sorry I didn’t know about the Axios, but I don’t have time to study, so I have to deliver this by the end of this afternoon. As for the counter was passing the wrong input in the IF inside the function. Now I need to solve this problem even AJAX ASYNC

  • I understood, no and better open another specific question about the counter because the scope of this question here is table formatting and the format of the site does not allow this change of scope in a question after answered.

  • Yes it is true Augusto, I will open, thank you very much for the help.

Show 2 more comments

0

Just like you used the .append() to place elements in the tr, you can use it to put the text in the elements td that the result will be correct. For example:

var name = document.createElement('td');
name.append(line.name);

And the result:

Tabela preenchida corretamente

Browser other questions tagged

You are not signed in. Login or sign up in order to post.