How to take the value of each TD inside each TR dynamically using jQuery?

Asked

Viewed 538 times

1

I have the following sample HTML:

<tr>
    <td>Futebol</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Volei</td>
    <td>Quadra</td>
</tr>
<tr>
    <td>Tenis</td>
    <td>Saibro</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Natação</td>
    <td>Piscina</td>
</tr>
<tr>
    <td>Ciclismo</td>
    <td>Rua</td>
</tr>

I would need to go through the tr taking the value of each td and have a json sort of like this:

"esportes":[
{
    "esporte":"Futebol",
    "ambiente":"Campo"
},
{
    "esporte":"Volei",
    "ambiente":"Quadra"
},
{
    "esporte":"Tenis",
    "ambiente":"Saibro",
    "ambiente":"Campo"
},
{
    "esporte":"Ciclimo",
    "ambiente":"Rua"
}]

How could I do that to jQuery? I did just that for now but do not know how to continue from here (if I am in the way). Turning to JSON is not quite the problem, the biggest problem would be to take the values in the right way, each sport with its use environment:

$("#tableEsportes > tbody > tr").each(function(){ 
    console.log($(this).text());
});
  • Useful link: https:/jsonlint.com allows you to validate your json with a brief explanation about Json

3 answers

8


First of all, JSON cannot have repeated keys:

"ambiente":"Saibro",
"ambiente":"Campo"

I suggest this structure:

[
    {
        "esporte":"Futebol",
        "ambiente": ["Campo"]
    },
    {
        "esporte":"Volei",
        "ambiente": ["Quadra"]
    },
    {
        "esporte":"Tenis",
        "ambiente": ["Saibro", "Campo" ]
    },
    {
        "esporte":"Ciclismo",
        "ambiente": ["Rua"]
    }
]

Then you can use the seletore :first-child to catch only the first <td> son of <tr> and the selector :not(:first-child) to pick up the other elements that will be the local:

$(function () {
    var esportesJson = { "esportes": [] };

    $("#tableEsportes tr").each(function () {
        var esporte = $("td:first-child", this);
        var ambientes = [];
        
        $("td:not(:first-child)", this).each(function () {
            ambientes.push($(this).text());
        });
        
        esportesJson.esportes.push({
            "esporte": esporte.text(),
            "ambiente": ambientes
        });
    });

    console.log(esportesJson);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table id="tableEsportes">
<tr>
    <td>Futebol</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Volei</td>
    <td>Quadra</td>
</tr>
<tr>
    <td>Tenis</td>
    <td>Saibro</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Natação</td>
    <td>Piscina</td>
</tr>
<tr>
    <td>Ciclismo</td>
    <td>Rua</td>
</tr>
</table>

  • 2

    Very good! It will be useful for a project of mine in the future. + 1 :)

  • 1

    Very good, that’s exactly what I needed to work. Thank you!

2

To william’s response da is very good, but another way to be doing using pure Javascript:

var arrayTr = document.body.querySelectorAll('#tableEsportes > tbody > tr');
var array = [];

for (let i = 0, j = arrayTr.length; i < j; i++) {
    let obj = {};
    let ambientes = [];
    let tr = [];

    tr = arrayTr[i];
    obj.esporte = tr.children[0].textContent;

    for (let x = 1, y = tr.children.length; x < y; x++) {
        ambientes.push(tr.children[x].textContent);
    }

    obj.ambiente = ambientes;
    array.push(obj);
}

console.log(JSON.stringify(array));
<table id="tableEsportes"> 
<tr>
    <td>Futebol</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Volei</td>
    <td>Quadra</td>
</tr>
<tr>
    <td>Tenis</td>
    <td>Saibro</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Natação</td>
    <td>Piscina</td>
</tr>
<tr>
    <td>Ciclismo</td>
    <td>Rua</td>
</tr>
</table>

Explaining

  • Return all lines with document.querySelectorAll
  • Deducing that the first column will always be the sport, the next ones should be the environment so use another to traverse the rest of the columns.
  • Use JSON.stringify to transform your array in a string in format JSON.
  • Change innerHTML for textContent please :)

  • @Guilhermenascimento what the difference?

  • Marconi innerHTML would take any HTML content injected there, whereas textContent takes only the text, ignoring HTML tags (textContent is equivalent to innerText). https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML vs https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent

  • @Guilhermenascimento bacana, thanks for the tip :), code changed!

  • 1

    There’s the +1 deserved :D

  • 1

    Very good @Marconi. + 1 :)

  • @Guilhermenascimento was worth it :)

  • 1

    @Jorgematheus was worth :)

  • 1

    @Marconi made some adjustments to the code, if you wish you can revert, but they are only for micro-optimizations

  • @Guilhermenascimento and my thanks, I have already left the +1 in your reply!

Show 5 more comments

0

You can do this: create an array and add the elements to it and then serialize:

var obj = {
esportes: []
};
$("#tableEsportes > tbody > tr").each(function() {
var linha = {
    esporte: $(this).find('td').eq(0).text(),
    ambiente: $(this).find('td').eq(1).text()
}
obj.esportes.push(linha);
});

console.log(JSON.stringify(obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableEsportes">

<tr>
    <td>Futebol</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Volei</td>
    <td>Quadra</td>
</tr>
<tr>
    <td>Tenis</td>
    <td>Saibro</td>
    <td>Campo</td>
</tr>
<tr>
    <td>Natação</td>
    <td>Piscina</td>
</tr>
<tr>
    <td>Ciclismo</td>
    <td>Rua</td>
</tr>
</table>

Browser other questions tagged

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