Append dynamically created table javascript - javascript

I make an xhr request, I get the response and I append some values that I get to a table by appending. then I make second xhr request on another page, get some other results that I want to append under the previously inserted row..the problem is that every next append that I make instead of getting "under" the previously created row, gets before it..
I guess this is because these are dynamically created..but is there any way to solve this? without adding classes or ids to table or rows..
here is my code..
first the html
<body>
<table border="1">
<tr>
<th>first cell</th>
<th>second cell</th>
</tr>
</table>
<div id="div1">
</body>
and my javascript
function response(url, callback{
//xhr request
}
var url1 = "http://example1.com";
request(url1, function(response){
var temp1 = document.getElementsByTagName("table")[0];
var temp2create = document.createElement("tr");
var temp3 = ("<td>" + someresponse + "</td><td>" + someotherresponse + "</td>");
temp2create.innerHTML = temp3;
temp1.appendChild(temp2create);
});
var url2 = "http://example1.com";
request(url2, function(response){
var temp4 = document.getElementsByTagName("table")[0];
var temp5create = document.createElement("tr");
var temp6 = ("<td>" + someresponse + "</td><td>" + someotherresponse + "</td>");
temp5create.innerHTML = temp6;
temp4.appendChild(temp5create);
});
so, instead of having new row added after previous row, it gets before..

It could be that the first xhr request is taking longer to complete than the second one. Therefore the second one appends its response before the first receives and appends its response. You could either make placeholder rows in the table if a fixed amount of requests will come back, such as:
<body>
<table border="1">
<tr>
<th>first cell</th>
<th>second cell</th>
</tr>
<tr id="tr1">
</tr>
<tr id="tr2">
</tr>
</table>
</body>
and javascript:
(url1,response())
{
document.getElementById("tr1").innerHTML("someresponse");
}
(url2,response())
{
document.getElementById("tr2").innerHTML("some other response");
}
Or you could link the requests to occur in sequence if time is not of the essence.
request(url1, function(response){
var temp1 = document.getElementsByTagName("table")[0];
var temp2create = document.createElement("tr");
var temp3 = ("<td>" + someresponse + "</td><td>" + someotherresponse + "</td>");
temp2create.innerHTML = temp3;
temp1.appendChild(temp2create);
var url2 = "http://example1.com";
request(url2, function(response){
var temp4 = document.getElementsByTagName("table")[0];
var temp5create = document.createElement("tr");
var temp6 = ("<td>" + someresponse + "</td><td>" + someotherresponse + "</td>");
temp5create.innerHTML = temp6;
temp4.appendChild(temp5create);
});
});

nikolas, no. The calls are asynchronous, meaning the order they run, and complete is undefined. You can not rely on the order of completion matching the order of initiation. If you need that, then the thing to do is have the second xhr be called from the first's callback (chaining).

This is what I used on a recent project had to append JSON to an HTML.
Define the Table
<table id="geoTable" border="1"></table>
Populate
appendTableRow('geoTable', "MPH", 70);
appendTableRow('geoTable', "KPH ", 112.654);
Function to add rows
function appendTableRow(tableName,name,value)
{
tableName = "#" + tableName;
//<tr><td>name</td><td>value</td></tr>
var tableRow = "<tr><td>$name</td><td>$value</td></tr>";
tableRow = tableRow.replace("$name",name);
tableRow = tableRow.replace("$value",value);
$(tableName).append(tableRow);
}

Related

Extracting data from an HTML table

I have a table which shows these values.
turn-right
Go straight
turn-left
How do i get the 2nd value Go straight only ? I have this following codes.
var text = $('#personDataTable tr:first td:first').text();
This code above allows me to get the very first 'turn-right'. I tried to use
var text = $('#personDataTable tr:second td:first').text();
but it does not work.
This is the code i use to draw the table.
function drawTable(data) {
for (var i = 0; i < data.routes[0].legs[0].steps.length; i++) {
drawRow(data.routes[0].legs[0].steps[i]);
}
}
function drawRow(steps) {
var row = $("<tr />")
$("#personDataTable").append(row);
row.append($("<td>" + steps.maneuver + "</td>"));
console.log('Added Table');
}
This is my html
<table id="personDataTable">
<tr>
<th>Maneuver</th>
</tr>
</table>
tr:second is invalid CSS. The correct syntax is :
'#personDataTable tr:nth-child(2) td:first'

Get one specific row in automatically generated table

I am building a web application for the school. And I need to populate a table with data from a database. To do so, I used the following javascript :
http.onload = function (){
var roomData = JSON.parse(this.response);
roomData.forEach(data => {
var location=data.location;
var price=data.price;
var size=data.size;
var available=data.available;
var index = $("table tbody tr:last-child").index();
var row = '<tr>' +
'<td>'+location+'</td>' +
'<td>'+size+'</td>' +
'<td class="price">'+price+'</td>' +
'<td>'+available+'</td>' +
actions +
'</tr>'
$("table").append(row);
});
console.log((roomData));
}
http.open('GET', url, true);
http.send();
With the following architecture for the table :
<table class="table table-bordered">
<thead>
<tr>
<th>Address</th>
<th>Size</th>
<th>Price</th>
<th>Available</th>
</tr>
</thead>
<tbody>
</tbody></table>
But then, when I try to access one specific data with javascript, for example the price, I cannot really make the distinction between the rows because they have all the same id. Here is the code I am using to get the row's price :
$('td.price').html());
But obviously it only returns the price of the first row and not the one I want. How can I do it ?
You can achieve it as below:
Add the index in your forEach and use it as Id of the row:
roomData.forEach(function (element, index) {
var location=data.location;
var price=data.price;
var size=data.size;
var available=data.available;
var index = $("table tbody tr:last-child").index();
var row = '<tr>' +
'<td>'+location+'</td>' +
'<td>'+size+'</td>' +
'<td id="pricerow' + index + '" class="price">'+price+'</td>' +
'<td>'+available+'</td>' +
actions +
'</tr>'
$("table").append(row);
$('#pricerow1').html());
$('#pricerow2').html());
Ok I finally figured how to do it, I used :
var rows = document.getElementsByTagName('tr');
console.log(rows[$(this).closest("tr").index()+1].cells[2].innerHTML);
Your 'roomdata' info should have an ID of some sort, which you can use as an ID on the . Like (roomdata ID 5), en then access it with $('#rd-5 td.price').
Not sure if I understand you correctly, but that's the easiest way. Always have an unique reference and work with ID's.

