Problems using x.length within for loop - javascript

I'm having problems trying to dynamically generate an HTML table based on input (column/row) values.
When I hardcode the values in the loop below (i.e. instead of using the prompt), it creates the correct number of cells. However, when using x.length within the loop, something isn't working correctly.
works correctly:
function createTable() {
// declare variables
var body = document.body,
table = document.createElement('table');
// Begin creating table
// for each row
for(var r = 0; r < 8; r++) {
// create row
var tr = table.insertRow();
// for each column
for(var c = 0; c < 8; c++) {
// create column
var td = tr.insertCell();
td.appendChild(document.createTextNode('Cell'));
}
}
// append table to body
body.appendChild(table);
}
createTable();
does not create correct cells based on variable input
function createTable() {
// declare variables
var body = document.body,
table = document.createElement('table'),
rows = prompt("enter rows"),
columns = prompt("enter columns");
// Begin creating table
// for each row
for(var r = 0; r < rows.length; r++) {
// create row
var tr = table.insertRow();
// for each column
for(var c = 0; c < columns.length; c++) {
// create column
var td = tr.insertCell();
td.appendChild(document.createTextNode('Cell'));
}
}
// append table to body
body.appendChild(table);
}
createTable();

rows and columns are strings, that's the only reason why they have a .length. You seem to want to use them as parsed numbers, without any lengths:
var body = document.body,
table = document.createElement('table'),
rows = parseInt(prompt("enter rows"), 10),
columns = parseInt(prompt("enter columns"), 10);
for (var r = 0; r < rows; r++) {
var tr = table.insertRow();
for (var c = 0; c < columns; c++) {
var td = tr.insertCell();
td.appendChild(document.createTextNode('Cell'));
}
}
body.appendChild(table);

Use parseInt(rows) and parseInt(columns). This functions return an integer but you must check if the input is really an string-represented integer value.

Related

Using Javascript create table (tableee added)

I'm putting tableee's(a list contains 36 elements) elements into my table(which is x) ,but It's would be a 6*6 matrix not just 1*1 matrix.
wrong
I need(just a likely example)
var x = document.createElement('table');
var y = document.createElement("tr");
var z = document.createElement("td");
document.body.appendChild(x);
for (var i=0; i<tableee.length; i++){
x.appendChild(y);
y.appendChild(z);
var t = document.createTextNode("why");
z.appendChild(t);
}
//console.log(tableee);
document.getElementById("table1").innerHTML = x;
I don't know what tableee is, but since you only use the length I've changed it to two variables rows and columns.
This should create the table structure you are looking for:
var columns = 6;
var rows = 6;
var table = document.createElement('table');
var tbody = document.createElement('tbody');
for (var i = 0; i < rows; i++){
var row = document.createElement('tr');
for (var j = 0; j < columns; j++){
var column = document.createElement('td');
var text = document.createTextNode('text');
column.appendChild(text);
row.appendChild(column);
}
tbody.appendChild(row);
}
table.appendChild(tbody);
document.body.appendChild(table);
table td {
border: 1px solid black;
padding: 2px 4px;
}
Also, it's a better idea to append the table to the document body at the end to avoid reflow/repaint calls on every iteration.
Thank you for providing the content of the variable tableee. So in my opinion I think you can use template strings (ES6 feature) to print all the content of the array but you will tweak the array to subdivide it into sub arrays
I made it programmatically but if you have direct access to the array, feel free to edit first to have the same form as in the code comments:
function splitarray(input) {
var output = [];
for (var i = 0; i < input.length; i += 6) {
output[output.length] = input.slice(i, i + 6);
}
return output;
}
// this is a dummie array I made up according to your tablee data in the screenshots
var tableee = ['1year', '2year', '3year', '4year', '5year', 'rate1%', '1.0100', '1.0201', '1.0303', '1.0406', '1.0510', 'rate2%', '1.0100', '1.0201', '1.0303', '1.0406', '1.0510', 'rate3%', '1.0100', '1.0201', '1.0303', '1.0406', '1.0510', 'rate4%', '1.0100', '1.0201', '1.0303', '1.0406', '1.0510', 'rate5%', '1.0100', '1.0201', '1.0303', '1.0406', '1.0510'];
// This is to add an empty string at the beginning of the array
tableee.unshift('');
// This is to slice the array into sub-array that have lenght of 6 each (to fit the required table)
// The array will have the form of [ [...](6), [...](6), [...](6), [...](6), [...](6), [...](6) ](6)
var newTableee = splitarray(tableee);
var x = '<table border="1"> <tbody>';
for (var i = 0; i < newTableee.length; i++) {
x += '<tr>';
for (var j = 0; j < 6; j++) {
x += `<td> ${newTableee[i][j]} </td>`; // Here is the use of template strings
}
x += '</tr>';
}
x += '</tbody> </table>';
document.getElementById('table1').innerHTML = x;
<div id="table1"></div>
hopefully this is a more specific answer to your issue.

