looping javascript didn't work - javascript

I'm trying to get data from app engine datastore using javascript and json. it's also allowed jsonp service, here the javascript code:
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
$('#date').text(date);
$('#nohp').text(user);
$('#content').text(content);
}
});
you can also check it here: http://jsfiddle.net/YYTkK/7/
unfortunately, it just retrieve 1 latest data from the datastore. am I doing something wrong with this code?
thanks in advance.

You're not appending elements, but simply changing the value of the same 3 elements in question three times. So you simply overwrite the value you put into it the time before. The easiest way to solve this is to designate the existing tr as a .template and clone it in your loop, make the necessary changes (filling in the values) and then appending it.
Fixing some other unclear things this gives the following
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(records) {
for (var i = 0; i < records.length; i++) {
//Clone the row/unit which we will be using for each record (the class should refer to the type of item it /actually/ is)
row = $(".row.template").clone();
//The template class is hidden, so remove the class from the row/unit
row.removeClass("template");
var map = records[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
//Make the required changes (find looks for the element inside var row)
row.find('.date').text(date);
row.find('.nohp').text(user);
row.find('.content').text(content);
//Append it to the parent element which contains the rows/units
$("tbody").append(row);
}
});
See functional demo: http://jsfiddle.net/YYTkK/13/

You must append a new row in the table in every loop. Here's the working fiddle.
fiddle
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
var row = '<tr><td>'+date+'</td><td>'+user+'</td><td>'+content+'</td></tr>';
$('#valuetable').append(row);
}
});

what you have to do is create dynamic "tr" s and append to tbody and use thead for header and separate the body using tbody and create tr s on each iteration and after the loop append that tr to tbody. that will do the job, as you do now it will override the values at each iteration.

#chamweer answer is correct you have to create a new tr with td's dynamically
like this:
http://jsfiddle.net/YYTkK/14/
Because you're overriding the same td's over and over again.
$.getJSON("http://1.handy-post-402.appspot.com/show?callback=?", function(json) {
for (var i = 0; i < json.length; i++) {
var map = json[i].propertyMap;
var content = map.isi;
var user = map.No_HP;
var date = map.tanggal;
// create a temporary tr
var tr = $("<tr />");
// append to the tr the td's with their values
tr.append($("<td />").text(date), $("<td />").text(user),
$('<td />').text(content));
// finally append the new tr to the table's tbody
$("#js-tbody").append(tr);
}
});

Related

jQuery: Adding td elements with one class to tr

First of all I have to find the number of cells with one class, this line works.
var numcells = $('.hidden-td').length
And now I have to find the element with the class .placeholder-style I use this line (only one <tr>have this class):
$(this).find('.placeholder-style')
Now I have to add the same number of var numcellslike <td>inside the <tr>with the clase .hidden-td I think this will be with .addClass('hidden-td').
How can I make this?
Thanks
I'm assuming this is the correct structure you're after... if not, post your HTML so I can amend it but either way, this is how you should do it.
var numcells = $('.hidden-td').length;
var content = $(this).find('.placeholder-style');
for (i = 0; i < numcells; i++) {
content.append('<td class="hidden-td"></td>');
}

How to clear previous content from a table cell

I'm trying to add a "clearing" function to my table that calculates totals. So that when person first time presses button that does the calculation, then changes amounts of products and then presses again, the previous answer would be cleared and new added.
I have tried like this:
function clear () {
var table = document.getElementById("pricetable");
var rows = table.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
rows[i].className = "";
var cells = rows[i].getElementsByTagName("td");
for (var j = 1; j < cells.length - 1; j++) {
cells[j].className = "";
}
}
}
Then I'm calling the function in the beginning of my previous function that calculates the amounts and prices:
function calculate () {
clear ();
...
}
But nothing happens. I was thinking that it might have something to do with the fact that I have created the last row and also the last column (which both include the totals) dynamically. The id of the row is lastRow, and the column doesn't have id.
And I don't want to use jquery or add classes, ids etc to the html file. So does anyone know what's wrong with my code?
className just clears styling.
You're looking for innerHTML:
...
for (var j = 1; j < cells.length - 1; j++) {
cells[j].innerHTML = "";
}
...
className refers to the CSS class name(s) applied to an element. Here's what your current code does:
Before
<td class='foo'>999</td>
After
<td class=''>999</td>
innerHTML pretty much does what it says:
Before
<td class='foo'>999</td>
After
<td class='foo'></td>
Also, I just noticed your for loop starts at 1. Hopefully this was intentional ;)
I can see that you are setting the className to nothing rather than setting the innerHTML to nothing...
Try replacing this:
cells[j].className = "";
With this:
cells[j].innerHTML = "";

