ID to many elements elements - javascript

I have maybe weird question, but it is very important to me to solve this.
I have table wich is not with stable amount of rows and columns, so i put the += operator to create cells, rows and etc. Now i need to identify every cell, but i don't understand how i can do it in this situation.
function drawBoard(board) {
var t="";
t="<table border: 2px >";
var x,y;
for(x=0; x<board.length; x++){
t+="<tr>";
for(y=0; y<board.length; y++){
t+="<td class='tablecell' onclick=''>X</td>"
}
t+="</tr>";
}
t+="</table>";
}

By identify a cell I'm assuming you would like to reference them later in different part of the code.
You could achieve it by giving your rows and cells classes and/or ids.
For a row, for example:
t += '<tr id="tr-' + x + '">';
for a cell
t += '<td class="tablecell tr-' + x + ' col-' + y + '" onclick="" id="td-' + x + '-' + y + '">X</td>'
Then rows can be referenced by #tr-x and cells #tr-x > td, and all specific columnd .col-y
As Matheus Avellar mentioned, added id to a cell as well in case you want to reference a particular cell on a grid using #td-x-y

You are able to use:
const cells = document.getElementsByClassName('tablecell')
Or you can collect every cell on the stage of creation, for example:
const cells = [];
for (let i = 0; i < board.length){
for (let j = 0; j < board.length){
const cell = document.createElement('td');
cells.push(cell);
}
}

You can set the id of each one equal to your 'y' variable.
Something like:
function drawBoard(board) {
var t = "";
t = "<table border: 2px >";
var x, y;
for (x = 0; x < board.length; x++) {
t += "<tr>";
for (y = 0; y < board.length; y++) {
t += `<td id="table-${y}" class='tablecell' onclick=''>X</td>`
}
t += "</tr>";
}
t += "</table>";
}
Using a bit of ES6 template literals, you can set tie your ID to your 'Y' variable since it's an incrementing number.

Related

What are the javascript parts in this for loop?

Can someone explain to me the parts of the for loops?
for (let i = 0; i < height; i++) {
grid += '<tr class="row-' + i + '">';
// loop for each cell
for (let j = 0; j < width; j++) {
grid += '<td class="cell" id="row-' + i + '_cell-' + j + '"></td>';
}
grid += '</tr>';
}
Unfortunately, I don't get the grid parts. How can I write it in a different way?
The grid variable is practically the content of the table. On each grid line, a new HTML element is generated (except the last one).
For i iterations, a new row is added with a class name equivalent to the iteration index. Considering how rows are indexed vertically on a table, height is used as a metric for the y axis.
Similarly, j iterations add a new cell into the current 'i' row. Considering how a cell is combination of a row and column on a table, width is used as a metric for the x axis.
After the second (j) loop is finished, the closing tag </tr>is added in order to close the current iterated row.
In your code, the grid is simply making height number of rows and width number of rows. The grid will store this HTML code and then it must probably be replacing it somewhere using Html DOM manipulation.
What are the javascript parts in this for loop?
The loop is part of javascript, the height, width, grid variables are part of javascript. Even the HTML code you are storing is part of javascript since it is being stored in grid which is just another JS variable.
You can refer the below code to see what the code is really doing -
<!DOCTYPE html>
<html>
<body>
<p>This example demonstrates the <b>making a table using JS</b> method.</p>
<p id="demo"></p>
<script>
//var is used to store the HTML code, height and width store the number of rows and columns of table
var grid = "<table>",
height = 5,
width = 5;
for (let i = 0; i < height; i++) {
grid += '<tr class="row-' + i + '">';
// loop for each cell
for (let j = 0; j < width; j++) {
grid += '<td class="cell" id="row-' + i + '_cell-' + j + '"> (' + i + ' , ' + j + ' )    </td>';
}
grid += '</tr>';
}
grid += "</table>";
// Below we are just replacing the HTML in p with HTML that we filled in grid
var x = document.getElementsByTagName("p");
document.getElementById("demo").innerHTML = grid;
</script>
</body>
</html>
The grid part is just a variable name the programmer chose. It is a simple nestes for loop that will produce html that will look like this (for a 1x1 input)
With the variables i and j representing the index of their loop.

Connect single image to single cell in a table with Javascript

