Unable to append row through javascript function - javascript

Im trying to append a row to a table. And this is the code that i tried
function load() {
for (var k = 0; k < 1; k++) {
var myTableDiv = document.getElementById("pID");
var tableBody = document.getElementById("tBody");
var table = document.getElementById('pTable');
table.appendChild(tableBody);
for (var i = 0; i < 3; i++) {
var tr = document.getElementById('RiskRow');
tableBody.appendChild(tr);
for (var j = 0; j < 1; j++) {
var element1= document.getElementById('RiskTD');
var element2= document.getElementById('severityTD');
var element3= document.getElementById('mitigationTD');
var element4= document.getElementById('contingencyTD');
var element5= document.getElementById('riskStatusTD');
tr.appendChild(element1);
tr.appendChild(element2);
tr.appendChild(element3);
tr.appendChild(element4);
tr.appendChild(element5);
}
}
myTableDiv.appendChild(table);
}
}
But this results in appending only one row. I need multiple rows to be added that follows the for loop. Im not sure where i stuck up.

Regardless of the redundant loops you have there (var k = 0; k < 1 will always perform once...), the reason you're seeing this behavior is because you're trying to append the same element over and over. This will cause the element to be moved, rather than copied.
Have a look at document.cloneNode

Related

Adapting merge cells in InDesign script

I found this script on SO, which is very close to what I need. But instead of it merging the cells with the one above I need it to merge with the cell to left of any empty cell.
I have tried to experiment with it and manged to get it to merge horizontally once but it merge three cells that weren't empty into one.
Would be greatful for any help
THanks
var myDoc = app.activeDocument;
myPage = myDoc.pages;
for (var p=0; myPage.length>p; p++){
try{
var myTable = myPage[p].textFrames.everyItem().tables.everyItem();
if (myTable.constructor.name == 'Table'){
for (var t = myTable.cells.length - 1; t >= 0; t--)
{
if (myTable.cells[t].contents==""){
var w = myTable.columns.length;
myTable.cells[t-w].merge(myTable.cells[t]);
}
}
}
}
catch(e){}
}
I found a solution
var i, j, cells;
// Get all the rows in the document
var rows = app.documents[0].stories.everyItem().tables.everyItem().rows.everyItem().getElements();
for (i = 0; i < rows.length; i++) {
// Get all the cells in a row
cells = rows[i].cells.everyItem().getElements();
for (j = cells.length-1; j >= 1; j--) {
if (cells[j].contents == '') {
cells[j-1].merge (cells[j]);
}
}
}

Javascript Array or indices undefined

