dynamically added dom-elements not responding to jQuery-function - javascript

Consider the following code:
$(document).ready(function(){
var table1 = $("table").eq(0);
var row_list;
var rows;
var x;
var y;
$("#mybutton").click(function(){
row_list = table1.find("tr");
rows = row_list.length;
x = $("#field_x").val();
y = $("#field_y").val();
if(x>rows || y>rows){
var num;
if(x>y) num=x;
else num=y;
var n = num-rows;
var row; table1.find("tr").eq(0).clone();
while(1){
row = table1.find("tr").eq(0).clone();
table1.append(row);
n--;
if(n===0) break;
}
n = num-rows;
var td;
while(1){
td = table1.find("td").eq(0).clone();
table1.find("tr").append(td);
n--;
if(n===0) break;
}
}
var text = $("#text").val();
var css = $("#css").val();
$("table:eq(0) tr:eq(" + (x-1) + ") td:eq(" + (y-1) + ")").text(text).css("color", css);
});
table1.find("td").click(function(){
$(this).html("");
});
});
* {
font: 14px normal Arial, sans-serif;
color: #000000;
}
table {
margin: 50px auto;
}
table, td {
border: 1px solid #aaa;
border-collapse: collapse;
}
th {
padding: 10px;
font-weight: bold;
}
td {
background-color: #eeeeee;
width: 80px;
height: 80px;
}
table:first-child tr td {
cursor: pointer;
}
td[colspan="4"]{
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="4">Fill a field:</th>
</tr>
</thead>
<tbody>
<tr>
<td>Text: <br/><input type="text" id="text" value=""></td>
<td>Field X: <br/><input type="text" id="field_x" value=""></td>
<td>Field Y: <br/><input type="text" id="field_y" value=""></td>
<td>CSS: <br/><input type="text" id="css" value=""></td>
</tr>
<tr>
<td colspan="4"><button id="mybutton">Fill</button></td>
</tr>
</tbody>
</table>
What the program does is the following:
The user can choose a field by giving an x-value and a y-value. In this field the content from the input field with label "Text" is displayed.
- This part of the program works fine.
If the user chooses an x-value or a y-value larger than the current number of rows (columns), rows and columns are added until the number of rows/columns is equal to the value in the x-(or y-) field.
- This part of the program also works fine.
The only functionality that does not work is the following:
If the user clicks on one of the non-empty fields in the table, the content of the table is supposed to go back to its natural (empty) state.
To this end, the following function was added to the code (see last couple of lines in the javascript part of the code):
table1.find("td").click(function(){
$(this).html("");
});
This piece of code basically means:
If the user clicks on any box ("td") in the table, the content of this box should disappear.
This is more or less the most simple part of the code. But it's also the one aspect that doesn't work. More precisely: It works for the original boxes, but it doesn't work for any boxes that were added. - And I don't get why it behaved that way.

If you are dynamically adding elements to the DOM and expect to be attaching events to them, you should consider using event delegation via the on() function :
// This will wire up a click event for any current AND future 'td' elements
$(table1).on('click', 'td', function(){
$(this).html("");
});
Simply using click() on it's own will only wire up the necessary event handlers for elements that exist in the DOM at the time of that function being called.

You're assigning the event handlers before the user has a chance to input any data. This means that if an additional row or column is added, the new <td>s need event handlers added manually.
Alternately, you can add a single click handler to the entire table:
table1.click(function (ev) { $(ev.target).html(''); }
The ev.currentTarget property will be the <table> element because that's the element the event handler is registered to, but the ev.target property will be the <td> element that you're looking for.
Here's a JSFiddle to experiment with.

Hey there here's what I thought the answer might be,
HTML File:
<!DOCTYPE html>
<html lang="de-DE">
<head>
<meta charset="UTF-8" />
<style>
* {
font: 14px normal Arial, sans-serif;
color: #000000;
}
table {
margin: 50px auto;
}
table, td {
border: 1px solid #aaa;
border-collapse: collapse;
}
th {
padding: 10px;
font-weight: bold;
}
td {
background-color: #eeeeee;
width: 80px;
height: 80px;
}
table:first-child tr td {
cursor: pointer;
}
td[colspan="4"]{
text-align:center;
}
.pre-height {
min-height: 80px;
}
</style>
</head>
<body>
<table>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="pre-height"></td>
<td class="pre-height"></td>
<td class="pre-height"></td>
<td class="pre-height"></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="4">Fill a field:</th>
</tr>
</thead>
<tbody>
<tr>
<td>Text: <br/><input type="text" id="text" value=""></td>
<td>Field X: <br/><input type="text" id="field_x" value=""></td>
<td>Field Y: <br/><input type="text" id="field_y" value=""></td>
<td>CSS: <br/><input type="text" id="css" value=""></td>
</tr>
<tr>
<td colspan="4"><button id="myButton">Fill</button></td>
</tr>
</tbody>
</table>
<script src="jquery.min.js"></script>
<script src="jack.js"></script>
</body>
</html>
JACK.JS file:
window.onload = function() {
'use strict';
/**
* Appends 'n' number of rows to the table body.
*
* #param {Number} n - Number of rows to make.
*/
var makeRows = function(n) {
let tbody= document.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0],
tr = document.querySelector("table:first-of-type tbody tr");
for (let i = 0; i < n; i++) {
let row = Node.prototype.cloneNode.call(tr, true);
tbody.appendChild(row);
}
};
/**
* Appends 'n' number of cells to each row.
*
* #param {Number} n - Number of cells to add to each row.
*/
var makeColumns = function(n) {
let addNCells = (function(n, row) {
for (let i = 0; i < n; i++) {
let cell = Node.prototype.cloneNode.call(td, true);
row.appendChild(cell);
}
}).bind(null, n);
let tbody= document.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0],
td = document.querySelector("table:first-of-type tbody tr td"),
rows = document.querySelectorAll("table:first-of-type tbody tr");
rows.forEach(function(row) {
addNCells(row);
});
};
document.getElementById("myButton").addEventListener("click", () => {
let x = document.getElementById("field_x").value,
y = document.getElementById("field_y").value;
makeColumns(x);
makeRows(y);
});
/**
* Newly added code
*/
(function() {
let table = document.querySelector("table");
// We will add event listener to table.
table.addEventListener("click", (e) => {
e.target.innerHTML = "";
e.target.style.backgroundColor = "orange";
});
})();
};
Edit: And I didn't even answer the question completely. You might wanna attach event listener to the nearest non-dynamic parent so that click event will bubble up and you can capture that, check the code under the comment newly added code.