I'm quite new both to programming and to this community, I'll try to be as clear as possible. I need to create an HTML table 16x16 with a button in every cell that displays a different image - a smiley - per cell, without ever showing the same smiley for different cells. I'm a bit stuck and I would also appreciate a hint, just to try and move on on my own. Thanks! Here is my code that creates the table and displays the image:
function displayImage(){
var num = Math.floor(Math.random() * 256);
document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
document.getElementById("YourImage").style.visibility = "visible";
}
for(var r = 0; r < rows;r++)
{
table += '<tr>';
for(var c= 0; c< cols;c++)
{
table += '<td style="width:50px" id="(i++)">' + '<button type="button" onclick="displayImage()">' +
"show me" + '</button>' + '</td>';
}
table += '</tr>';
}
document.write('<table id="grid" border="1">' + table + '</table>');
(ImagesArray is not shown for readability but it simply collects all 256 binary combinations).
The problem with this is that each time I click on a button it displays a random image and if I click again on the same button it shows another one, while I'd like it to show me always the same image for the same button.
NOTE: I cannot delete the button afterwards or similar tricks, as the player (it's an oTree experiment) needs to be able to go back to a smiley he saw any time.
Thanks a lot for your help!
I would change the point where the random number is generated and advance it from the display function to the initialization of the table.
Create an array with the numbers from 0 to 255. While looping through rows and columns to create the table, pick one random number from that array and assign it to the button's id attribute. Be sure to remove this number from the array, so it can't be used again for the following buttons. This way every of the 256 numbers will be used, but in random order. When a user clicks a button, with displayImage(this.id) the button's id is used as a parameter to call displayImage(). Thus always the same number of the button will be used the fetch the according image.
The code:
// call displayImage() with parameter
function displayImage(num){
document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
document.getElementById("YourImage").style.visibility = "visible";
}
// create array 'nums' with numbers from 0 to 255 (= rows * cols)
var nums = [];
for (var i = 0; i < (rows * cols); i++) {
nums.push(i);
};
for(var r = 0; r < rows; r++)
{
table += '<tr>';
for(var c = 0; c < cols; c++)
{
// get random index in array 'nums'
var random = Math.floor(Math.random() * nums.length);
// assign an id to the button with a random number from 'nums' and use this id in displayImage()
table += '<td style="width:50px" id="(i++)">' + '<button id="' + nums[random] + '" type="button" onclick="displayImage(this.id)">' +
"show me" + '</button>' + '</td>';
// remove the already used random number from 'nums'
nums.splice(random, 1);
}
table += '</tr>';
}
document.write('<table id="grid" border="1">' + table + '</table>');
This way you will have the same image connected to every button. It's randomized while creating the table, so the order is different every time you load the page.
I assume you are using HTML5 because only then it is permitted that id attributes consists only of digits.
Note: I don't know what exactly you want to achieve with id="(i++)" when creating the <td> element. The way you do it just names every id with the string (i++) which contradicts the idea that ids should be unique. If you want to name the ids ascending from for example td-0 to td-255 you should change the line to:
table += '<td style="width:50px" id="td-' + (r * rows + c) + '">' + '<button id="' + nums[random] + '" type="button" onclick="displayImage(this.id)">' + "show me" + '</button>' + '</td>';
You can't just use the numbers without adding something like td-, because the buttons already have pure numbers as id.
try this:
var rows = 16, cols = 16;
var table = '';
function shuffle(array) { // shuffle (randomize) array elements
var i = array.length, j, x;
while (i) {
j = Math.random() * i-- | 0;
x = array[i];
array[i] = array[j];
array[j] = x;
}
}
var rNums = new Array(rows * cols);
for (var i = 0; i < rows * cols; i++) {
rNums[i] = i;
}
shuffle(rNums);
function displayImage(num) {
//var num = Math.floor(Math.random() * 256);
document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
//document.getElementById("canvas").innerHTML = num;
document.getElementById("YourImage").style.visibility = "visible";
}
var i = 0;
for (var r = 0; r < rows; r++) {
table += '<tr>';
for (var c = 0; c < cols; c++) {
table += '<td style="width:50px" id="' + i + '"><button type="button" onclick="displayImage(' + rNums[i] + ')">show me</button></td>';
i++; //go to next element of rNums array
}
table += '</tr>';
}
document.write('<table id="grid" border="1">' + table + '</table>');

Trying to pass by value in Javascript multi-dim array

So, I'm building a web site that you can play othello on as a code sample. I've got a multidimensional array as the behind-the-scenes gameboard, and then iterate through every 'td' in a table to match the value of the corresponding array member. The problem i'm encountering is that iterating through the table. and using the iterators as essentially coordinates to my array doesn't work. As the iterator increases in value, so too does the coordinates in each of my 'td's. I'm stumped, and running on fumes. Any help would be appreciated.
function gridArray() {
// creates game board's array.
for (var i = 0; i < gameArray.length; i++) {
gameArray[i] = new Array(8);
}
for (var row = 0; row < gameArray.length; row++) {
for (var col = 0; col < gameArray[row].length; col++) {
gameArray[row][col] = "green";
}
}
}
function drawGrid(){
// writes table to HTML document
var htmlString = "<table id='othelloGrid'><tr>";
for (var i = 0; i < 8; i++) {
htmlString += "<th>" + i + "</th>";
}
htmlString += "</tr>";
for (var j = 0; j < 8; j++) {
htmlString += "<tr>";
xPos = j;
for (var x = 0; x < 8; x++) {
yPos = x;
// HERE!!! I now realize javascript passes by reference, so as this loop iterates,
// every single 'td' is getting 'onclick = 'changeClass(7, 7)''.
// for my game grid to work, I need each td to have a unique xPos, yPos to
// connect back to gameArray.
htmlString += "<td onclick = 'changeClass(xPos, yPos)'></td>";
}
htmlString += "</tr>";
}
htmlString += "</table>";
return htmlString;
}
Variables are not expanded inside strings. So all your TDs have the literal attribute onclick='changeClass(xPos, yPos)' in them, not the values of these variables from the loop. So when you actually click on them, they all use the most recent values of those variables.
You need to use string concatenation to get the values. And there's no need for the global variables xPos and yPos, you can use the local j and x variables.
htmlString += "<td onclick = 'changeClass(" + j + ", " + x + ")'></td>";

How to calculate how many rows and columns are needed

I want to produce a table with Javascript. I want to give it a number and that's how many cells are created. There are always to be 3 columns however (3 pictures per row)
Could someone help me out with this? I think I need to use the modulus operator but I am unsure of how to use it correctly.
I do not want any extra cells. I can calculate the rows without issue but I don't want extra cells for those rows if that makes sense. So once the cells have been made that row ends even if it's 1 or 2 cells short.
I have this at the moment:
rows = ?? //Not sure how to calculate this
columns = 3;
str = "";
str += '<table border="1" cellspacing="1" cellpadding="5">';
for(i = 0; i < rows; i++){
str += '<tr>';
for (j = 0; j < columns; j++){
str += '<td>' + (i + j) + '</td>';
}
str += '</tr>';
}
str += '</table>';
Say if u have number of pictures as numPictures:-
Then
var numRows = Math.ceil(numPictures/3);
I hope the following code that what you want.
var numOfPics = 100; // Number of Pictures
var columns = 3, rows = Math.ceil(numOfPics / columns), content = "", count = 1;
content = "<table border='1' cellspacing='1' cellpadding='5'>";
for (r = 0; r < rows; r++) {
content += "<tr>";
for (c = 0; c < columns; c++) {
content += "<td>" + count + "</td>";
if (count == numOfPics)break; // here is check if number of cells equal Number of Pictures to stop
count++;
}
content += "</tr>";
}
content += "</table>";
document.body.innerHTML = content; // insert `content` value into body of page
You know how many cells there are. So you divide the number of cells by the number of columns to get the number of rows. Math.ceil() rounds up in case there are not the exact amount of cells to fill a row.
rows = Math.ceil(total_num_cells / 3);

Need help w/ JavaScript and creating an html table from array

I've tried everything I can find via google and nothing has worked correctly. Output is just a single row with all the contents of the array listed. What I need is a way to write the contents of an array but after 3 cells, automatically start a new line. I'll post the code I've made below as well as the question. (yes this is from an assignment. :( )
//***(8) place the words in the string "tx_val" in a table with a one pixel border,
//*** with a gray backgound. Use only three cells per row. Empty cells should contain
//*** the word "null". Show the table in the span block with id="ans8"
var count = i % 3;
var nrow = "";
var out = "<table border='1' bgcolor='gray'><tr>"
for (var i=0; i<txArr.length; i++)
{
out += ("<td>" + txArr[i] + "</td>");
count++;
if (count % 3 == 0)
{
nrow += "</tr><tr>";
}
}
document.getElementById('ans8').innerHTML = out + nrow;
you need to print the tr's inside the table (annd add a </table>!):
var count = i % 3; // btw. what's this??
var nrow = "";
var out = "<table border='1' bgcolor='gray'><tr>"
for (var i=0; i<txArr.length; i++)
{
out += "<td>" + txArr[i] + "</td>";
count++;
if (count % 3 == 0)
out += "</tr><tr>";
}
out += "</table>";
document.getElementById('ans8').innerHTML = out;
Rather than try to write out the html, try manipulating the dom. It seems much more straightforward to me. Take a look at the following:
var row = table.insertRow();
msdn
mdc
var cell = row.insertCell();
msdn
mdc
var cellContent = document.createTextNode(txArr[i]);
msdn
mdc
cell.appendChild(cellContent);
msdn
mdc
For deciding when to start a new row, just use the modulus operator (%
msdn
mdc
) against i:
if (i % 3 == 0)
{
row = table.insertRow()
}
You'd end up with something like this:
var container = document.getElementById("ans8");
var t = container.appendChild(document.createElement("table"));
var row;
txArr.forEach(function (item, i)
{
if (i % 3 == 0)
{
row = t.insertRow()
}
row.insertCell().appendChild(document.createTextNode(item));
});
I'll leave a little for you to figure out - border, background color, getting the word "null" in there. It is your homework after all. :-)
Also, for older browsers you'll need to add Array.forEach in yourself.
I prefer using an array over concatination
var html = [];
html.push("<table><tr>");
var i = 0;
for (var k in txArr)
{
if(i>=3){
i=0;
html.push("</tr><tr>");
}
html.push("<td>" + txArr[k] + "</td>");
i++;
}
html.push("</tr></table>");
document.getElementById('ans8').innerHTML = html.join('');
// wrapped in function
function arrayToTable(a,cols){
var html = [];
html.push("<table><tr>");
var i = 0;
for (var k in a)
{
if(i>=cols){
i=0;
html.push("</tr><tr>");
}
html.push("<td>" + a[k] + "</td>");
i++;
}
html.push("</tr></table>");
return html.join('')
}
document.getElementById('ans8').innerHTML = arrayToTable(txArr, 3);
It might be a tad easier to accomplish with something like
buffer = "<table>";
for(var r = 0; r < 10; r++){
buffer += "<tr>";
for(var c = 0; c < 3 ; c++){
buffer += "<td>Cell: " + r + ":" + c + "</td>";
}
buffer += "</tr>";
}
buffer += "</table>";
document.getElementById("ans8").innerHTML = buffer;
That would create a table 30 rows long by 3 columns for each row.
you might be assigning values to "count" too early as you don't know what i is yet. and you are not spitting out the value of nrow anywhere... change it to out.
var count;
var nrow = "";
var out = "<table border='1' bgcolor='gray'><tr>"
for (var i=0; i<txArr.length; i++)
{
out += ("<td>" + txArr[i] + "</td>");
count++;
if (count % 3 == 0)
{
out += "</tr><tr>";
}
}
document.getElementById('ans8').innerHTML = out + nrow;
Basically I would split it up into 3 functions, for readability and maintenance. These functions would consist of creating a cell, a row, and a table. This definitely simplifies reading the code. As I have not tested it, below is an example of what I would do.
function createTableCell(value) {
return value == null? "<td>NULL</td>":"<td>" + value + "</td>";
}
function createTableRow(array) {
var returnValue = "";
for (var i = 0; i < array.length; i++) {
returnValue = returnValue + createTableCell(array[i]);
}
return "<tr>" + returnValue + "</tr>";
}
function arrayToTable(array, newRowAfterNArrayElements) {
var returnValue = "<table>";
for (var i = 0; i < array.length; i = i + newRowAfterNArrayElements) {
returnValue = returnValue + createTableRow(array.split(i, (i + newRowAfterNArrayElements) - 1));
}
return returnValue + "</table>";
}
document.getElementById("ans8").innerHTML = arrayToTable(txArr, 3);
In addition this makes your code much more dynamic and reusable. Suppose you have an array you want to split at every 4 element. Instead of hardcoding that you can simply pass a different argument.
Here's a live example of doing this with DOMBuilder, and of using the same code to generate DOM Elements and an HTML String.
http://jsfiddle.net/insin/hntxW/
Code:
var dom = DOMBuilder.elementFunctions;
function arrayToTable(a, cols) {
var rows = [];
for (var i = 0, l = a.length; i < l; i += cols) {
rows.push(a.slice(i, i + cols));
}
return dom.TABLE({border: 1, bgcolor: 'gray'},
dom.TBODY(
dom.TR.map(rows, function(cells) {
return dom.TD.map(cells);
})
)
);
}
var data = [1, 2, null, 3, null, 4, null, 5, 6];
document.body.appendChild(arrayToTable(data, 3));
document.body.appendChild(
dom.TEXTAREA({cols: 60, rows: 6},
DOMBuilder.withMode("HTML", function() {
return ""+arrayToTable(data, 3);
})
)
);
Yes, you can build from scratch...but there's a faster way. Throw a grid at it. The grid will take data in a string, array, json output, etc and turn it into a proper HTML outputted table and will allow you to extend it with sorting, paging, filtering, etc.
My personal favorite is DataTables, but there are numerous others out there.
Once you get proficient, setting one of these up literally takes 5 minutes. Save your brain power to cure world hunger, code the next facebook, etc....

Categories

Resources