I am building a web app which contains a DOM table. This is my code that should create a table from an array:
function create_table() {
var tablediv=document.getElementById('icon-table');
var table = document.createElement("table");
var grid = [[15][15]];
var template = "pixel-{1}-{2}";
table.className = "icon-table";
tablediv.appendChild(table);
for (var i = 0; i < 16; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < 16; j++) {
var td = document.createElement("td");
td.className = "icon-pixel";
td.id="pixel-"+ i + "-" + j;
td.style.backgroundColor = "rgb(255,255,255)"; // no dash - css attribute name becomes camelCase
grid[i][j] = td;
td.addEventListener("click", setpixel)
td.addEventListener("mousedown", pinselpixel)
tr.appendChild(td);
}
}
}
The assignment grid[i][j] = td; fails during the first loop iteration.
On the console in my browser the output says:
TypeError: undefined is not an object (evaluating 'grid[i][j] = td')
what am I missing?
There's a couple of problems here. First, you seem to be under the impression that
[[15],[15]]
will create an an array with two sub-arrays, each with 15 keys.
Instead, what that actually gives you is an array with two sub-arrays each containing one key each, with the value 15.
You probably meant this:
[new Array(15), new Array(15)]
Passing an integer to the array constructor creates the slots; passing it to an array literal simply adds that value to the array.
Even then, this approach isn't ideal. Yes, you're containing 15 (actually you presumably meant 16) slots, but they're just undefined slots right now, so this line will fail, since you can't treat undefined as an array:
grid[i][j] = td; //grid[i] == undefined, not an array
Better this (truncated for brevity):
for (var i = 0; i < 16; i++) {
grid[i] = []; //<-- create the row array in the loop
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < 16; j++) {
var td = document.createElement("td");
grid[i][j] = td; //<-- now we can append the column cell
tr.appendChild(td);
}
}
you are trying to loop over an array of array which has 2 elements inside. Each element is (like i said) an array, with a single entry - in your case 15.
Afterwards you are trying to iterate from 0 up to 15.
So your iterations should at first loop over grid array and afterwards over grid's elements up to their length.
but in my opinion it is not necessary to loop over an array here. just do the following:
var myGrid = []
for (var i = 0; i < 16; i++) {
for var k = 0; k < 16; k++) {
//do your stuff
myGrid[i][k] = td
}
}
this should work
The method of intializing the two dimensional array is wrong.
Please use the below method to initialize.
var grid = new Array(15);
for (var i = 0; i < 16; i++) {
grid[i] = new Array(15);
}
First we create the rows of the array (15 rows), then using a for loop we initialize 15 columns for each row. Then the code works fine!
function create_table() {
var tablediv=document.getElementById('icon-table');
var table = document.createElement("table");
var grid = new Array(15);
for (var i = 0; i < 16; i++) {
grid[i] = new Array(15);
}
var template = "pixel-{1}-{2}";
table.className = "icon-table";
tablediv.appendChild(table);
for (var i = 0; i < 16; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < 16; j++) {
var td = document.createElement("td");
td.className = "icon-pixel";
td.id="pixel-"+ i + "-" + j;
td.style.backgroundColor = "rgb(255,255,255)"; // no dash - css attribute name becomes camelCase
grid[i][j] = td;
td.addEventListener("click", function(){console.log("clicked");})
td.addEventListener("mousedown", function(){console.log("mousedown");})
tr.appendChild(td);
}
}
}
create_table();
<div id="icon-table"></div>
Your grid initialization is wrong. As mentioned by some comments:
var grid = [[15][15]];
is equivalent to:
const arr = [15]; // array with one element, 15
var grid = arr[15]; // 16th element, which doesn't exist
You probably instead want:
var grid = new Array(15).fill(new Array(15));
Which will give you a two-dimensional array that is 15 "wide" and 15 "tall".
That said, you really don't need to prefill your grid unless it is a requirement for some other reason (like you are printing out a chessboard or something that always has a fixed size).
Can change to this and try it?
var grid = [[15][15]];
to
var grid = [new Array(15), new Array(15)];

Creating a dynamic table in JavaScript

I am trying to create a dynamic table using JavaScript. I need the table to take the form of a scheduler (hour blocks for 24 hours) It has to span a full 24 columns for the hours with a header for each block. 12am, 1am...11pm, etc. However, I'm currently restricted to the first col for the headers. My knowledge of JavaScript is at a beginner level. This is a basic representation of what I need and what is broken. What would be the best way to fix this code or implement something better?
function populateTable(table, time, rows, cells, content) {
if (!table) table = document.createElement('table');
var head = document.createElement('thead');
var title = document.createElement('th');
head.appendChild(title);
for (var x = 1; x <= time; x++){
table.appendChild(head);
title.appendChild(document.createTextNode(x));
}
var body = document.createElement('tbody');
for (var i = 0; i < rows; ++i) {
var row = document.createElement('tr');
for (var j = 0; j < cells; ++j) {
row.appendChild(document.createElement('td'));
row.cells[j].appendChild(document.createTextNode(content + (j + 1)));
}
table.appendChild(row);
}
return table;
}
$(document).ready(function () {
document.getElementById('scheduleTable')
.appendChild(populateTable(null,12,12, 12, "content"));
});
Need to change the top part to:
var head = document.createElement('thead');
table.appendChild(head);
for (var x = 1; x <= time; x++) {
var title = document.createElement('th');
title.appendChild(document.createTextNode(x));
head.appendChild(title);
}
If you want the title cells to be spread out correctly.

JavaScript function to create an M x N text input table in a div

So I'm trying to work on a JavaScript function that will do what I said in the title. I assume the skeleton of it will be something like:
function createInputTable(divID, tableID, rows, cols)
{
var T = document.createElement('table id="'+tableID+'"');
// ... Do some stuff ...
document.getElementById(divID).appendChild(T);
}
Now I just need to figure out what goes in the // ... Do some stuff ....
From what I understand, appendChild(n) finds the "lowest" child node and adds a node n "below" it. Since my table consists of children that are rows, which have children that are columns, each of which has 1 child that is an input cell, I should have a loop like the following.
for (var i = 0; i < rows; ++i)
{
var thisRow = document.createElement("tr");
for (var j = 0; j < cols; ++j)
{
var thisCol = document.createElement("td");
var thisCell = document.createElement('input type="text"');
thisCol.appendChild(thisCell);
thisRow.appendChild(thisRow);
}
document.getElementById.appendChild(thisRow);
}
Or not. I'm wondering whether my understanding is correct and, if not, what I need to fix.