Related

How to create a JavaScript loop that adds DOM properties to attributes?

I have a table with cells that are not contentEditable. However, using a JavaScript loop or function, I would like to make them so.
I understand that it is very simple to do this manually for each cell, and this would probably be easier for a table with only a few cells, but I would like to quicken this process with a loop/function for the table could become much larger, and the time spent manually setting each cell to be contentEditable would be tedious.
Below is a quick example that displays a table calculator, un-editable at present. But using a loop or function, I'd like to make every cell in the right column set to .contentEditable = true in the DOM. I imagine that the parameters would look something like (var i = 0; l != rows.length; i < l; i+2), but I'm struggling with what the statements following the argument would have to be for the loop/function to work. Any help would be much appreciated!
function myFunction() {
var jack2 = document.getElementById("jack").innerText;
var john2 = document.getElementById("john").innerText;
var joe2 = document.getElementById("joe").innerText;
var total2 = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);
document.getElementById("total").innerHTML = total2;
}
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
Get all cell in the tabel that have a left neigbour (the header is not effected because there are th and not td). Add to each of these cells your attribute.
Edited: For getting the totalsum add an eventlistener on each td that calls the calc-function if the content changes.
function myFunction() {
let weightCells = document.querySelectorAll("table tr:not(:last-child) td ~ td");
weightCells.forEach(td => {
td.setAttribute('contentEditable', true);
td.addEventListener ("change", calcSum());
});
}
function calcSum() {
let sum=0;
let weightCells = document.querySelectorAll("table tr td ~ td");
let count = weightCells.length-1;
for (i=0; i<count; i++) {
sum += parseInt(weightCells[i].innerHTML) || 0;
}
weightCells[count].innerHTML = sum;
}
myFunction();
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
You can select the whole table, then use querySelectorAll to get all rows then for each rows change the contenteditable for the second td like this
codepen
let table = document.getElementById('table')
let rows = table.querySelectorAll('tr')
rows.forEach(row => {
let tds = row.querySelectorAll('td')
// all the cells of the row
if (tds.length > 0) { // if it is not the header
tds[1].contentEditable = true
// change the contenteditable
}
})
(you need to add an id to your table in case you have more than one table)
<table id="table">
...
</table>