how to get the id of a tr inside the loop

hi i got the tr content like this way simil
var td = $("tr td"); // get first child of all the td elements
var htmlContent = []; // initilize an empty array
for (i = 0; i < td.length; i++) {
htmlContent[i] = $(td[i]).text();
trid[i] = $(td[i]).attr("id");
}
i want the tr id so i use this code
trid[i] = $(td[i]).attr("id");
but this is not good
You can use .parent() to get the tr, and then its id.
var htmlContent = []; // initilize an empty array
$('tr td').each(function () {
htmlContent.push($(this).text());
console.log($(this).parent().attr('id'));
});
Here is a simple fiddle: https://jsfiddle.net/hxsbLws2/1/
You should use td only since it is already a DOM object. You don't need to use it as a selector again like this $(td) ..
Then just specify the index td[i]
trid[i] = td[i].attr('id');

How can I reference an element after I have appended it using javascript not jquery

I am doing some basic javascripting and am creating a 3 column table created by javascript sourced from an xml. The table is created by appending all the data in rows via javascript.
The first column has an input checkbox, created via javascript, that if ticked fetches a price from the third column on that row and adds all the prices of the rows selected to give a price total.
The problem I am having is I don't seem to be able to reference the appended information to obtain the information in the related price column (third column).
I have attached both the function I am using to create the table which is working and the function I am using to try and add it up which isnt working.
I found the following two articles Getting access to a jquery element that was just appended to the DOM and How do I refer to an appended item in jQuery? but I am using only javascript not jquery and would like a javascript only solution if possible.
Can you help? - its just the calculateBill function that isn't working as expected.
Thank you in advance
function addSection() {
var section = xmlDoc.getElementsByTagName("section");
for (i=0; i < section.length; i++) {
var sectionName = section[i].getAttribute("name");
var td = document.createElement("td");
td.setAttribute("colspan", "3");
td.setAttribute("class","level");
td.appendChild(document.createTextNode(sectionName));
var tr = document.createElement("tr");
tr.appendChild(td);
tbody.appendChild(tr);
var server = section.item(i).getElementsByTagName("server");
for (j=0; j < server.length; j++) {
var createTR = document.createElement("tr");
var createTD = document.createElement("td");
var createInput = document.createElement("input");
createInput.setAttribute("type", "checkbox");
createInput.setAttribute("id", "checkInput");
createTD.appendChild(createInput);
createTR.appendChild(createTD);
var item = server[j].getElementsByTagName("item")[0].innerHTML;
var createTD2 = document.createElement("td");
var createText = document.createTextNode(item);
createTD2.appendChild(createText);
createTR.appendChild(createTD2);
var price = server[j].getElementsByTagName("price")[0].innerHTML;
var createTD3 = document.createElement("td");
var createText2 = document.createTextNode("£" + price);
createTD3.appendChild(createText2);
createTR.appendChild(createTD3);
tbody.appendChild(createTR);
}
}
}
onload = addSection();
function calculateBill() {
var finalBill = 0.0;
var checkBox = document.getElementById("checkInput");
for (i=0; i < checkBox.length; i++) {
if (checkBox[i].checked) {
var parentTR = checkBox[i].parentNode;
var priceTD = parentTR.getElementsByTagName('td')[2];
finalBill += parseFloat(priceTD.firstChild.data);
}
}
return Math.round(finalBill*100.0)/100.0;
}
var button = document.getElementById("button");
button.onClick=document.forms[0].textTotal.value=calculateBill();
When you do x.appendChild(y), y is the DOM node that you are appending. You can reference it via javascript either before or after appending it. You don't have to find it again if you just hang on to the DOM reference.
So, in this piece of code:
var createInput = document.createElement("input");
createInput.setAttribute("type", "checkbox");
createInput.setAttribute("id", "checkInput");
createTD.appendChild(createInput);
createInput is the input element. You can reference it with javascript at any time, either before or after you've inserted it in the DOM.
In this piece of code:
var price = server[j].getElementsByTagName("price")[0].innerHTML;
var createTD3 = document.createElement("td");
var createText2 = document.createTextNode("£" + price);
createTD3.appendChild(createText2);
createTR.appendChild(createTD3);
tbody.appendChild(createTR);
You're creating a <td> element and putting a price into it. createTD3 is that particular <td> element.
If you want to be able to find that element sometime in the future long after the block of code has run, then I'd suggest you give it an identifying id or class name such that you can use some sort of DOM query to find it again. For example, you could put a class name on it "price" and then be able to find it again later:
var price = server[j].getElementsByTagName("price")[0].innerHTML;
var createTD3 = document.createElement("td");
createTD3.className = "price";
var createText2 = document.createTextNode("£" + price);
createTD3.appendChild(createText2);
createTR.appendChild(createTD3);
tbody.appendChild(createTR);
Then, you could find all the price elements again with:
tbody.querySelectorAll(".price");
Assuming tbody is the table where you put all these elements (since that's what you're using in your enclosed code). If the table itself had an id on it like id="mainData", then you could simply use
document.querySelectorAll("#mainData .price")
to get all the price elements.
FYI, here's a handy function that goes up the DOM tree starting from any node and finds the first node that is of a particular tag type:
function findParent(node, tag) {
tag = tag.upperCase();
while (node && node.tagName !== tag) {
node = node.parentNode;
}
return node;
}
// example usage:
var row, priceElement, price;
var checkboxes = document.querySelectorAll(".checkInput");
for (var i = 0; i < checkboxes.length; i++) {
// go up to the parent chain to find out row
row = findParent(checkboxes[i], "tr");
// look in this row for the price
priceElement = row.querySelectorAll(".price")[0];
// parse the price out of the price element
price = parseFloat(priceElement.innerHTML.replace(/^[^\d\.]+/, ""));
// do something here with the price
}