How to iterate through td in a tbody?

<table>
<tbody id="SAMPLETBODY">
<tr>
<td>TEST1</td>
<td>TEST2</td>
<td>TEST3</td>
<td>TEST4</td>
</tr>
</tbody>
</table>
I have the code above, I want to iterate through the td's, since iterating through tbodies in a table is like this:
var table1 = document.getElementById('firstTable');
for(int i = 0; i < table1.tBodies.length; i++) {
/*DO SOMETHING HERE*/
}
How can I do it in td inside tbodies?
EDIT:
I have multiple tbodies in the table, I have already tried some codes that is similar (It iterated through all tbodies) and posted here before I asked the question.
EDIT AGAIN:
final code:
function sampleFunc() {
var x = "";
var tds = document.querySelectorAll('#SAMPLETBODY td'), i;
for(i = 0; i < tds.length; ++i) {
x = x + tds[i].innerHTML;
}
return x;
}
thanks to:rink.attendant.6
Use querySelectorAll():
var tds = document.querySelectorAll('tbody td'), i;
for(i = 0; i < tds.length; ++i) {
// do something here
}
If you wish to restrict it to a certain table, for instance, #firstTable, you will need to specify that:
var tds = document.querySelectorAll('#firstTable tbody td');
Just noticed that you have an ID on your tbody, so the selector would look like this for your specific tbody:
var tds = document.querySelectorAll('#SAMPLETBODY td');
Using getElementsByTagName('td') or querySelectorAll is the most reasonable approach, but since you already know about tbodies, it might be interesting for you to learn about rows and cells as well.
A tbody element has a property rows, which is a collection of tr elements, i.e. the rows it contains (not surprising, right?). Each tr element in return as a property cells, which is a collection of td elements (no surprise here either).
So technically you could do
for(var i = 0; i < table1.tBodies.length; i++) {
var tbody = table1.tBodies[i];
for (var j = 0; j < tbody.rows.length; j++) {
var row = tbody.rows[j];
for (var k = 0; k < row.cells.length; k++) {
var cell = row.cells[k];
// ...
}
}
}
But such a nested for loop is hard to read and maintain. The other answers show much better solutions.
You can learn about the properties of tbody, tr and td in the MDN documentation.
var table1 = document.getElementById('firstTable');
Here it returns table with id firstTable
Then using that get all td within the table1 like
var tds = table1.getElementsByTagName('td');
Now you can iterate over each td like
for (i = 0; i < tds.length; i++) {
console.log(tds[i])
}
JSFiddle
Iterate over rows an cells arrays:
var table1 = document.getElementById('firstTable');
for (var i = 0; i < table1.tBodies.length; i++) {
var rows = table1.tBodies[i].rows;
for (var j = 0; j < rows.length; j++) {
var cells = rows[j].cells;
for (var k = 0; k < cells.length; k++) {
console.log(cells[k]);
}
}
}
http://jsfiddle.net/dfsq/6Xbre/
You can use this for example:
var tbody = document.getElementsByTagName("tbody")[0];
var tds = tbody.getElementsByTagName("td");
for(var node in tds){
console.log(tds[node])
}
There are different methods to do this things, you can use document.getElementById (if you have table or tbody with id), document.getElementsByClassName in case when table or tbody have class name etc.
Demo
give a id for your table and use javascript for this
<table id="table_id" >
<script>
var e1 = document.getElementById('table_id');
for(int i = 0; i < e1.tBodies.length; i++) {
}
</script>
</table>
try something like this
var table1 = document.getElementById('SAMPLETBODY');
var tds = table1.getElementsByTagName("td");
for (var i = 0; i < tds.length; i++) {
alert(tds[i].innerHTML);
}
Try this..
$("td", firstTable).each(function() {...}
With javascript only. Try this...
Edit:
var table = document.getElementById('SAMPLETBODY'),
cells = table.getElementsByTagName('td');
for (var k = 0; k < cells.length; ++k) {
// do stuff with cells[k];
alert(cells[k].innerHTML);
}
You can use the humble getElementsByTagName():
var tbody = document.getElementById('SAMPLETBODY'),
cells = tbody.getElementsByTagName('td');
for (var k = 0; k < cells.length; ++k) {
// do stuff with cells[k];
}

Categories