How to separate each results page in table when user search for more than one product?

Here is my code, try to find the products when the user is searching.
if ($Results.find("product").length > 0)
{
var $theProduct = null;
var $id = vars['searchTerm'];
//Search for each product
$Results.find("product").each(function() {
if ($Results.find('id').text() === $id)
{
$theResult = $(this);
}
});
From this point my search results display in table
// Get the product data into the variables from the matched product
var id = $theResult.find("id").text();
var top = $theResult.attr("top-level-category");
var sub = $theResult.attr("sub-level-category");
var title = $theResult.find("title").text();
var brand = $theResult.find("brand").text();
var price = $theResult.find("price").text();
//Results goes to table
$('#search_table').append("<tr><td>" +
id + "</td><td>" +
top + "</td><td>" +
sub + "</td><td>" +
title + "</td><td>" +
brand + "</td><td>&pound" +
price + "</td></tr>");
});
}
When no search results find
else{
// We don't have any results
$("#mainBody").find("table").hide();
$("#mainBody").append("<h3>There are no search results. </h3>");
}
The problem i have now is when the user try to find more than one product one my page, my code breaks and i do not know why.
My html:
<div id="mainBody">
<table id="search_table">
<thead>
<tr>
<th>Product Code</th>
<th>Product Category</th>
<th>Product Type</th>
<th>Title</th>
<th>Brand</th>
<th>Price</th>
<tr>
</thead>
<tbody>
</tbody>
</table>
</div>
Ah, following on from my comment above...now I've formatted your code to be readable, with proper indentation, the problem becomes much more obvious. You run a .each() loop over the products inside Results, but all you do within the loop is assign a value to $theResult. Then you do nothing with it. Next time the loop runs, the value is over-written.
Then after the loop finishes, you start to try to use $theResult to append results to your table. But since you placed that code outside the loop, it will only run once, and will only ever use whatever the last value of $theResult happened to be - the value it was assigned the last time the loop executed.
This won't be a problem as long as there's only one item in $Results, but as soon as there are multiple items it'll be an issue. The fix is very simply to move all the code which interacts with $theResult inside your loop, so it will execute as many times as there are matching products:
$Results.find("product").each(function() {
if ($Results.find('id').text() === $id)
{
$theResult = $(this);
// Get the product data into the variables from the matched product
var id = $theResult.find("id").text();
var top = $theResult.attr("top-level-category");
var sub = $theResult.attr("sub-level-category");
var title = $theResult.find("title").text();
var brand = $theResult.find("brand").text();
var price = $theResult.find("price").text();
//Results goes to table
$('#search_table').append("<tr><td>" +
id + "</td><td>" +
top + "</td><td>" +
sub + "</td><td>" +
title + "</td><td>" +
brand + "</td><td>&pound" +
price + "</td></tr>");
});
}
});

The html td is not updating via jquery

