I am rendering an array of data in table element, the data can be filtered so the table should be updated with the new data.
I am using JQuery replaceWith() for replacing the old tbody element with new tbody which represents the new data, but it seems to take very long time on IE11 to be rendered when the length of the array of data is 1700.
This is my code:
var markup='', table = [] // 2D array of data;
markup += '<tbody>';
for (var row = 0; row < table.length; row++) {
markup += '<tr role="row">';
for (var col = 0; col < table[0].length; col++) {
markup += '<td>' + table[row][col] + '</td>';
}
markup += '</tr>';
}
markup += '</tbody>';
.$('#data-results > tbody').replaceWith(markup);
In my understanding, adding large strings of tags using .append() or .html() is supposed to be more efficient than adding through .replaceWith().
So, try my below lines of code to achieve the same you asked.
$('#data-results > tbody').empty();
$('#data-results > tbody').html(markup);
In otherway, you can also try .innerHTML
$('#data-results > tbody').empty();
$('#data-results > tbody').innerHTML = markup;
Related
I have table like this:
<table id="search-table" class="table">
<thead>
<tr>
<th>Something</th>
<th>Something2</th>
<th>Something3</th>
<th>Something4</th>
<th>Something5</th>
</tr>
</thead>
<tbody></tbody>
</table>
I have an API call which returns data that I want to put as row and columns in the empty tbody element.
var body = document.getElementsbyTagName("tbody");
var x = 0;
for (i = 0; i < APIcall.length; i++) {
var createRow = body.insertRow();
for (j = 0; j < 7; j++) {
var x = createRow.insertCell(j);
}
}
If I insertRow on the thead element the rows are created, but not when I try to add it to tbody. Probably me just misunderstanding something. Any suggestions what I should do?
you're almost there.
First, as Rory mentioned, you're not targeting the tbody in DOM.
You can fix that by replacing the first line with this:
var body = document.querySelector('#search-table tbody')
What that does, is this: It looks for an element with an ID of search-table and a descendant <tbody> and returns a reference.
Your code would run without an error then, but I'm confused about the result.
In the second line, you have var x = 0 but later on I can see var x = createRow.insertCell(j); also. (The second x would give you a reference to a new <td> element).
Hope that helps.
var html ='';
for (i = 0; i < APIcall.length; i++) {`enter code hereenter code here
html += '<tr><td>' + APIcall[i].somthing + '</td><td>'+ APIcall[i].somthing + '</td>' +
'<td>' + APIcall[i].somthing + '</td>' + < td > '+APIcall[i].somthing+' </td>'+
'<td>' + APIcall[i].somthing + '</td></tr>';
}
$('#search-table > tbody').append(html);
enter code here
If you have more than one tbody in your markup, you have to target your's specifically because getElementsByTagName returns an array of elements.
for eyample:
var tbodies = document.getElementsbyTagName("tbody");
var targetTbody = tbodies[0];
or you could loop over tbodies if you want to add your stuff to multiple tbodies.
I have been able to successfully read in a CSV file from a URL, parse through it, and write it out to a table. Simple to most but a Herculean effort for me. There is a header row, and each row contains 4 values (the first will be disregarded).
What I need to do is to be able to write each row to a different place on my page at will. I assume to do this I'd need to load each row into a slot in an array, where I can then call them specifically. For example if I want the 3rd entry, and also be able to access each value to build my text string, it would have to look something like:
document.getElementById("snow").innerHTML = 'Trail Status: ' + trail[2].status + 'Report Date: ' + trail[2].reportDate;
I know that the above code probably is flawed, but it was more illustrative than anything.
What I don't know how to do is setup an array to hold each row (so they can be accessed individually), define each value so it can be a accessed (trail, reportDate,etc), and read the CSV properly into that array.
I'm currently using jQuery and the code below to read, parse, and create the table.
$.ajax({
url: 'https://data.import.io/extractor/...',
dataType: 'text',
}).done(successFunction);
function successFunction(data) {
var allRows = data.split(/\r?\n|\r/);
var table = '<table>';
for (var singleRow = 0; singleRow < allRows.length; singleRow++) {
if (singleRow === 0) {
table += '<thead>';
table += '<tr>';
} else {
table += '<tr>';
}
var rowCells = allRows[singleRow].split(',');
for (var rowCell = 0; rowCell < rowCells.length; rowCell++) {
if (singleRow === 0) {
table += '<th>';
table += rowCells[rowCell];
table += '</th>';
} else {
table += '<td>';
table += rowCells[rowCell];
table += '</td>';
}
}
if (singleRow === 0) {
table += '</tr>';
table += '</thead>';
table += '<tbody>';
} else {
table += '</tr>';
}
}
table += '</tbody>';
table += '</table>';
$('body').append(table);
}
Any direction to reaching my end state would be greatly appreciated. Ultimately I'm building a dashboard that will show the Trail Conditions (from the CSV) and 10-day weather forecast (from Wunderground) to help plan Snowmobile Trips for local Michigan snowmobilers.
Thanks!
Marc
Create a multidimensional array - with 2 dimensions. The first index will access each row. The second index will access each cell within a row.
This reference may help: https://trans4mind.com/personal_development/JavaScript/Array2D.htm
This is an example using your current for loops.
function successFunction(data) {
var parsedData = [];
var allRows = data.split(/\r?\n|\r/);
for (var singleRow = 0; singleRow < allRows.length; singleRow++) {
var rowCells = allRows[singleRow].split(',');
for (var rowCell = 0; rowCell < rowCells.length; rowCell++) {
parsedData[singleRow][rowCell] = rowCells[rowCell];
}
}
}
Thanks for the input, i found that PapaParse was the way to go! The data was easy to get at and I had no problems!
Say I have a dynamic table, something like this (just an example):
var table = '<table>';
for (var i=0; i<6; i++) {
table += '<tr>';
table += '<th>';
table += 'HEADER ' + i + '</th></tr>'
table += '<tr><td>one</td>';
table += '<td>two</td>';
table += '<td>three</td>';
table += '<td>four</td>';
table += '<td>five</td>';
table += '<td>six</td>';
table += '<td>seven</td>';
table += '<td>eight</td>';
table += '</tr>';
}
table += '</table>';
What I'd like to do is to take each header and its table data under the header and save each as a separate table. For example, the first table would be:
HEADER 0
1 2 3 4 5 6 7 8
The second table would be:
HEADER 1
1 2 3 4 5 6 7 8
etc...
NOTE: There's no guarantee that there's only one row under each header. Some may have multiple rows.
To get the first table I could do:
var indexval = $(table).find('tr:contains("1")').index();
var firstTable = $(table).find('tr:lt('+indexval+')');
$('#testarea').html(firstTable);
I'm aware I'm calling these "tables" and that may not be correct. But how to start at the "next" header and go the the one after that and save 'that' table? In the end I'd have a number of little tables I could print to the screen by calling their variable names.
Demo:
var table = '<table>';
for (var i = 0; i < 6; i++) {
table += '<tr>';
table += '<th>';
table += '<td>HEADER ' + i + '</td></th></tr>'
table += '<tr><td>one</td>';
table += '<td>two</td>';
table += '<td>three</td>';
table += '<td>four</td>';
table += '<td>five</td>';
table += '<td>six</td>';
table += '<td>seven</td>';
table += '<td>eight</td>';
table += '</tr>';
}
table += '</table>';
//$('#testarea').html(table);
var indexval = $(table).find('tr:contains("1")').index();
var firstTable = $(table).find('tr:lt(' + indexval + ')');
$('#testarea').html(firstTable);
td, th {
min-width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='testarea'></div>
EDIT: I ended up solving my own problem by just using a couple of arrays to store each section of the table (each header and its immediate relevant rows under it). The first for loop gets the index value of the header, and the second for loop selects out the table rows (header and associated cells under it). The "firstRow" variable selects just the first header and its rows, the 'lastRow' variable does the same with the last header and row(s). Apologies for not initially putting the question in clear terms. The question was just asking how to segment out a large table into pieces with each header and its relevant rows underneath and save them as separate variables. My thinking was this would clean up my pagination method I've currently got on my site. When a 'page up' or 'page down' is clicked, it just loads the appropriate variable in the div on the page.
var firstRow = "";
var test = [];
var indexVal = [];
for (var i=2; i<7; i++) {
indexVal[i] = $(table).find('tr:contains('+('MC' + ' ' + i)+')').index();
}
firstRow = $(table).find('tr:lt('+indexVal[2]+')');
lastRow = $(table).find('tr:gt('+((indexVal[6]) - 1)+')');
for (var j=1; j<7; j++) {
test[j] = $(table).find('tr:lt('+indexVal[j + 1]+'):gt('+((indexVal[j]) - 1)+')');
}
The only issue I had was not being able to integrate the first and last rows into the for loops. I had to make them separate hand coded variables. But it works.
JSFIDDLE
I want print a table dynamically, but my program displayed in a messy way.
I hope each row conludes two elements. I want to display the table like this. In 1s it gets a name and display it. And in next 1s it gets another name and display it. By repeating in this way, display all data.Here is my main code.
var count = 0;
function AddTd(id, showname)
{
console.log(id);
if(id == 0) // if this is in the first column
{
var str = '<tr><td width="10px">'+showname+'</td>';
$("#datashow").append(str);
count = 1; // next element should in second column
return;
}
if(id == 1) // if this is in the second column
{
var str = '<td width="10px">'+showname+'</td></tr>';
$("#datashow").append(str);
count = 0; // next element should in first column
return;
}
}
setInterval('change()',50); // In function change, print the table dynamically
This should create table with as many elements as there will be in array and do 2 columns per row.
http://jsfiddle.net/XfKME/3/
var names = ["name1", "name2", "name3", "name4"];
var tbody = "<table>";
$.each(names, function (i, item) {
if (i % 2 == 0)
tbody += "<tr>";
tbody += "<td>";
tbody += item;
tbody += "</td>"
if (i % 2 == 1)
tbody += "</tr><br />";
});
tbody += "</table>";
I was hoping some would know how to tile a grid across. I have some code to get started
1 | 2
3 | 4
5 | 6
and in my ajax function
$.ajax({
complete:function(result) {
// in here i want to tile across two sets of td's for each tr
for(var i = 0; i < products.length; i++) {
$('#products').append('<tr><td>' + products[i].Title + '</td></tr>');
}
}
});
<table id="products"></table>
This works whatever the products size is (even or odd).
Hope with comments make it easy to understand
var table_body = '< tbody>';
for(var i = 0; i < products.length; i++) {
if(i%2==0)//if even we open a row
table_body += '<tr>';
//We always put a value
table_body += '<td>' + products[i].Title + '</td>';
if(i%2!=0 || (i==products.length-1))//if odd we close a row
table_body += '</tr>';
}
table_body += '< /tbody>';
$('#products').append(table_body);
Here is a sample code of what you are trying to achieve. You can optimize it to suit your needs. Fiddle
for(var i = 0, y=0; i < 10; i++){
if(y == 0){
$('table').html($('table').html() + '<tr>');
}
$('table').append('<td>' + i + '</td>')
y++;
if( y == 2 ){
y = 0;
$('table').html($('table').html() + '</tr>');
}
}
The simplest solution is to simply not use a table. Chances are if you're arranging data this way, it's not tabular data anyway. I recommend using display: inline-block on your elements and using an HTML element that makes sense for the data you're using, like a ul or li.
This will work for even or odd numbers of elements, fully tested.
var tbl = "";
for (var i = 0; i < products.length; ++i) {
if (i % 2 == 0) tbl += '<tr>';
tbl += '<td>' + products[i].Title + '</td>';
if (i % 2 == 1) tbl += '</tr>';
}
if (i % 2 == 1) tbl += '</tr>';
$("#products").append(tbl);
fiddle