I am using handlebars to compile and get the html from the JS object. Is it possible to transform (html) back to JS object (using handlebars or anyother library)? To be more precise; Using handlebars, I have the following template:
<tr>
<td>{{qty}}</td>
<td>{{rate}}</td>
<td>{{gstPerc}}</td>
<td>{{discountPerc}}</td>
<td>{{amount}}</td>
</tr>
and following JS Object:
{
qty : 12,
rate : 1000,
gstPerc : 10,
discountPerc : 2,
amount: 1500
}
after compilation using handlebars, it gets transform to simple html i.e following, for example.
<tr>
<td>12</td>
<td>1000</td>
<td>10</td>
<td>2</td>
<td>1500</td>
</tr>
Now what I was wondering is, Is it possible (using handlebars), to transform the given HTML back to the object?
give give data-name as qty ,rate etc
var obj = getElementsByTagName('td');
$data = {};
for(var i=0;i<obj.length;i++)
{
$data[obj[i].dataset.name] = obj[i].innerHtml;
}
you can do reverse process you want to populate table with object data
You can use grid control like jqgrid for easy integration
For arbitrary templates and values, this is not possible. Consider the following template:
<td>{{cell1}}</td><td>{{cell2}}</td>
and the following result:
<td></td><td></td><td></td>
Which of cell1, cell2 is empty, and which contains </td><td>?
If you know the HTML inserted is valid and you know the template in advance, this is easy. For your specific template:
var table = document.createElement("table")
table.innerHTML = input
var tds = table.rows[0].cells
return {qty: tds[0].innerHTML, rate: tds[1].innerHTML ...}
If you know the values inserted should be numbers, you can convert them as such:
return {qty: +tds[0].innerHTML, rate: +tds[1].innerHTML ...}
Maybe you could use jQuery and end up with something like this
In your template: add classes to the <td> elements:
<table>
<tr id='someId'>
<td class='qty'>12</td>
<td class='rate'>1000</td>
<td class='gstPerc'>10</td>
<td class='discountPerc'>2</td>
<td class='amount'>1500</td>
</tr>
</table>
Create your object again:
var myObj = {};
$("#someId td").each(function() {
var td = $(this);
myObj[td.attr("class")] = td.text();
});
alert(JSON.stringify(myObj));
Related
I am getting a little stuck with this one. I am trying to use javascript on my website to convert my API JSON data to a table. Without using an array in an array of data in JSON, it works fine which each item on a new line but soon as I use an nested array of data in there, it has all the data on one line, seperated by a comma. Thinking a for loop would work here but i'm not 100% sure if this is the best method.
I have tried multiple searches online and tested around myself but I can't seem to get it to work.
The following is simple version of the JSON data I am working with:
MACLIST = ["ABC","DEF"]
IPLIST = ["10.10.10.10","20.20.20.20"]
ZONELIST = ["Inside","Outside"]
var json = [{"MAC":MACLIST,"IP":IPLIST,"ZONE":ZONELIST},{"SOMETHING ELSE":"OK"}];
Script used:
$(document).ready(function () {
ko.applyBindings({
teams: json
});
});
HTML used:
<table>
<thead>
<tr>
<th>Device</th>
<th>IP</th>
<th>Zone</th>
</tr>
</thead>
<tbody data-bind="foreach: teams">
<tr>
<td data-bind="text: MAC"></td>
<td data-bind="text: IP"></td>
<td data-bind="text: ZONE"></td>
</tr>
</tbody>
</table>
Working JSON version (without nested array data) works:
var json = [{"MAC":"ABC","IP":"10.10.10.10","ZONE":"Inside"},{"MAC":"DEF","IP":"20.20.20.20","ZONE":"Outside}];
Any tips or advice would be greatly appreciated
Testing URL JSFiddle Link
You can map over each row to create a string of html for each row. Then inside each row, map over each column to create the string of html for each cell.
var json = [{
"MAC": "ABC",
"IP": "10.10.10.10",
"ZONE": "Inside"
}, {
"MAC": "DEF",
"IP": "20.20.20.20",
"ZONE": "Outside"
}];
const makeCell = (content) => {
return `<td>${content}</td>`
}
const makeRow = (content) => {
return `<tr>${content}</tr>`
}
const table = document.querySelector('.table')
const colHeaders = Object.keys(json[0]).map(key => makeCell(key)).join('')
const bodyRows = json.map(row => {
return makeRow(Object.keys(row).map(col => makeCell(row[col])).join(''))
}).join('')
document.querySelector('thead tr').innerHTML = colHeaders
document.querySelector('tbody').innerHTML = bodyRows
<table>
<thead>
<tr></tr>
</thead>
<tbody>
</tbody>
</table>
Hopefully this article will help you resolve the problem
https://www.geeksforgeeks.org/how-to-convert-json-data-to-a-html-table-using-javascript-jquery/
I have a HTML dinamically created table that should be filled by the user.
The user can creates a new SECTION (as many as he want) and he can creates LABELS and its TRANSLATIONS. As many as he wants.
Following is part of the html code:
<table>
<tr class = "section">
<td class = "sectionName">section1</td>;
<td><input type="submit" value="Update"></td>
</tr>
<tr class="lbl_trans_Wrap">
<td class="lbl">lbl_11</td>
<td class="trans"><input type="text" value="trans_11"></td>
</tr>
<tr class = "section">
<td class = "sectionName">section2</td>;
<td><input type="submit" value="Update"></td>
</tr>
<tr class="lbl_trans_Wrap">
<td class="lbl">lbl_21</td>
<td class="trans"><input type="text" value="trans_21"></td>
</tr>
<tr class="lbl_trans_Wrap">
<td class="lbl">lbl_22</td>
<td class="trans"><input type="text" value="trans_22"></td>
</tr>
...
</table>
Than I would like to create a JSON from the values filled by the user.
The object should be like this one:
var lang =
{
section1:
{
lbl_11:"trans_11"
},
section2:
{
lbl_21:"trans_21",
lbl_22:"trans_22"
}
};
To generate the above JSON I am using the following javascript:
var lang ={};
var lbl="";
var trans="";
var section="";
$( "tr" ).each(function() {//Pass trough each line in the table
if($(this).hasClass( "section" )){
section = $(this).children("td.sectionName").html();//Grab all sections
//console.log(section);
}
if($(this).hasClass( "lbl_trans_Wrap" )){
lbl = $(this).children("td.lbl").html();//Grab all labels
//console.log(lbl);
trans = $(this).children("td.trans").children("input.txt_translate").val();//Grab all translation
//console.log(trans);
lang[section]={lbl:trans};
}
});
//console.log(lang);
But the JSON is not being created as expected.
There are 2 issues here:
The lang[section]={lbl:trans} is overriding the last one. So at the end of the process we have only the last one element.
The lbl variable is not being recognized as variable but as a string.
Looks like this:
var lang =
{
section1:
{
lbl:"trans_11"
},
section2:
{
lbl:"trans_21"
}
};
I've tried suggestions from this post and this one.
But they do not use dynamically created property.
I've tried to use push but it not works to objects.
I could create a JSON string and then to parse it.
But I would like to know how to solve this issue in another way.
Any idea in how to generate this JSON dynamically ?
UPDATE:
After James's post, this is the code that works:
$( "tr" ).each(function() {//Pass trough each line in the table
if($(this).hasClass( "section" )){
section = $(this).children("td.sectionName").children("h1").html();//Grab all sections
//console.log(section);
}
if($(this).hasClass( "lbl_trans_Wrap" )){
lbl = $(this).children("td.lbl").html();//Grab all labels
//console.log(lbl);
trans = $(this).children("td.trans").children("input.txt_translate").val();//Grab all translation
//console.log(trans);
if (!lang[section]) {
lang[section] = {};
}
lang[section][lbl] = trans;
}
});
//console.log(lang);
So there are two bugs, one you are overwriting the value of lang[section] with a new object each time. Two, that new object contains a key with the string value "lbl", not the value contained in the lbl variable.
To fix, replace:
lang[section]={lbl:trans};
With:
if (!lang[section]) {
lang[section] = {};
}
lang[section][lbl] = trans;
Hello experts,
Could you please recommend:
I have two tables:
<tr id='firs_table'>
<td id="team">team1</td><td>45</td>
<td id="team">team2</td><td>47</td>
</tr>
<tr id='second_table'>
<td id="team">team1</td><td id="service">service name1</td><td id="count">count1</td>
<td id="team">team1</td><td id="service">service name2</td><td id="count">count2</td>
<td id="team">team1</td><td id="service">service name3</td><td id="count">count3</td>
<td id="team">team2</td><td id="service">service name1</td><td id="count">count1</td>
<td id="team">team2</td><td id="service">service name2</td><td id="count">count2</td>
</tr>
I need to create dictionary like:
team1: ['service name1','service name2','service name3'], [count1,count2, count3]
team2: ['service name1','service name2'], [count1,count2]
could you please advise algorithm with jquery ?
I need that result in order create RGraph graph.
Thank you in advance.
I could not provide any working example of jquery code, I could not find a way how to iterate over $("tr#first_table td"#team") value and compare it with $("tr#second_table td"#team"), if values are the same => return array of [[$("tr#second_table td"#service")], [$("tr#second_table td"#count")] ].
I mean, I could not find idea.
This should do what you need
var res = {}
$('table tr').each(function () {
var cellText = $(this).find('td').map(function (i, el) {
return $(el).text();
}).get();
if (!res[cellText[0]]) {
res[cellText[0]] = [[],[]];
}
res[cellText[0]][0].push(cellText[1]);
res[cellText[0]][1].push(cellText[2]);
});
If you have a heading row can use $('table tr:gt(0)')
DEMO
The documentation is not quite clear on this, or I may not be understanding how to implement this in the HTML, but how do you handle a template in tempojs that has an empty list/array of items coming from JSON output? Is there a template directive that can be used to display something when the data list is empty (i.e. like the else empty in normal conditional code)?
Here's an example:
Javascript:
$(function() {
/*var data = [
{id:'1',name:'Test One',coordinates:'12.0012,-122.92'}
];*/
var data = [];
Tempo.prepare('userLocs').render(data);
});
HTML:
...
<tbody id="userLocs">
<tr data-template>
<td>{{name}}</td>
<td>{{coordinates}}</td>
<td>Delete</td>
</tr>
<tr data-template-fallback>
<td colspan="3">Javascript is not available.</td>
</tr>
</tbody>
...
I have an HTML table with combined row td's, or how to say, I don't know how to express myself (I am not so good at English), so I show it! This is my table:
<table border="1">
<thead>
<tr>
<th>line</th>
<th>value1</th>
<th>value2</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr>
<td>1.3</td>
<td>1.4</td>
</tr>
<tr>
<td rowspan="2">2</td>
<td>2.1</td>
<td>2.2</td>
</tr>
<tr>
<td>2.3</td>
<td>2.4</td>
</tr>
</tbody>
</table>
(you can check it here)
I want to convert this table to a JSON variable by jquery or javascript.
How should it look like, and how should I do it? Thank you, if you can help me!
if you want to convert only text use this one :
var array = [];
$('table').find('thead tr').each(function(){
$(this).children('th').each(function(){
array.push($(this).text());
})
}).end().find('tbody tr').each(function(){
$(this).children('td').each(function(){
array.push($(this).text());
})
})
var json = JSON.stringify(array);
To make a somehow representation of your table made no problem to me, but the problem is how to parse it back to HTML! Here a JSON with the first 6 tags:
{"table":{"border":1,"thead":{"th":{"textContent":"line","tr":"textContent":"value1",...}}}}}...
OR for better understanding:
{"tag":"table","border":1,"child":{"tag":"thead","child":{"tag":"th","textContent":"line",
"child":{"tag":"tr","textContent":"value1","child":...}}}}...
Closing tags are included.
For further explanations I need to know whether your table is a string or part of the DOM.
I belive this is what you want:
var jsonTable = {};
// add a new array property named: "columns"
$('table').find('thead tr').each(function() {
jsonTable.columns = $(this).find('th').text();
};
// now add a new array property which contains your rows: "rows"
$('table').find('tbody tr').each(function() {
var row = {};
// add data by colum names derived from "tbody"
for(var i = 0; i < jsonTable.columnsl.length; i++) {
row[ col ] = $(this).find('td').eq( i ).text();
}
// push it all to the results..
jsonTable.rows.push( row );
};
alert(JSON.stringify(jsonTable));
I think there should be some corrections, but this is it I think.