I have this little method which, on the first load, created a <tr> and some <td>'s. That works. But if the underlying data changes, the <td>'s are not updated. I'm not sure why.
function ParseJson(json, isFirstLoad)
{
json = $.parseJSON(json);
var tr;
for (var i = 0; i < json.length; i++) {
if (isFirstLoad === 1)
{
tr = $('<tr/>');
tr.append("<td id='" + json[i].LocationName + "'>" + json[i].LocationName + "</td>");
tr.append("<td id='" + json[i].LocationName + "Count'>" + json[i].Count + "</td>");
$('#MainTable').append(tr);
}
else
{
var td = $("#" + json[i].LocationName + "Count");
td.html = json[i].Count;
}
}
When isFirstLoad is 1, the html is rendered as I would expect. Example:
<tr>
<td id="ChemLab">ChemLab</td>
<td id="ChemLabCount">24</td>
</tr>
But the next time around, if the data has changed and someone has left the Chem Lab, the html for ChemLabCount does not change.
I have verified that the json being passed into this method is correct. Meaning, the count DOES indeed change. It just doesn't get displayed on the screen.
jQuery .html() is a function, not a property.
td.html(json[i].Count);
The problem comes from td.html = json[i].Count; because it's not the right way of using html() method.
To set the Count to your td you could use .text() instead :
td.text( json[i].Count );
Else if you want to set an HTML code the you could use .html() :
td.html( json[i].Count );

jquery adding columns based on database records

I have an sqlite table with these columns:
| date | weight | bmi | mood | etc.
I want a table on my html page to display like this on the html page:
<table>
<caption></caption>
<thead>
<tr>
<td>(empty cell over row headings)</td>
Additional tH's as needed (this is where each date entry goes)
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Weight</th>
additional tD's as needed (this is where each weight entry goes matched with date in column heading)
</tr>
<tr>
<th scope="row">BMI</th>
additional tD's as needed (same as above)
</tr>
</tbody>
</table>
so basically I'm flipping the rows and columns for display purposes. This is all so I can graph the table using jQuery Visualize plugin that goes out as the date progresses. As you can imagine, over time more entries will be made adding to the columns of the display table. Here is what I have been messing around with so far (not including the graphing scripts ). I've gotten myself totally confused and now I'm just a mess...
Any suggestions would be a big help. I think I'm running into problems when trying to insert data into a table that's also trying to insert itself. I'm probably going about this wrong I bet.
Thanks
Mike
function homeSuccess(tx, results) {
// Gets initial count of records in table...
var entries = results.rows.length;
// Iterates over all the existing records...
for (var i = 0; i < entries; ++i) {
// The following element id's can be found in the div's within the table below, see element.innerHTML line...
var element = document.getElementById('colDate');
element.innerHTML += '<th scope="col">' + results.rows.item(i).timeStamp + '</th>';
var element2 = document.getElementById('tdWeight');
element2.innerHTML += '<td>' + results.rows.item(i).weight + '</td>';
var element3 = document.getElementById('tdBmi');
element3.innerHTML += '<td>' + results.rows.item(i).bmi + '</td>';
};
// 'screenView2 is a placeholder on the main html page...
var element = document.getElementById('screenView2');
element.innerHTML = '<br /><br /><h1>Data:</h1><br />Number of entries: ' + entries + '<br />' + '<table><caption>Mikes Health</caption><thead><tr><td></td><div id="colDate"></div></tr></thead><tbody><tr><th scope="row">Weight</th><div id="colWeight"></div></tr><tr><th scope="row">BMI</th><div id="colBmi"></div></tr></tbody></table>';
// This section is just a test trying to plug in static elements prior to trying database data... When using this section I had the iteration section commented out.
var element2 = document.getElementById('colDate');
element2.innerHTML = '<th scope="col">4-1-13</th>';
var element3 = document.getElementById('colWeight');
element3.innerHTML = '<td scope="col">123</td>';
var element4 = document.getElementById('colBmi');
element4.innerHTML = '<td scope="col">321</td>';
}
function homeQuery(tx) {
console.log("entering homeQuery");
tx.executeSql('SELECT * FROM HEALTHGRAPH', [], homeSuccess, onSqlError);
console.log("leaving homeQuery");
}
// Function that is called on initial page load
function homeDBopen() {
console.log("opening db for home data");
theDB = window.openDatabase("hgDB", "1.0", "HealthGraph", 3 * 1024 * 1024);
theDB.transaction(homeQuery, onTxError, onTxSuccess);
console.log("leaving homeDBopen");
}
Thought for sure someone would have answered this question as it seems like an issue lots of people must run into. A little discouraging. Anyway, I found an answer that I can adapt to my own project here:
http://msdn.microsoft.com/en-us/library/ie/ms532998(v=vs.85).aspx
// Insert cells into the header row.
for (i=0; i<heading.length; i++)
{
oCell = oRow.insertCell(-1);... etc.

Categories