I've been stuck on this stupid problem for a few days now. I guess it's not complicated but I might need someone's help...
Here is the thing: I start with an empty table in my html page. There is only the head with the name of the columns. Then, I get JSON data thanks to php, and I fill my table by creating a new row and new cells as follows:
for (var j = 0; j < jsonVal.length; j++){
var tr = table.insertRow(-1);
tr.insertCell(-1).innerHTML = "<img src=\"" + jsonVal[j].image + "\">";
tr.insertCell(-1).innerHTML = jsonVal[j].name;
tr.insertCell(-1).innerHTML = jsonVal[j].rating;
};
Now, all I want to do is to update this table according to some parameters (ordered by name or rating, only 5 lines etc...)
To do so, I want to delete all the rows I currently have to put with the new data. BUT I can't find a way to delete them. Here is my deleting code:
var currentTable = document.getElementsByTagName("table")[0];
var rowCount = currentTable.rows.length;
for(var i = 1; i < rowCount; i++){
currentTable.deleteRow(i);
}
I get the following error:
IndexSizeError: Index or size is negative or greater than the allowed amount
Is that the correct way to do it?
PS: sorry for such a long explanation.
My bad, I only needed to change i to 1 in my for loop as follows:
var currentTable = document.getElementsByTagName("table")[0];
var rowCount = currentTable.rows.length;
for(var i = 1; i < rowCount; i++){
currentTable.deleteRow(1);
}
Related
I'm creating an HTML table from a server-side array (google apps script; so tableArray is coming from there). I have two forEach functions which work. However, I'm attempting to use two for loops instead because I'd like to be able to add different classes to different <td>'s.
The output doesn't come out as expected (see #1 below). I can either get an array in one column (instead of each element of the array as a separate <td> or the arrays are repeated in each <td> (see #2 below).
What do I need to change in my for loops to get the expected output?
You can see the version that works HERE.
1 (works with forEach)
2 (does not work with for)
Index.html
function buildTable(tableArray) {
var table = document.getElementById('table');
var tableBody = document.createElement('tbody');
var tbodyID = tableBody.setAttribute('id', 'tbody');
for (var i = 0; i < tableArray.length; ++i) {
var column = tableArray[i];
var colA = column[0];
var colB = column[1];
var colC = column[2];
var colD = column[3];
if (colA != "") {
var row = document.createElement('tr');
for (var j = 0; j < column.length; ++j) {
var cell = document.createElement('td');
cell.appendChild(document.createTextNode(column));
row.appendChild(cell);
}
}
tableBody.appendChild(row);
}
table.appendChild(tableBody);
document.body.appendChild(table);
}
Instead of line cell.appendChild(document.createTextNode(column));
write cell.appendChild(document.createTextNode(column[j]));
You've forgotten to add index [j]
// Loop over rows
for (var i = 0; i < tableArr.length; i++) {
var row = tableArr[i];
// loop over columns
for( var j =0; j<row.length; j++){
//create each column and append to row
}
// append row to table body
}
// append table body to DOM
For performance reasons you want to write to the DOM only once and create the table in memory first.
Change
cell.appendChild(document.createTextNode(column));
to
cell.appendChild(document.createTextNode(column[i]));
This will make it loop through all of your column data properly instead of appending the same content of the whole array repeatedly.
I have a table on Sharepoint and an array, I tried to compare them and highlight the ones that match but it doesn't work. Please help! The following code is coded in Javascript. I have tried various ways and tweaked accordingly according to my findings all around the web but nothing seems to be able to resolve this issue.
//gets table
var oTable = document.getElementById('tablename');
//gets rows of table
var rowLength = oTable.rows.length;
//loops through rows
for (i = 0; i < rowLength; i++){
//gets cells of current row
var oCells = oTable.rows.item(i).cells;
//gets amount of cells of current row
var cellLength = oCells.length;
//loops through each cell in current row
for(var j = 0; j < cellLength; j++){
// get your cell info here
var cellVal = oCells.item(j).innerHTML;
console.log(cellVal);
var serverRelativeUrlOfMyFile = "https://Sharepointsite/Blacklist.txt";
$.ajax({
url: serverRelativeUrlOfMyFile,
type: "GET"
}).done(handler);
function handler(data){
//console.log(data);
var lines = data.split('\n');
for(var line = 0; line < lines.length; line++)
{
if (cellVal.includes(lines[line])){
oCells.item[j].style.background = "red";
}
}
}
}
}
Below's another way that I tried to match my table on Sharepoint with my array. It works partially - Only the last item in the array gets matched when I run through the array properly. I don't really understand so appreciate the people out there who can help! Thanks a lot in advance.
(Additional Information!)
I create my table on Sharepoint by generating a table using Javascript with the executeQueryAsync function to retrieve data from a Sharepoint list and then producing it out as a viewable HTML table.
var serverRelativeUrlOfMyFile = "https://Sharepointsite/SoftwaresBlacklist.txt";
$.ajax({
url: serverRelativeUrlOfMyFile,
type: "GET"
}).done(handler);
function handler(data){
//console.log(data);
var lines = data.split('\n');
for(var line = 0; line < lines.length; line++){
//var templines = lines;
//alert(lines[line]);
$("#tablename tr:contains('" + lines[line] + "')").css("background-color", "red");
}
}
Another note, "item" is a method, so should use (), not [].
this.theCells.item[j].style.background = "red";
this.theCells.item(j).style.background = "red";
I ran into something similar recently. It came down to an issue of "scope" when referring to objects outside of the AJAX function.
Try something like this: (the new property named "theCells" and the line that starts with "this.theCells".)
$.ajax({
url: serverRelativeUrlOfMyFile,
theCells: oCells,
type: "GET"
}).done(handler);
function handler(data){
//console.log(data);
var lines = data.split('\n');
for(var line = 0; line < lines.length; line++)
{
if (cellVal.includes(lines[line])){
//oCells.item[j].style.background = "red";
this.theCells.item(j).style.background = "red";
}
}
}
Please read my question complete before answer or marking it duplicate because i am dealing with constraint in my problem.
Hi All Javascript rock stars,
I am creating a html table with javascript. In table i need scroller both vertical and horizontal. I am done with this part. It is working. Now my problem starts. When i am creating millions rows for the table it block my browser. For few thousand record it work fine.
I have done lot of google to improve performance but did not gain any significant performance improvement. Like some has suggested to use row.appendChild(cell); I have also tried to use Workers. But then i found i can not have access of document object in Workers. setTimeout is also not sufficient to solve my problem. Here is my code for creating rows of table.
var arr = JSON.parse(rcvReq.responseText);
var json = arr.abc;
var columns = [];
columns = Object.keys(json[0]);
//Build an array containing Customer records.
var customers = new Array();
customers.push(columns);
for (i = 0; i < json.length; i++) {
var dataVal = [];
for(j = 0; j < columns.length; j++){
var mytempvar = json[i];
dataVal.push(mytempvar[columns[j]+'']);
}
customers.push(dataVal);
}
//Create a HTML Table element.
var table = document.createElement("TABLE");
var table1 = document.createElement("TABLE");
table.border = "1";
//Get the count of columns.
var columnCount = customers[0].length;
//Add the header row.
var row = document.createElement('tr');
row.className = 'fixed-header';
for (var i = 0; i < columnCount; i++) {
var headerCell = document.createElement("TH");
headerCell.innerHTML = customers[0][i];
row.appendChild(headerCell);
}
table1.appendChild(row);
//Add the data rows.
var documentFragment = document.createDocumentFragment();
for (var i = 1; i < customers.length; i++) {
row = document.createElement('tr');
for (var j = 0; j < columnCount; j++) {
var cellVal = customers[i][j];
var cell = document.createElement("TD");
cell.innerHTML = cellVal;
row.appendChild(cell);
}
setTimeout(function(){ }, 1000);
documentFragment.appendChild(row);
}
/* Event of button */
var siblings = e.parentNode.children;
var childOf1stShibling = siblings[0];
table.appendChild(documentFragment);
var div = document.createElement("DIV");
var dvTable = document.getElementById(siblings[1].id +'');
var dvTable1 = document.getElementById(childOf1stShibling.children[0].id + '');
dvTable.innerHTML = "";
dvTable1.innerHTML = "";
dvTable.appendChild(table);
dvTable1.appendChild(table1);
Constraint
No use of jquery. Only i can use javascript, css and html.
No use of third party plugin.
I can not use pagination.
Records are in millions not in thousand.
Please suggest any workaround keeping above constraint in mind.
Thanks so much in advance.
You can check the source of this JavaScript plugin and take the pieces you need. The whole plugin is about 300 rows of code, you can remove some parts if you do not need them. This is a link to their GitHub repo.
On their demo site they append 500k rows and the scroll is smooth.
You can not display that many DOM elements without "blocking" browser.
And there are no "optimization" techniques to handle this, the only option, as mentioned #dandavis would be to listen for scroll events and display subsets on-demand for current scroll position.
As said #Veselin Clusterize.js does exactly that, but it works vertically only. If you need to apply this technique for two directions (horizontally + vertically) - take a look at library called Fattable. Demo
I have this code sample which updates cells within the html table.
for (var i = 0; i < o.Rows.length; i++) {
var row = $("tr").filter("[data-id='" + o.Rows[i].Id + "']");
row.find("td:eq(3)").text(o.Rows[i].Status);
row.find("td:eq(4)").text(o.Rows[i].Date);
}
Executing of this sample of code takes a long time if o.Rows.length is 100 000. Is there any more efficient way to do this?
You probably shouldn't have a table with 100,000 rows, but...
You could speed up things a little bit by querying all of them upfront:
var trs = $('tr');
for (var i = 0, l = o.Rows.length; i < l; i++) {
var tr = trs.eq(i);
var o = o.Rows[i];
tr.find('td:first').html(o.Status).next().html(o.Date);
}
Here's a jsperf showing it on 100 lines: http://jsperf.com/table-update/2
I've been trying to total a list of die rolls (sum of pairs) in a table using javascript to avoid hard-coding 11 rows in my html page and accessing each row seperately later in the js file to add the values.
So I used a loop and document.writeln() to do this in a more compact way but the output doesn't show the table or anything.
document.writeln("<table border=\"1\"><thead><tr><th>Sum of Dice</th><th>Total Times Rolled</th></tr></thead><tbody>");
for (var i=0; i < 11; i++)
{
document.writeln("<tr><td>2</td><td></td></tr>");
}
document.writeln("</tbody></table>");
The rows shouldn't all start with 2, I only used that number as a test and the second tag in the for loop is for the totals that I already have in an array but my issue is with displaying the table.
Try this:
<script>
var code = "";
function write(){
code += "<table border=\"1\"><tr><th>Sum of Dice</th><th> Total Times Rolled</th></tr>";
for (var i = 0; i < 11; i++){
code += "<tr><td>2</td><td></td></tr>";
}
code += "</table>";
document.body.innerHTML = code;
}
</script>
And don`t forget to put this code to html:
<body onload="write()">
Here you have the result:
I think create table by writeln with whole bunch of HTML text string is generally not a good idea. I would recommend create table dom element via Javascript and append it to the wrapper element.
var headerContent = ['Sum of Dice', 'Total Times Rolled'];
var table = document.createElement('table'),
header = table.createTHead(),
row,
cell;
table.border = 1;
// construct header
row = header.insertRow(0);
for (var i = 0, len = headerContent.length; i < len; i++) {
cell = row.insertCell(i);
cell.innerHTML = headerContent[i];
}
// construct table content
for (var i = 0; i < 11; i++) {
row = table.insertRow(i + 1);
for (var j = 0, len = headerContent.length; j < len; j++) {
cell = row.insertCell(j);
cell.innerHTML = '2';
}
}
// add table element to the dom tree
var wrapper = document.getElementById('wrapper');
wrapper.appendChild(table);
See http://jsfiddle.net/LgyuE/