Trying to pass by value in Javascript multi-dim array - javascript

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>";

Related

Nested for loop table with array

I would like to have the table randomized with array.
As you can see when you run it, it shows the same random number each row. I would like it to have it randomized on each cell.
here's the code:
//this is the variable that creates an array of random numbers
var random = [];
for(var i = 0; i < 100; i++){
random[i] = Math.floor(Math.random() * 1000) +1;
}
random.sort(function(a,b){
return a-b;});
var tabell;
tabell = "<table border='1' width='300' cellspacing='0' cellpadding='3'>";
//this is the nested for loop for creating a row
for(var i = 0; i < 10; i++){
tabell = tabell + "<tr>";
//this is the for loop for creating the cell
for(var j=0; j<10; j++){
tabell += "<td>" + random[i] + "</td>";
}
tabell = tabell + "</tr>"
}
tabell = tabell + "</table>"
document.write(tabell);
You could use random[(i*10) + j]
When i == 0 you wolud get random[0] to random[9]
When i == 1 you would get random[10] to random[19]
....
When i == 9 you would get random[90] to random[99]

ID to many elements elements

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.

Put a line break in a for loop that is generating html content

I have a for loop that is generating some HTML content:
var boxes = "";
for (i = 0; i < 11; i ++) {
boxes += "<div class=\"box\"><img src=\"unlkd.png\"/></div>";
}
document.getElementById("id").innerHTML = boxes;
I want to display 3 boxes in one row, then below them 2 boxes in one row, then 1, then 3 again, 2, and 1.
First i thought of using the if statement to check whether i > 2 to add a line break, but it will also add a line break after every box past the third one. Nothing comes to mind, and my basic knowledge of javascript tells me I'll have to make a loop for each row I want to make. Any advice?
I would use a different approch :
Use a array to store the number of item per row :
var array = [3, 2, 1, 3, 2];
Then, using two loops to iterate this
for(var i = 0; i < array.length; i++){
//Start the row
for(var j = 0; j < array[i]; ++j){
//create the item inline
}
//End the row
}
And you have a pretty system that will be dynamic if you load/update the array.
PS : not write javascript in a while, might be some syntax error
Edit :
To generate an id, this would be simple.
create a variable that will be used as a counter.
var counter = 0;
On each creating of an item, set the id like
var id = 'boxes_inline_' + counter++;
And add this value to the item you are generating.
Note : This is a small part of the algorithm I used to build a form generator. Of course the array contained much more values (properties). But this gave a really nice solution to build form depending on JSON
You can try something like this:
Idea
Keep an array of batch size
Loop over array and check if iterator is at par with position
If yes, update position and index to fetch next position
var boxes = "";
var intervals = [3, 2, 1];
var position = intervals[0];
var index = 0;
for (i = 0; i < 11; i++) {
boxes += "<div class=\"box\"><img src=\"unlkd.png\"/></div>";
if ((position-1) === i) {
boxes += "<br/>";
index = (index + 1) % intervals.length;
position += intervals[index]
}
}
document.getElementById("content").innerHTML = boxes;
.box{
display: inline-block;
}
<div id="content"></div>
var boxes = "",
boxesInRow = 3,
count = 0;
for (i = 0; i < 11; i ++) {
boxes += "<div class=\"box\"><img src=\"unlkd.png\"/></div>";
count++;
if(count === boxesInRow) {
boxes += "<br/>";
boxesInRow -= 1;
count = 0;
if (boxesInRow === 0) {
boxesInRow = 3;
}
}
}
document.getElementById("id").innerHTML = boxes;
var i;
var boxes = "";
for (i = 0; i < boxes.length; i++) {
boxes += "<div class=""><img src=""/></div>";
function displayboxes() {
"use strict";
for (i = 0; i < boxes.length; i++) {
out.appendChild(document.createTextNode(boxes[i] + "<br>"));
}
}
displayboxes(boxes);

Javascript html table not showing

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/

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