Dynamically creating an object using eval() JS - javascript

I am trying to dynamically create an object in javascript. Here is the JS code that I have written:
var table = $("#eidtPersonalInfoTbl");
var trs = table.find('tr');
var obj = { };
$(trs).each(function(index, row){
var field = $(row).find('td').eq(0).html();
var value = $(row).find('td').eq(1).html();
eval('obj.' + field + ' = ' + value );
});
And here is the HTML markup for the table:
<table class="table" border="1" id="eidtPersonalInfoTbl">
<tr>
<td class="span3 hidden-phone" > Name </td>
<td class="span5"> Name </td>
</tr>
<tr>
<td class="span3 hidden-phone"> Address</td>
<td class="span5"> Address </td>
</tr>
<tr>
<td class="span3 hidden-phone">Area</td>
<td class="span5"> Area</td>
<tr>
<tr>
<td class="span3 hidden-phone">Gender</td>
<td>Male</td> </tr>
<tr>
<td class="span3 hidden-phone" > Salutation </td>
<td class="span5"> Dr</td>
</tr>
<tr>
<td class="span3 hidden-phone">State</td>
<td class="span5"> State </td>
<tr>
<tr>
<td class="span3 hidden-phone">City</td>
<td class="span5"> City </td>
</tr>
<tr>
<td class="span3 hidden-phone" > Postel Code </td>
<td class="span5"> Postel Code </td>
</tr>
<tr>
<td class="span3 hidden-phone" > Phone# </td>
<td class="span5"> 04128741 </td>
</tr>
<tr>
<td class="span3 hidden-phone" > Mobile# </td>
<td class="span5"> 03218741525</td>
</tr>
<tr>
<td class="span3 hidden-phone" > Cover Letter </td>
<td>Cover letter goes here</td>
</tr>
<tr>
<td> <input type="submit" name="per-det" class="btn btn-success span5" value="Update and Cont."></td>
</tr>
Whenever I try to execute this, it gives me this error
Undefined variable Name