JavaScript DOM : add an attribute to a <tr>

I want to create a JavaScript function that parses my HTML page, get the Table by it's ID, and after that, add a class attribute to each <tr> as if the line is the 1st, I'll add :
class="line1" to the <tr>
but if the line is the second, I'll add class="line2" to the <tr>
How to do please
If I understand you corrrectly, you want to alternate the class names to get some kind of zebra style right?
var table = document.getElementById('yourTableId');
var rows = table.rows;
for(var i = 0, l = rows.length;i < l; i++) {
rows[i].className = 'class' + ((i%2) + 1);
}
See the HTML DOM Table Object.
its very easy in jquery ... as below :-
$(document).ready(function() {
//for table row
$("tr:even").addClass("AlternateBG1");
$("tr:odd").addClass("AlternateBG2");
})
BUT IN JQUERY...
var table = document.getElementById("yourTableId");
for(var i in table.rows){
table.rows[i].className = 'line'+(i+1).toString();
}
It is easy without jQuery:
oTBody=document.getElementById("tBodyId");
//for (key in oTbody.childNodes) {
for (var nPos=0, nLength = oTbody.childNodes.length; nPos<nLegth; nPos++)}
oRow = oTbody.childNodes[nPos];
if (oRow && oRow.tagName && oRow.tagName.toLowerCase() == "tr") {
oRow.className = (bNormalRow? sClass1:sClass2);
bNormalRow = !bNormalRow;
}
}
With jQuery is really simple, do something like:
var i = 1;
$("#myTable tr").each(function() {
$(this).addClass("line"+i);
i++;
});
Where #myTable is your table id, and $(this) inside each function will be the current element on the cycle.

Categories