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;
Related
I am trying to get the information from my table td's, using javascript. How can i achieve this? I have tried and failed, because i do not exactly understand the JS. So far, i have managed to get one of them to work, which is 'id' but thats just getting info from the db directly, the td values ive been unable to.
echoing the vals in my php update page shows the id val being passed successfully, but none others.
EDIT
Per your last comment I can recommend you use an event listener on all <td> tags and this way you can just get the relevant text of the specific <td> that the user clicked:
var tds = document.querySelectorAll('td');
for (var i = 0; i < tds.length; i++) {
var td = tds[i];
td.addEventListener('click', function(){
console.log(this.innerText)
});
}
<table>
<tr>
<td class="awb">I am the first awb</td>
<td class="awb">I am the second awb</td>
</tr>
<tr>
<td class="differentClass">I am the first differentClass</td>
<td class="differentClass">I am the second differentClass</td>
</tr>
</table>
You are approaching this all wrong...
Instead of this:
var awbno = String(tr.querySelector(".awb").innerHTML);
Do this:
var awbno = document.querySelector(".awb").innerHTML;
Here is a snippet:
var awbno = document.querySelector(".awb").innerHTML;
console.log(awbno);
<table>
<tr>
<td class="awb">Test Text inside a td tag</td>
</tr>
</table>
in order to get the contents of any element using class
let value = document.querySelector('.className').innerHTML;
in order to get the contents of a specific TD
let value = document.querySelector('td.className');
I have the following HTML table:
<table id="review-total">
<tbody><tr class="wlp">
<td class="left-cell">WLP Total</td>
<td>199.00</td>
</tr>
<tr class="tax">
<td class="left-cell">GST</td>
<td>19.90</td>
</tr>
<tr class="net">
<td class="left-cell">Order Total</td>
<td class="net-price">$218.90</td>
</tr>
</tbody>
</table>
I'm trying to loop through this table and retrieve the values i.e
199.00, 19.90 and $218.90 I have the following code:
var reviewTotal = document.getElementById('review-total');
for (var i = 1; i < reviewTotal.rows.length; i++) {
if (reviewTotal.rows[i].cells.length) {
wlpTotal = (reviewTotal.rows[i].cells[1].textContent.trim());
gstAmount = (reviewTotal.rows[i].cells[3].textContent.trim());
totalOrderAmount = (reviewTotal.rows[i].cells[5].textContent.trim());
}
}
I'm having a small issue trying to retrieve those values specified above, at present the error I get is textContent is undefined.
Can someone show me how I should go about retrieving those values, unfortunately I'm not strong in Javascript.
You have 3 rows and each row has only 2 cells. The 3 and 5 indices are undefined and undefined doesn't have .textContent property.
If you want to store the values by using specific variable names, you remove the loop and select the target elements manually:
var wlpTotal = reviewTotal.rows[0].cells[1].textContent.trim();
var gstAmount = reviewTotal.rows[1].cells[1].textContent.trim();
var totalOrderAmount = reviewTotal.rows[2].cells[1].textContent.trim();
If you want to store the values in an array, you can code:
var values = [].map.call(reviewTotal.rows, function(row) {
return row.cells[1].textContent.trim();
});
By using ES2015's Destructuring Assignment you can also extract the array's elements:
var [wlpTotal, gstAmount, totalOrderAmount] = values;
First:the index start the 0 either row or cell.
Secend:get value in the tag to use innerText or innerHTML ,The code following:
var reviewTotal = document.getElementById('review-total');
for (var i = 0; i < reviewTotal.rows.length; i++)
{
if (reviewTotal.rows[i].cells.length>1)
{
wlpTotal = (reviewTotal.rows[i].cells[1].innerText);
}
}
The following code outputs a table with values, and according to the value, it gets a layout. I use jQuery (Ajax) to update the information every 10 seconds.
php script that generates the wanted variables and stores (echoes) them into a json array (example.php)
$variable1 = 20;
if ($variable1 > 0) {
$td_variable1class="positive";
} else {
$td_variable1class="negative";
}
$array['variable1'] = $variable1;
$array['td_variable1'] = $td_variable1;
echo json_encode($array);
html table where the variable is retrieved from the json generated by the example.php:
<table>
<tr>
<td class='variable1class'>
<div id='variable1'></div>
</td>
</tr>
</table>
javascript:
<script type="text/javascript">
$(function() {
refresh();
});
function refresh() {
$.getJSON('example.php', function(data) {
$('div#variable1').html(data.variable1);
$('td.td_variable1').addClass(data.td_variable1);
});
setTimeout("refresh()",10000);
}
The problem is the "addClass" adds a class to the existing class, resulting in an output like this:
before the refresh:
<td class="td_variable1 positive">
after (assuming the variable changed from positive to negative):
<td class="td_variable1 positive negative">
I tried to avoid this by using removeclass:
$('td.td_variable1').removeClass().addClass(data.td_variable1);
But then the actual class name of the td is removed and my output looks like this:
<td class="negative">
and it should look like this:
<td class="td_variable1 negative">
Thanks for your help in advance!
Assuming you only have those 2 options, remove both (and only those two) then add the new one:
$('td.td_variable1').removeClass("positive negative").addClass(data.td_variable1);
.removeClass() removes all classes when not given any parameter. Use .removeClass("negative") instead.
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));
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.