Is there a way of obtaining the value of the TH when hoovering over a TD in a table on HTML? [duplicate]

This question already has answers here:
How can I get the corresponding table header (th) from a table cell (td)?
(6 answers)
Closed 4 years ago.
I am trying to obtain the value of a TH after hoovering over its TD. I am able to obtain the value of the TD data cell when I hoover over it but cannot find a way to get the value for the TH.
This javascript allows me to click on the TD to obtain the entire row of values or hoover over a particular cell to get the value of it. However, I can't seem to find a way to get the TH.
$('#grid').click(function(evt) {
var row = $(evt.target).parent('tr'); // Get the parent row
var cell = $(evt.target); //Get the cell
alert('Row data: ' + row.text());
alert('Cell data: ' + cell.text());
});
$('#grid').on('mouseenter', 'td', function() {
console.log($(this).text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<div id="grid">
<table id="table1" border="1">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr>
<td>101</td>
<td>Jackie</td>
</tr>
<tr>
<td>102</td>
<td>Thomas</td>
</tr>
</tbody>
</table>
Rather than using javascript or jquery to traverse the DOM to find the th involved- you could use a HTML5 data-attribute and set the vvalue for each td - then show that on the click (here i am consoling it for the snippet).
$('#table td').on('click', function() {
let col = $(this).attr('data-col');
let content = $(this).text();
console.log(col + ": " + content);
});
table {
border-collapse: collapse;
}
th {
border: solid 1px #d4d4d4;
border-bottom-width: 2px;
padding: 5px 10px
}
td {
border: solid 1px #d4d4d4;
padding: 5px 10px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr>
<td data-col="ID">101</td>
<td data-col="Name">Jackie</td>
</tr>
<tr>
<td data-col="ID">102</td>
<td data-col="Name">Thomas</td>
</tr>
</tbody>
</table>
Alternatively - you could have an array of the th contents (espescially if you create the table dynamically) - then on the click of the td - get its index in its tr (again you could store this in a data-attribute - or as an id - then use that index to reference the array.
This ouwl be the better method use an array or object to create the table dynamically and then you already have the data source to reference the content from.
var columns = ['ID','Name'];
$('#table td').on('click', function() {
let index = parseInt($(this).attr('data-index'));
let col = columns[index];
let content = $(this).text();
console.log(col + ": " + content);
});
table {
border-collapse: collapse;
}
th {
border: solid 1px #d4d4d4;
border-bottom-width: 2px;
padding: 5px 10px
}
td {
border: solid 1px #d4d4d4;
padding: 5px 10px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr>
<td data-index='0'>101</td>
<td data-index='1'>Jackie</td>
</tr>
<tr>
<td data-index='0'>102</td>
<td data-index='1'>Thomas</td>
</tr>
</tbody>
</table>
Based on thread linked in the comments, Ive created below code.
This console logs the text value of the TH and the value of the TD on mouseover.
$('#grid').click(function(evt) {
var row = $(evt.target).parent('tr'); // Get the parent row
var cell = $(evt.target); //Get the cell
alert('Row data: ' + row.text());
alert('Cell data: ' + cell.text());
});
$('#grid').on('mouseenter', 'td', function() {
var $td = $(this),
$th = $td.closest('table').find('th').eq($td.index());
console.log($th.text() + ": " + $td.text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="grid">
<table id="table1" border="1">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr>
<td>101</td>
<td>Jackie</td>
</tr>
<tr>
<td>102</td>
<td>Thomas</td>
</tr>
</tbody>
</table>
</div>
Find child-index-number of the td element under the tr element.
Find the th element by index.
//Find table
var table = document.getElementById('table');
//Hover event callback
function hoverTDEvent(evt) {
//Only run on td
if (evt.target.nodeName.toLowerCase() != 'td') {
return false;
}
//Find relative index
var index = Array.prototype.slice.call(evt.target.parentNode.children).indexOf(evt.target);
//Find th by index and log contents
console.log(table.querySelectorAll("th")[index].textContent,evt.target.textContent);
}
//Bind event
table.addEventListener("mousemove", hoverTDEvent);
<table id="table" border="1">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr>
<td>101</td>
<td>Jackie</td>
</tr>
<tr>
<td>102</td>
<td>Thomas</td>
</tr>
</tbody>
</table>
Notice that this wont work if you use the colspan property.

Duplicate all Column Cell Input Values with first Column Cell input value

I have an html table that is wrapped by a form with each cell having an input element in it.
I was wondering if there is a way to obtain the first cell's input value of a particular column and pasting that value in the rest of the cells in that column. In other words, the user will type into the input field of first cell and then click on button to duplicate that entry into the rest of the cells of that column.
Assuming you have a table with a button on each row, give the button a class so that it can have an event assigned:
<button type='button' class='copybtn'>copy</button>
don't use IDs as you need multiple buttons;
$(".copybtn").click(function() {
You can get the button's column using var col = $(this).closest("td").index() (add 1 as .index() is 0-based, but we need 1-based :nth-child).
Get the column cells using:
var cells = $("table").find("tr > td:nth-child(" + col + ")");
Various ways to handle this - eg get all the cells as above, then get the first for the input and last for the button or get the input from the first row's nth-child (as in the snippet)
To get the value: var val = inp.val()
To copy the values, depends on your HTML, you could give each destination cell a class then:
cells.find("td.dest").text(val);
or you can get all cells and exclude first/last:
tbl.find("tr:not(:first):not(:last) > td:nth-child(" + col + ")").text(val);
Altogether:
$(".copybtn").click(function() {
// get 0-based column index
var col = $(this).closest("td").index() + 1;
var tbl = $(this).closest("table");
var val = tbl.find("tr:first td:nth-child(" + col + ")").find("input").val();
tbl.find("tr:not(:first):not(:last) > td:nth-child(" + col + ")").text(val);
});
input {
width: 50px;
}
td {
min-width: 20px;
border: 1px solid #CCC;
margin: 0;
padding: 5px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id='t'>
<tbody>
<tr>
<td><input type='text' class='inp' /></td>
<td><input type='text' class='inp' /></td>
<td><input type='text' class='inp' /></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><button type='button' class='copybtn'>copy</button></td>
<td><button type='button' class='copybtn'>copy</button></td>
<td><button type='button' class='copybtn'>copy</button></td>
</tr>
</tbody>
</table>
If I understand correctly, you'll need something like this:
const copy=(id) => {
var value = document.getElementById("col"+id+"-input").value
var list = document.getElementsByClassName("col"+id+"-input")
for (i = 0; i < list.length; i++)
list[i].value = value
}
document.getElementById("col1-button").addEventListener("click", ()=>copy(1))
document.getElementById("col2-button").addEventListener("click", ()=>copy(2))
document.getElementById("col3-button").addEventListener("click", ()=>copy(3))
<table>
<tr>
<td><input id="col1-input" class="col1-input"><button id="col1-button">OK</button><br>
<td><input class="col1-input"></td>
<td><input class="col1-input"></td>
<td><input class="col1-input"></td>
<td><input class="col1-input"></td>
</tr>
<tr>
<td><input id="col2-input" class="col2-input"><button id="col2-button">OK</button><br>
<td><input class="col2-input"></td>
<td><input class="col2-input"></td>
<td><input class="col2-input"></td>
<td><input class="col2-input"></td>
</tr>
<tr>
<td><input id="col3-input" class="col3-input"><button id="col3-button">OK</button><br>
<td><input class="col3-input"></td>
<td><input class="col3-input"></td>
<td><input class="col3-input"></td>
<td><input class="col3-input"></td>
</tr>
</table>
Try this... JQuery solution.
Good luck!
$(function() {
$('button').on('click', function() {
var inputVal = $(this).prev().val();
// Plus one because arrays start at zero
var colIndex = $(this).parent().parent().children().index($(this).parent()) + 1;
$('table tr td:nth-child('+colIndex+')').not(':first')
.html(inputVal);
});
});
body { margin: 10px; }
table { max-width: 600px; }
td { min-width: 280px; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="">
<table class="table table-bordered">
<tr>
<td><input type="text"><button type="button">Copy</button></td>
<td><input type="text"><button type="button">Copy</button></td>
<td><input type="text"><button type="button">Copy</button></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</form>

How to get value of nextsibling if element search by specific string?

I am trying to get the text which is in the next element of searched element by string.Let me explain by code
<table id="myTable">
<tbody>
<tr>
<th>Name</th>
<td>foo</td>
</tr>
<tr>
<th>age</th>
<td>20</td>
</tr>
</tbody>
</table>
I have to search string if "age" exist. then return 20 as its value.
I tried to search string by contains: But unable to access value
You could use jQuery next() and contains selector to achieve what you need.
$(document).ready(function() {
console.log($("th:contains(age)").next().html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<th>Name</th>
<td>foo</td>
</tr>
<tr>
<th>age</th>
<td>20</td>
</tr>
</tbody>
</table>
This solution will go through all the elements that are children of trs and check to see that their text is equal to the search. If it is equal, it assigns the next element to nextElem.
let search = "age";
let nextElem;
$('#myTable tr').children().each(function() {
if ($(this).text() === search)
nextElem = $(this).next();
});
console.log(nextElem.text())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<th>Name</th>
<td>foo</td>
</tr>
<tr>
<th>age</th>
<td>20</td>
</tr>
</tbody>
</table>
You've already set up the table to display name-value pairs, where each name is contained within <th>...</th> and its corresponding value is contained within <td>...</td>.
So one approach to this is straightforward Document Object Model navigation, using:
getElementsByTagName('th')
getElementsByTagName('td')
var table = document.getElementsByTagName('table')[0];
var button = document.getElementsByTagName('button')[0];
var summary = document.getElementsByClassName('summary')[0];
var searchedFor = summary.getElementsByTagName('p')[0];
var correspondingResult = summary.getElementsByTagName('p')[1];
function displayResult() {
var returnValue = '';
var searchString = document.getElementsByTagName('input')[0].value;
var lowerCaseSearchString = searchString.toLowerCase();
var tableRows = document.getElementsByTagName('tr');
for (var i = 0; i < tableRows.length; i++) {
var name = tableRows[i].getElementsByTagName('th')[0].textContent.toLowerCase();
if (name === lowerCaseSearchString) {
returnValue = tableRows[i].getElementsByTagName('td')[0].textContent;
}
if (returnValue === '') {
returnValue = 'No Matches';
}
}
searchedFor.textContent = 'You searched for... ' + '"' + searchString + '"';
correspondingResult.textContent = 'The corresponding result is... ' + '"' + returnValue + '"';
}
button.addEventListener('click',displayResult,false);
table, .search-panel {
display: inline-block;
vertical-align: top;
margin-right: 24px;
}
table {
border: 2px solid rgb(127,127,127);
}
th, td {
padding: 12px;
}
th {
text-align: left;
background-color: rgb(191,191,191);
}
th::after {
content:':';
}
.search-results p span {
font-weight:bold;
}
<table>
<tbody>
<tr>
<th>Name</th>
<td>Foo</td>
</tr>
<tr>
<th>Age</th>
<td>20</td>
</tr>
</tbody>
</table>
<div class="search-panel">
<form>
<input type="text" placeholder="Enter your string here..." value="" />
<button type="button">Search for String</button>
</form>
<div class="summary">
<p>You searched for... </p>
<p>The corresponding result is... </p>
</div>
</div>

Moving an Array to the next row in a Table

I am trying to get the following code to get variable round2players to be randomly assigned to the 2nd row in the table, here is my code so far:
var x = 0, //starting column Index
cells = document.getElementsByTagName('td')
round1players = ['Forrest Gump', 'Tim Thomas', 'Pamila Henryson', 'Lotus Hobbes', 'Jerry Sparks', 'Kenneth Ingham'];
round2players = ['Cyril Willard', 'Gale Frank', 'Aveline Derricks', 'Darcey Bullock', 'Jaiden Deering', 'Glenn Benn'];
function myFunction(round1playersArray)
{
var round1names = round1playersArray.slice(0);
while (round1names.length > 0 && x < cells.length) {
var randomIndex = Math.floor(Math.random()*round1names.length);
cells[x].innerHTML = round1names[randomIndex];
x++;
round1names.splice(randomIndex, 1);
}
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 75%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
text-align: center
}
tr:nth-child(even) {
background-color: #dddddd;
}
<!DOCTYPE html>
<html>
<body>
<table align=center>
<tr>
<th>Black</th>
<th>Blue</th>
<th>B & B</th>
<th>Ex-Tm #1</th>
<th>Ex-Tm #2</th>
<th>Gryphons</th>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<div style="padding:25px" align=center>
<button type="button" onclick="myFunction(round1players)">Simulate to next round</button>
</div>
</body>
</html>
Group your arrays in another array. Now you have an array of arrays or multidimensional array. Multidimensional arrays are great for tables. Renamed the arrays because I hate typing long names. Details are commented in Snippet.
Snippet
var round1 = ['Forrest Gump', 'Tim Thomas', 'Pamila Henryson', 'Lotus Hobbes', 'Jerry Sparks', 'Kenneth Ingham'];
var round2 = ['Cyril Willard', 'Gale Frank', 'Aveline Derricks', 'Darcey Bullock', 'Jaiden Deering', 'Glenn Benn'];
/* game is a multidimensional array.
| Each element is an array(sub-array).
| Each sub-array is a row in a table.
| Each element of a sub-array is a cell.
*/
var game = [round1, round2];
// count will be incremented per click of button
var count = 0;
function rounds(n, obj) {
// Determine which sub-array to use
var array = obj[n - 1];
// Determine the specific <tr>
var row = 'tr:nth-of-type(' + n + ')';
// Reference each <td> cell of the <tr> row
var cells = document.querySelectorAll('tbody ' + row + ' td');
// Cell count
var x = 0;
// Separate each element of sub-array
array = array.slice(0);
// while loop establishes limits and iteration
while (array.length > 0 && x < cells.length) {
// Get a randomly generated number
var randomIndex = Math.floor(Math.random() * array.length);
/* On each iteration...
| ...insert the element of sub-array...
| ...that was determined by a randomly...
| ...generated index number.
*/
cells[x].innerHTML = array[randomIndex];
// Increment cell count
x++;
// Join each cell together in it's new order
array.splice(randomIndex, 1);
}
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 75%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
text-align: center
}
tr:nth-child(even) {
background-color: #dddddd;
}
<!DOCTYPE html>
<html>
<body>
<table align=center>
<thead>
<tr>
<th>Black</th>
<th>Blue</th>
<th>B & B</th>
<th>Ex-Tm #1</th>
<th>Ex-Tm #2</th>
<th>Gryphons</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<div style="padding:25px" align=center>
<!-- This button's attribute event has a incremental counter, so each successive click will change the count parameter -->
<button type="button" onclick="count++;rounds(count, game)">Simulate to next round</button>
</div>
</body>
</html>

Categories

Resources