Reputation: 115
I am trying to get array of json object from html table using jquery. This table and data will be determined during runtime and hold different data. So I would like to get property for json object from thead td and values from tbody td.
<table id="myTable">
<thead>
<tr>
<td>Name</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr>
<td>Mary Jane</td>
<td>Female</td>
</tr>
<tr>
<td>Peter Parker</td>
<td>Male</td>
</tr>
</tbody>
</table>
I am able to create array of json object but I have to write property hard coded.
var jsonList = [{"Name":"Mary Jane", "Gender":"Female"},{"Name":"Peter Parker", "Gender":"Male"}]
My code:
var data = [];
var target = $('#myTable tr').not('thead tr');
target.each(function (i) {
console.log($(this).find('td:eq(0)').html());
data.push({
"Name": $(this).find('td:eq(0)').html(),
"Gender": $(this).find('td:eq(1)').html()
});
});
var json =JSON.stringify(data);
How do i do this using jquery ?
Upvotes: 0
Views: 164
Reputation: 468
There are a few things you can do to make this a bit easier if you are able to edit the HTML:
First I would change the td in the thead to th. This will help out the JavaScript, and is also better semantically.
var data = [];
var $myTable = $('#myTable'); //keeping the table in memory is a bit more effcient
var labels = $myTable.find('thead th').toArray().map(function(th) { //toArray converts the jQuery object to a standard JavaScript array so that we can use the native .map method.
return th.innerHTML.trim(); //innerHTML is like jQuery .text(), .trim() removes any whitespace on the left or right.
}); //["Name","Gender"]
var $rows = $myTable.find('tbody tr');
$rows.each(function() {
var $row = $(this);
var row_data = {};
for (let i = 0; i < labels.length; i++) { //native JS for loop
row_data[labels[i]] = $row.find('td:eq(' + i + ')').text().trim();
}
data.push(row_data);
});
console.log(data);
var json_data = JSON.stringify(data); //array of objects in string format
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr>
<th>Name</th>
<th>Gender</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mary Jane</td>
<td>Female</td>
</tr>
<tr>
<td>Peter Parker</td>
<td>Male</td>
</tr>
</tbody>
</table>
So what's going on with the JavaScript? First I'm keeping the table in memory as $myTable and finding the elements we need inside of it from there. To find the labels, I've used jQuery .toArray() to convery the jQuery object to a vanilla JavaScript array so that we can use .map(). Map is a very useful method as whatever you return to from the callback gets pushed onto the new array that I've called labels.
Next we gets all the rows from $myTable and loop over them like you were doing. Instead of hard coding the object keys, I'm looping over the labels array we made earlier. I'm also using the temporary variable i to find the td that you wanted. Finally push the constructed object to the end of the array.
Please note!! That is there is any broken HTML on the page, or a row has some missing data, you will have issues with your data as well. If you are able to edit HTML, but need the data from in JavaScript, I suggest using an application/json tag like so:
var $myData = $('#myData');
var json_data = $myData.text(); //if you just need string data, stop here!
console.log(json_data);
var data = JSON.parse(json_data);
console.log(data);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script id="myData" type="application/json">
[{
"Name": "Mary Jane",
"Gender": "Female"
}, {
"Name": "Peter Parker",
"Gender": "Male"
}]
</script>
I hope this helps :)
Upvotes: 0
Reputation: 6904
there you go
var a = $(`<table id="myTable">
<thead>
<tr>
<td>Name</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr>
<td>Mary Jane</td>
<td>Female</td>
</tr>
<tr>
<td>Peter Parker</td>
<td>Male</td>
</tr>
</tbody>
</table>`);
var keys = a
.find("thead tr td")
.toArray()
.map(x => x.textContent);
var result = a
.find("tbody tr")
.map((i, tr) => {
var obj = {};
$(tr)
.find("td")
.each((i, td) => (obj[keys[i]] = td.innerText));
return obj;
})
.toArray();
console.log(result);
Upvotes: 0
Reputation: 2323
var headers = $('#myTable thead tr:eq(0)').find('td, th').map(function () {
return $(this).text();
}).get();
var data = $('#myTable tbody tr').map(function () {
return Array.from($(this).find('td')).reduce(function (accumulator, current, index) {
accumulator[headers[index]] = $(current).text();
return accumulator;
}, {});
}).get();
var json = JSON.stringify(data);
console.log(json);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr>
<td>Name</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr>
<td>Mary Jane</td>
<td>Female</td>
</tr>
<tr>
<td>Peter Parker</td>
<td>Male</td>
</tr>
</tbody>
</table>
Upvotes: 1
Reputation: 122047
You could first get cells from thead
in an array and then loop each row in tbody
and use cell index to get the property name from the thead with the same index.
let th = $("#myTable thead tr td").map(function() {
return $(this).text()
}).get();
let data = $("#myTable tbody tr").map(function() {
return Array.from($(this).find("td")).reduce(function(r, td, i) {
r[th[i]] = td.textContent;
return r;
}, {})
}).get()
console.log(data)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr>
<td>Name</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr>
<td>Mary Jane</td>
<td>Female</td>
</tr>
<tr>
<td>Peter Parker</td>
<td>Male</td>
</tr>
</tbody>
</table>
Upvotes: 2