How to create html table with 100 unique td using javascript

I'm trying to draw game board with 100 places using javascript.
I thought a table would be perfect for that - so every line will be tr, and every square is td. I manage to do this by this code above.
The problem that although I get my desired board visually – i actually just duplicate my tr 10 times.
I'm trying to give each square a unique id.
I need some guidance here.
function createBoard() {
var table = document.getElementById("puzzleBoard");
table.innerHTML = "";
for (var r = 0; r < 10; r++) {
var newRow = document.createElement("tr");
table.appendChild(newRow);
for (var c = -1; c < 9; c++) {
var newCell = document.createElement("td");
var cellName = (c + 1);
newRow.appendChild(newCell);
var newPiece = document.createElement("div");
//newPiece.setAttribute("id", "cell-0"+cellName;);
newPiece.innerHTML = "cell-0" + cellName;
newCell.appendChild(newPiece);
}
}
}
Try cellName = (c + 1) * (r + 1).
newPiece.innerHTML = `cell-${cellName}-row-${r}`;
The simplest unique identifier:
cellName++
Here the code:
function createBoard() {
var table = document.getElementById("puzzleBoard");
table.innerHTML = "";
var cellName = 0;//<-- initialization
for (var r = 0; r < 10; r++) {
var newRow = document.createElement("tr");
table.appendChild(newRow);
for (var c = -1; c < 9; c++) {
var newCell = document.createElement("td");
newRow.appendChild(newCell);
var newPiece = document.createElement("div");
newPiece.setAttribute("id", "cell-"+cellName);//<-- set id
newPiece.innerHTML = "cell-"+cellName;
cellName++;//<-- plus 1
newCell.appendChild(newPiece);
}
}
}
Now we have a 10x10 matrix in which we can perform easier math operations (you are doing a game). Each cell have a number from 0 to 99.

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.

Making grid set size no matter how many words are in it

I have a list of 3 letter words that dynamically generate a grid.
The problem is I need a 6x6 grid, and if there is not enough words in the list to facilitate a 6x6 (12 words) then it won't be the size needed, and only be a grid as big as the words in it.
How can I make it so it always produces a 6x6 grid, randomly generates positions for the words and fills the gaps with empty cells?
var listOfWords = {};
var ul = document.getElementById("wordlist");
var i;
for(i = 0; i < ul.children.length; ++i){
listOfWords[ul.children[i].getAttribute("data-word")] = {
"pic" : ul.children[i].getAttribute("data-pic"),
"audio" : ul.children[i].getAttribute("data-audio")
};
}
console.log(listOfWords);
var shuffledWords = Object.keys(listOfWords).slice(0).sort(function() {
return 0.5 - Math.random();
}).slice(0, 12);
var guesses = {}
console.log(shuffledWords);
var tbl = document.createElement('table');
tbl.className = 'tablestyle';
var wordsPerRow = 2;
for (var i = 0; i < Object.keys(shuffledWords).length - 1; i += wordsPerRow) {
var row = document.createElement('tr');
for (var j = i; j < i + wordsPerRow; ++j) {
var word = shuffledWords[j];
guesses[word] = [];
for (var k = 0; k < word.length; ++k) {
var cell = document.createElement('td');
$(cell).addClass('drop').attr('data-word', word);
cell.textContent = word[k];
// IF FIREFOX USE cell.textContent = word[j]; INSTEAD
row.appendChild(cell);
}
}
tbl.appendChild(row);
}
document.body.appendChild(tbl);
I have tried this, but cannot get it to work....
while(listOfWords.length < 12)
listOfWords.push(" ");
Did you try creating the table with the required size before, and then putting the word to a random td and tr?

Categories