It's far easier, safer and faster to use this:
obj[field] = value;
... instead of eval('obj.' + field + ' = "' + value + '"'), which obviously has the same purpose.
You see what you see now because value should be wrapped in the quotation marks. For example, if both field and value are equal to 'Name' (string), the evalled expression as it stands now will look like...
obj.Name = Name
... obviously causing the 'Undefined variable Name' error.
Two sidenotes here. First, there's no sense wrapping trs in jQuery object again in this line...
$(trs).each(function(index, row)
... as it already IS a jQuery object (result of table.find('tr')). This redundancy is easier to see if you follow a simple convention: preceding names of all the variables that are used to store jQuery objects with $:
var $table = $("#eidtPersonalInfoTbl");
var $trs = $table.find('tr');
// ...
// $($trs) - obviously redundant
Second, it's a bit wasting to go through DOM twice in these lines:
var field = $(row).find('td').eq(0).html();
var value = $(row).find('td').eq(1).html();
I'd rather have it rewritten it like this:
var $tds = $(row).find('td');
var field = $tds.eq(0).html(); // or just $tds[0].innerHTML;
var value = $tds.eq(1).html(); // or just $tds[1].innerHTML;

Related

Javascript XPath table loop td's

I am trying to create a Chrome Extension that will extract some data from a table. I want to transform the TD's of the TR's in simple lines with each column separated by a pipe | character, ex:
01/01/2020 | XX | 57,43 | |
02/01/2020 | YY | 11,22 | |
Here is a part of it:
<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td class="TRNbarratabelac" width="3%">
<input type="checkbox" name="chkTodos" id="chkTodos" onclick="selTodos(this)" style="background:transparent;border:0px;"></td>
<td class="TRNbarratabelac">Data do <br>pagamento</td>
<td class="TRNbarratabelac">Tipo</td>
<td class="TRNbarratabelac">Favorecido/beneficiário</td>
<td class="TRNbarratabelac">Valor (R$)</td>
<td class="TRNbarratabelac">Informações complementares</td>
<td class="TRNbarratabelac" colspan="2" width="20%">Opções</td>
</tr>
<tr>
<td class="TRNlicbe"><input type="checkbox" name="chkSel" id="chkSel" value="1" onclick="verSelTodos(this)" style="background:transparent;border:0px;"></td>
<td class="TRNlicbe">21/02/2020 </td>
<td class="TRNliebe">Concessionárias</td>
<td class="TRNliebe"> </td>
<td class="TRNlidbe">57,43 </td>
<td class="TRNlicbe"> </td>
<td class="TRNlicbde" width="8%">Visualizar</td>
<td class="TRNlicbde" width="12%"><span>enviar por email</span> </td>
</tr>
</tbody>
</table>
To iterate over it, I use XPath like this:
function DOMtoString(doc) {
let path_tr = '(//div[#class="contborda"])[4]/table[3]/tbody/tr[position()>1]';
var tr = doc.evaluate(path_tr, doc, null, XPathResult.ANY_TYPE, null);
let alertText = '';
let x = tr.iterateNext();
while (x) {
alertText += x.textContent;
x = tr.iterateNext();
}
return alertText;
}
Here I get the table (ignoring the first TR with column names), but the result is this (just some part of it):
<br> <br> 21/02/2020 <br> Concessionárias<br> <br> 57,43 <br> <br> Visualizar<br> enviar por email <br><br>
I see that XPath is adding BR's on it.
I try to loop over the TD's of these TR's with no success like this:
let path_td = '//td';
var td = tr.evaluate(path_td, tr, null, XPathResult.ANY_TYPE, null);
What is the correct way that I can interact over the TD's and get the raw text of them with no BR's?
Use innerText instead of textContent to avoid line breaks. You can use Document.querySelector() instead of XPath which will make DOM manipulation much easier.
CSS Selectors:
function DOMtoString() {
let lines = [];
let trs = document.querySelectorAll(
'div.contborda > table:nth-of-type(2) > tbody > tr:not(:first-child)'
);
trs.forEach(tr => {
let line = [];
let tds = tr.querySelectorAll('td');
tds.forEach(td => line.push(td.innerText.trim()));
lines.push(line.join('|'));
});
return lines;
}
console.log(DOMtoString());
<div class="dummy"></div>
<div class="contborda">
<table class="dummy"><tbody></tbody></table>
<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td class="TRNbarratabelac" width="3%">
<input type="checkbox" name="chkTodos" id="chkTodos" onclick="selTodos(this)" style="background:transparent;border:0px;"></td>
<td class="TRNbarratabelac">Data do <br>pagamento</td>
<td class="TRNbarratabelac">Tipo</td>
<td class="TRNbarratabelac">Favorecido/beneficiário</td>
<td class="TRNbarratabelac">Valor (R$)</td>
<td class="TRNbarratabelac">Informações complementares</td>
<td class="TRNbarratabelac" colspan="2" width="20%">Opções</td>
</tr>
<tr>
<td class="TRNlicbe"><input type="checkbox" name="chkSel" id="chkSel" value="1" onclick="verSelTodos(this)" style="background:transparent;border:0px;"></td>
<td class="TRNlicbe">21/02/2020 </td>
<td class="TRNliebe">Concessionárias</td>
<td class="TRNliebe"> </td>
<td class="TRNlidbe">57,43 </td>
<td class="TRNlicbe"> </td>
<td class="TRNlicbde" width="8%">Visualizar</td>
<td class="TRNlicbde" width="12%"><span>enviar por email</span> </td>
</tr>
</tbody>
</table>
</div>
If you have any other reasons you want to stick to using XPath, then you should use dot .// when you want to select nodes relative to nodeContext:
XPath:
function DOMtoString() {
let lines = [];
let path_tr = '//div[#class="contborda"]/table/tbody/tr[position()>1]';
let tr = document.evaluate(path_tr, document, null, XPathResult.ANY_TYPE, null);
let x = tr.iterateNext();
while (x) {
let line = [];
let path_td = './/td';
var td = document.evaluate(path_td, x, null, XPathResult.ANY_TYPE, null);
let y = td.iterateNext();
while (y) {
line.push(y.innerText.trim());
y = td.iterateNext();
}
lines.push(line.join('|'));
x = tr.iterateNext();
}
return lines;
}
console.log(DOMtoString());
<div class="dummy"></div>
<div class="contborda">
<table class="dummy"><tbody></tbody></table>
<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td class="TRNbarratabelac" width="3%">
<input type="checkbox" name="chkTodos" id="chkTodos" onclick="selTodos(this)" style="background:transparent;border:0px;"></td>
<td class="TRNbarratabelac">Data do <br>pagamento</td>
<td class="TRNbarratabelac">Tipo</td>
<td class="TRNbarratabelac">Favorecido/beneficiário</td>
<td class="TRNbarratabelac">Valor (R$)</td>
<td class="TRNbarratabelac">Informações complementares</td>
<td class="TRNbarratabelac" colspan="2" width="20%">Opções</td>
</tr>
<tr>
<td class="TRNlicbe"><input type="checkbox" name="chkSel" id="chkSel" value="1" onclick="verSelTodos(this)" style="background:transparent;border:0px;"></td>
<td class="TRNlicbe">21/02/2020 </td>
<td class="TRNliebe">Concessionárias</td>
<td class="TRNliebe"> </td>
<td class="TRNlidbe">57,43 </td>
<td class="TRNlicbe"> </td>
<td class="TRNlicbde" width="8%">Visualizar</td>
<td class="TRNlicbde" width="12%"><span>enviar por email</span> </td>
</tr>
</tbody>
</table>
</div>

Get all values from URL with no name textarea

I want to get all fields data separately from the table. as the table is dynamically created so main problem is newly created one.
Please check out:
I tried to get all fields using Javascript, but I still can't get values of newly created rows. Please check out the screenshot of Javascript method result:
I want to get all fields of table values, including newly created values too..so that I can post the data and access data using URL and post it in database
Here is my HTML :
<table id="items">
<tr>
<th>Item</th>
<th>Description</th>
<th>Unit Cost</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr class="item-row">
<td class="item-name">
<div class="delete-wpr"><textarea name="invoice_item[]">Web Updates</textarea><a class="delete" href="javascript:;" title="Remove row">X</a></div>
</td>
<td class="description"><textarea name="description[]">Monthly web updates for http://widgetcorp.com (Nov. 1 - Nov. 30, 2009)</textarea></td>
<td><textarea class="cost" name="unit_cost[]">$650.00</textarea></td>
<td><textarea class="qty" name="quantity[]">1</textarea></td>
<td><span class="price">$650.00</span></td>
</tr>
<tr class="item-row">
<td class="item-name">
<div class="delete-wpr"><textarea name="invoice_item[]">SSL Renewals</textarea><a class="delete" href="javascript:;" title="Remove row">X</a></div>
</td>
<td class="description"><textarea name="description[]">Yearly renewals of SSL certificates on main domain and several subdomains</textarea></td>
<td><textarea class="cost" name="unit_cost[]">$75.00</textarea></td>
<td><textarea class="qty" name="quantity[]">3</textarea></td>
<td><span class="price">$225.00</span></td>
</tr>
<tr id="hiderow">
<td colspan="5"><a id="addrow" href="javascript:;" title="Add a row">Add a row</a></td>
</tr>
<tr>
<td colspan="2" class="blank"> </td>
<td colspan="2" class="total-line">Subtotal</td>
<td class="total-value">
<div id="subtotal">$875.00</div>
</td>
</tr>
<tr>
<td colspan="2" class="blank"> </td>
<td colspan="2" class="total-line">Total</td>
<td class="total-value">
<div id="total">$875.00</div>
</td>
</tr>
<tr>
<td colspan="2" class="blank"> </td>
<td colspan="2" class="total-line">Amount Paid</td>
<td class="total-value"><textarea id="paid">$0.00</textarea></td>
</tr>
<tr>
<td colspan="2" class="blank"> </td>
<td colspan="2" class="total-line balance">Balance Due</td>
<td class="total-value balance">
<div class="due">$875.00</div>
</td>
</tr>
</table>
My Javascript code :
function myFunction() {
let QueryString = '';
var formFields = document.querySelectorAll('textarea');
formFields.forEach(function(textarea) {
//creates querystring for the form inputs
QueryString += textarea.name + '=' + textarea.value + '&';
//show the value of the textarea
console.log(textarea.value);
});
//remove the extra "&" from the end of the querystring
QueryString = QueryString.substr(0, QueryString.length - 1);
console.log("==FOR USING AS QUERY STRING FOR====");
// window.location.href = "index.php?name=" + QueryString;
alert(QueryString);
}
By newly created rows do you mean rows created after the page has loaded?
If so why don't you play around with
const formFields = [].slice.call(document.querySelectorAll('textarea'));
let AllValues = "";
formFields.forEach(formField => formField.addEventListener("input", yourFunction, false));
function yourFunction() {
AllValues += `${event.target.name}=${event.target.value}&`;
console.log(AllValues);
}
note: I'd target the id of the form otherwise all the textareas will be targetted...

How do I put randomly generated numbers into a table?

I need to put 6 randomly generated numbers in a an HTML table, I was wondering what would be the best solution, this is my JS code :
function GenerateNumber(){
var sResultat = "";
var iCompteur;
for(iCompteur=0;iCompteur<=6;iCompteur++)
{
sResultat = Math.round(Math.random()* 18) + 1;
}
}
Would calling them with the AddEventListener work? I need to make it appear everytime I load the page, and of course, the numbers need to be different if I reload the page.
Here is my HTML code : (I put numbers temporarily to test my code and to show where I want them to appear)
<div class="table">
<table>
<tr>
<th>FORce</th>
<th>DEXtérité</th>
<th>CONstitution</th>
<th>INTelligence</th>
<th>SAGesse</th>
<th>CHArisme</th>
</tr>
<tr>
<td class = "FOR">
5
</td>
<td class = "DEX">
4
</td>
<td class= "CON">
4
</td>
<td class ="INT">
4
</td>
<td class="SAG">
4
</td>
<td class="CHA">
3
</td>
</tr>
</table>
</div>
function generateNumber() {
var sResultat
var cells = ["FOR", "DEX", "CON", "INT", "SAG", "CHA"]
cells.forEach(function(cell) {
sResultat = Math.round(Math.random() * 18) + 1;
document.getElementsByClassName(cell)[0].innerText = sResultat
})
}
generateNumber()
<div class="table">
<table>
<tr>
<th>FORce</th>
<th>DEXtérité</th>
<th>CONstitution</th>
<th>INTelligence</th>
<th>SAGesse</th>
<th>CHArisme</th>
</tr>
<tr>
<td class="FOR">
</td>
<td class="DEX">
</td>
<td class="CON">
</td>
<td class="INT">
</td>
<td class="SAG">
</td>
<td class="CHA">
</td>
</tr>
</table>
</div>
function GenerateNumber(){
var tds = document.querySelectorAll('.table td');
return Array.prototype.forEach.call(tds, function(td){
td.innerHTML = Math.round(Math.random()*18) + 1;
});
}
window.onload = GenerateNumber;
<div class="table">
<table>
<tr>
<th>FORce</th>
<th>DEXtérité</th>
<th>CONstitution</th>
<th>INTelligence</th>
<th>SAGesse</th>
<th>CHArisme</th>
</tr>
<tr>
<td class = "FOR">
5
</td>
<td class = "DEX">
4
</td>
<td class= "CON">
4
</td>
<td class ="INT">
4
</td>
<td class="SAG">
4
</td>
<td class="CHA">
3
</td>
</tr>
</table>
</div>

Google Sites HTML Box isn't recognizing CSS or Javascript

So, I've searched around for a bit and found out that some of the CSS won't load in editor mode but will load in previewer mode, however, not all CSS is functioning properly and the Javascript is completely failing.
Here's some html and javascript I tried with the HTML Box:
<table id="Killed" cellpadding="0" cellspacing="0" align="center">
<tbody>
<tr>
<td>Buffalo</td>
<td align="right">
<span id="Kill_Count1"></span>
</td>
</tr>
<tr>
<td>Camels</td>
<td align="right">
<span id="Kill_Count2"></span>
</td>
</tr>
<tr>
<td>Cattle</td>
<td align="right">
<span id="Kill_Count3"></span>
</td>
</tr>
<tr>
<td>Chickens</td>
<td align="right">
<span id="Kill_Count4"></span>
</td>
</tr>
<tr>
<td>Ducks</td>
<td align="right">
<span id="Kill_Count5"></span>
</td>
</tr>
<tr>
<td>Goats</td>
<td align="right">
<span id="Kill_Count6"></span>
</td>
</tr>
<tr>
<td>Horses</td>
<td align="right">
<span id="Kill_Count7"></span>
</td>
</tr>
<tr>
<td>Pigs</td>
<td align="right">
<span id="Kill_Count8"></span>
</td>
</tr>
<tr>
<td>Sheep</td>
<td align="right">
<span id="Kill_Count9"></span>
</td>
</tr>
<tr>
<td>Turkeys</td>
<td align="right">
<span id="Kill_Count10"></span>
</td>
</tr>
</tbody>
</table><br><br>
<script>
window.addEventListener("load", function () {
function Kill_Count(id,totalDeaths) {
var deathsPerSecond = totalDeaths/365/24/60/60/4;
var deaths = 0, result;
var timer = 1;
setInterval(function() {
deaths = deathsPerSecond*timer;
result = deaths.toFixed();
document.getElementById(id).innerHTML = result;
timer++;
}, 250);
}
var killnum = "23199336 1501799 301275455 49877536490 2676365000 402611664 5018470 1375940758 564785251 635382008";
killnum = killnum.split(" ");
for (var i = 1; i <= 10; i++) {
var num = i-1;
var temp = killnum[num];
Kill_Count('Kill_Count'+i,Number(temp));
}
});
</script>
What needs to be added? Here's the website https://support.google.com/sites/answer/2500646?hl=en
Interesting problem. I think I may have found a decent solution for you:
First off, Google's HTML Box is auto-generating new id tags for the ids you made. So, id="Kill_Count1" through id="Kill_Count10" is turning into something like id="id_3___"
The first thing I did was change all of the ids to Classes, all set to "Kill_Text":
<span class="Kill_Text"></span>
Next, I wrote some javascript code to collect the elements these classes were in and set their ids back to "Kill_Count1" and such like you had before:
var spans = document.getElementsByClassName("Kill_Text");
// Reset auto-generated ids to Kill_Count#
for (var j = 1; j <= spans.length; j++) {
spans[j-1].id = ("Kill_Count" + j);
}
From there, your code worked just as expected.
Side notes:
At first when I was trying to get javascript to run I had to save the code in the box, save again, then refresh the page. Hopefully this helps if you didn't know already :)
Have you used Chrome developer tools? They are super useful when debugging web pages. [Ctl + Shift + I]
Your code currently sets 10 timers doing pretty much the same actions on individual spans. It would be more efficient to have one timer doing 10 actions (1 on each span)
For Reference:
Here's the final code I used in the HTML box:
<table id="Killed" cellpadding="0" cellspacing="0" align="center">
<tbody>
<tr>
<td>Buffalo</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Camels</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Cattle</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Chickens</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Ducks</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Goats</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Horses</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Pigs</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Sheep</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
<tr>
<td>Turkeys</td>
<td align="right">
<span class="Kill_Text"></span>
</td>
</tr>
</tbody>
</table>
<script>
function Kill_Count(id,totalDeaths) {
var deathsPerSecond = totalDeaths/365/24/60/60/4;
var deaths = 0, result;
var timer = 1;
setInterval(function() {
deaths = deathsPerSecond*timer;
result = deaths.toFixed();
document.getElementById(id).innerHTML = result;
timer++;
}, 250);
}
var killnum = "23199336 1501799 301275455 49877536490 2676365000 402611664 5018470 1375940758 564785251 635382008";
killnum = killnum.split(" ");
var spans = document.getElementsByClassName("Kill_Text");
// Reset auto-generated ids to Kill_Count#
for (var j = 1; j <= spans.length; j++) {
spans[j-1].id = ("Kill_Count" + j);
}
for (var i = 1; i <= 10; i++) {
var num = i-1;
var temp = killnum[num];
Kill_Count('Kill_Count'+i,Number(temp));
}
</script>

jQuery Selectors - Select text within a specific tag

Here is my code snippet:
<div class="totals">
<table id="shopping-cart-totals-table">
<col />
<col width="1" />
<tfoot>
<tr>
<td style="" class="a-right" colspan="1">
<strong>Grand Total</strong>
</td>
<td style="" class="a-right">
<strong><span class="price">$364.99</span></strong>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td style="" class="a-right" colspan="1">
Subtotal </td>
<td style="" class="a-right">
<span class="price">$354.99</span> </td>
</tr>
<tr>
<td style="" class="a-right" colspan="1">
Shipping & Handling (Flat Rate - Fixed) </td>
<td style="" class="a-right">
<span class="price">$10.00</span> </td>
</tr>
</tbody>
</table>
How would I use jQuery to select the first span of class "price" and assign the "$364.99" text within that tag to a variable?
var total = $('.price:first').text();
You can do like this:
var price = $('span.price').first().text();
Or any of these:
var price = $('span.price:first').text();
var price = $('span.price:eq(0)').text();
var price = $('span.price').eq(0).text();
var price = $($('span.price').get(0)).text();
var price = $($('span.price').get()[0]).text();
To get the text
$(".price").eq(0).text()
To set the text
$(".price").eq(0).text('12.21$')

Categories

Resources