Compare items in an array against table items in JavaScript, Beginner - javascript

I created a really basic table with 20 numbers inside. I have then bodged together a system which creates an array of 20 numbers and shuffles it, there is then a button which displays one position of the array at a time.
What I want to do, which I haven't been able to figure out yet, is to use the number that has been generated to change to background color of that same number in the table. So if I drew the number 20 it would be marked on the table.
Please could you respond with JavaScript only as jQuery is still a little unknown at the moment.
// This bit shuffles an array
function shuffle(array) {
var i = array.length,
j = 0,
temp;
while (i--) {
j = Math.floor(Math.random() * (i+1));
// swap randomly chosen element with current element
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
// Array input
var ranNums = shuffle([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]);
//This bit calls the position of the array
var f = 0; // the index of the current item to show
function nextNumber() {
document
.getElementById('test')
.innerHTML = ranNums[f++]; // get the item and increment
if (f == ranNums.length) f = 0; // reset to first element if you've reached the end
}
body {
background-color: white;
color: black;
font-size: 20px;
font-family: "Lucida Grande", Verdana,Arial, Helvetica, sans-serif;
}
h1, th {
font-family: Georgia, "Times New Roman",Times, serif;
}
h1 {
font-size: 28px;
}
table {
border-collapse: separate;
border-spacing: 30px;
float: left;
}
th, td {
padding: 30px;
border: 2px black solid;
text-align: center;
width: 20%;
}
h2 {
}
button {
}
#item20 {
background-color: red;
}
<h1>Bingo!</h1>
<h2 id="test"></h2>
<table>
<tr>
<td id="item1"<h1>1</h1></td>
<td id="item2"<h1>2</h1></td>
<td id="item3"<h1>3</h1></td>
<td id="item4"<h1>4</h1></td>
<td id="item5"<h1>5</h1></td>
</tr>
<tr>
<td id="item6"<h1>6</h1></td>
<td id="item7"<h1>7</h1></td>
<td id="item8"<h1>8</h1></td>
<td id="item9"<h1>9</h1></td>
<td id="item10"<h1>10</h1></td>
</tr>
<tr>
<td id="item11"<h1>11</h1></td>
<td id="item12"<h1>12</h1></td>
<td id="item13"<h1>13</h1></td>
<td id="item14"<h1>14</h1></td>
<td id="item15"<h1>15</h1></td>
</tr>
<tr>
<td id="item16"<h1>16</h1></td>
<td id="item17"<h1>17</h1></td>
<td id="item18"<h1>18</h1></td>
<td id="item19"<h1>19</h1></td>
<td id="item20"<h1>20</h1></td>
</tr>
</table>
<button onclick="nextNumber()">Next Number</button>

Change your nextNumber method to also highlight the new random number selected
function nextNumber() {
var number = ranNums[f];
f++;
document.getElementById('test').innerHTML = number;
document.getElementById("item" + number).style.backgroundColor = "red";
if (f == ranNums.length) f = 0; // reset to first element if you've reached the end
}
Demo
// This bit shuffles an array
function shuffle(array) {
var i = array.length,
j = 0,
temp;
while (i--) {
j = Math.floor(Math.random() * (i + 1));
// swap randomly chosen element with current element
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
// Array input
var ranNums = shuffle([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);
//This bit calls the position of the array
var f = 0; // the index of the current item to show
function nextNumber() {
var number = ranNums[f];
f++;
document.getElementById('test').innerHTML = number;
document.getElementById("item" + number).style.backgroundColor = "red";
if (f == ranNums.length) f = 0; // reset to first element if you've reached the end
}
body {
background-color: white;
color: black;
font-size: 20px;
font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
}
h1,
th {
font-family: Georgia, "Times New Roman", Times, serif;
}
h1 {
font-size: 28px;
}
table {
border-collapse: separate;
border-spacing: 30px;
float: left;
}
th,
td {
padding: 30px;
border: 2px black solid;
text-align: center;
width: 20%;
}
h2 {}
button {}
#item20 {
background-color: red;
}
<h1>Bingo!</h1>
<h2 id="test"></h2>
<table>
<tr>
<td id="item1" <h1>1</h1>
</td>
<td id="item2" <h1>2</h1>
</td>
<td id="item3" <h1>3</h1>
</td>
<td id="item4" <h1>4</h1>
</td>
<td id="item5" <h1>5</h1>
</td>
</tr>
<tr>
<td id="item6" <h1>6</h1>
</td>
<td id="item7" <h1>7</h1>
</td>
<td id="item8" <h1>8</h1>
</td>
<td id="item9" <h1>9</h1>
</td>
<td id="item10" <h1>10</h1>
</td>
</tr>
<tr>
<td id="item11" <h1>11</h1>
</td>
<td id="item12" <h1>12</h1>
</td>
<td id="item13" <h1>13</h1>
</td>
<td id="item14" <h1>14</h1>
</td>
<td id="item15" <h1>15</h1>
</td>
</tr>
<tr>
<td id="item16" <h1>16</h1>
</td>
<td id="item17" <h1>17</h1>
</td>
<td id="item18" <h1>18</h1>
</td>
<td id="item19" <h1>19</h1>
</td>
<td id="item20" <h1>20</h1>
</td>
</tr>
</table>
<button onclick="nextNumber()">Next Number</button>

You could clean this up a bit, but this one uses a red class. The key is to target the box using document.getElementById("item" + randNum).className = "red";
I have added a resetNumbers() function and button to reset your classes. This is to display the reason why I chose to use a class. Originally I had it resetting after every button click, but if this is BINGO, that probably is not desired. I commented out where I was doing this, but you can still reset.
I prefer this to setting the background colour, as this is controlled through a css class instead, which is easier to manage.
// This bit shuffles an array
function shuffle(array) {
var i = array.length,
j = 0,
temp;
while (i--) {
j = Math.floor(Math.random() * (i+1));
// swap randomly chosen element with current element
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
// Array input
var ranNums = shuffle([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]);
//This bit calls the position of the array
var f = 0; // the index of the current item to show
function nextNumber() {
var randNum = ranNums[f++];
document.getElementById('test').innerHTML = randNum; // get the item and increment
if (f == ranNums.length) f = 0; // reset to first element if you've reached the end
//resetNumbers();//uncomment if you do not want to reset - or remove if you never want this here
document.getElementById("item" + randNum).className = "red";
}
function resetNumbers() {
for (var i = 0; i < ranNums.length; i++) {
document.getElementById("item" + ranNums[i]).className = "";
}
}
body {
background-color: white;
color: black;
font-size: 20px;
font-family: "Lucida Grande", Verdana,Arial, Helvetica, sans-serif;
}
h1, th {
font-family: Georgia, "Times New Roman",Times, serif;
}
h1 {
font-size: 28px;
}
table {
border-collapse: separate;
border-spacing: 30px;
float: left;
}
th, td {
padding: 30px;
border: 2px black solid;
text-align: center;
width: 20%;
}
.red {
background-color: red;
}
<h1>Bingo!</h1>
<h2 id="test"></h2>
<table>
<tr>
<td id="item1"<h1>1</h1></td>
<td id="item2"<h1>2</h1></td>
<td id="item3"<h1>3</h1></td>
<td id="item4"<h1>4</h1></td>
<td id="item5"<h1>5</h1></td>
</tr>
<tr>
<td id="item6"<h1>6</h1></td>
<td id="item7"<h1>7</h1></td>
<td id="item8"<h1>8</h1></td>
<td id="item9"<h1>9</h1></td>
<td id="item10"<h1>10</h1></td>
</tr>
<tr>
<td id="item11"<h1>11</h1></td>
<td id="item12"<h1>12</h1></td>
<td id="item13"<h1>13</h1></td>
<td id="item14"<h1>14</h1></td>
<td id="item15"<h1>15</h1></td>
</tr>
<tr>
<td id="item16"<h1>16</h1></td>
<td id="item17"<h1>17</h1></td>
<td id="item18"<h1>18</h1></td>
<td id="item19"<h1>19</h1></td>
<td id="item20"<h1>20</h1></td>
</tr>
</table>
<button onclick="nextNumber()">Next Number</button>
<button onclick="resetNumbers()">Reset Numbers</button>

Related

Random group with fixed match

I'm making a random group for an one-on-one debate, there are 16 people divided into 8 teams, and they will be assigned with 8 random topics as well as random sides(AFF & NEG).
Below is the part I used to generate random teams, the match will be held on am and pm so 8 per round.
For some reason we need two of them to be always in a match. I can't seem to do this in a logical way. I.E. Jerry Lin always debates with Sammy Singh, sides can change. Thanks in advance.
var team = [
"Sandra Tom*",
"Jerry Lin*",
"Josh Renaud*",
"Katie Bostian",
"Sammy Singh",
"Nader Shehayed*",
"Joseph Tu*",
"James Kim"
];
var text = "";
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
var randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
var temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
function shuffler() {
shuffle(team);
document.getElementById("player-0").innerHTML = team[0];
document.getElementById("player-1").innerHTML = team[1];
document.getElementById("player-2").innerHTML = team[2];
document.getElementById("player-3").innerHTML = team[3];
document.getElementById("player-4").innerHTML = team[4];
document.getElementById("player-5").innerHTML = team[5];
document.getElementById("player-6").innerHTML = team[6];
document.getElementById("player-7").innerHTML = team[7];
}
// var myInterval = setInterval(shuffler, 50);
// clearInterval(myInterval);
document.getElementById("random").addEventListener("click", shuffler);
window.addEventListener("keypress", checkKeyPressed, false);
function checkKeyPressed(e) {
if (e.charCode == "32") {
document.getElementById("random").addEventListener("click", shuffler);
}
}
body {
background-color: #232323;
}
#team {
box-shadow: 0px 0px 50px rgba(255,255,255,.25);
}
#team td {
height: 75px;
width: 300px;
text-align: center;
font-family: Helvetica, Arial, san-serif;
text-transform: uppercase;
font-weight: bold;
background-color: #000000;
color: #ffffff;
font-size: 24px;
padding: 0px;
}
#team .title {
height: 30px;
font-size: 16px;
}
#team .blue {
background-color: dodgerblue;
}
#team .red {
background-color: tomato;
}
#team .green {
background-color: olive;
}
#team .orange {
background-color: orange;
}
#team .grey {
background-color: #686868;
}
.fade {
opacity: 1;
transition: opacity .1s ease-in-out;
-moz-transition: opacity .1s ease-in-out;
-webkit-transition: opacity .1s ease-in-out;
}
<table align="center" id="team" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" class="title">
Team 1
</td>
</tr>
<tr>
<td id="player-0" class="blue"></td>
<td id="player-1" class="blue"></td>
</tr>
<tr>
<td colspan="2" class="title">
Team 2
</td>
</tr>
<tr>
<td id="player-2" class="red"></td>
<td id="player-3" class="red"></td>
</tr>
<tr>
<td colspan="2" class="title">
Team 3
</td>
</tr>
<tr>
<td id="player-4" class="green"></td>
<td id="player-5" class="green"></td>
</tr>
<tr>
<td colspan="2" class="title">
Team 4
</td>
</tr>
<tr>
<td id="player-6" class="orange"></td>
<td id="player-7" class="orange"></td>
</tr>
</table>
<table width="600" align="center">
<tr>
<td colspan="2" align="center">
<button id="random">RANDOM</button>
</td>
</tr>
</table>
Update:Snippet attached.
To clarify the question.
We want Jerry Lin always debates with Sammy Singh. 8 topics divided into am and pm, 16 people divided into 8 groups for those 8, all unique.
Define the two people who are always on the same team, then hack the shuffled team list. Check my solution below:
var team = [
"Sandra Tom*",
"Jerry Lin*",
"Josh Renaud*",
"Katie Bostian",
"Sammy Singh",
"Nader Shehayed*",
"Joseph Tu*",
"James Kim"
];
var text = "";
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
var randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
var temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
function hack(array, p1, p2){
var p1Index = array.indexOf(p1);
var p2Index = array.indexOf(p2);
if(p1Index % 2 === 0){
var temp = array[p1Index+1]
array[p1Index+1] = array[p2Index]
} else {
var temp = array[p1Index-1]
array[p1Index-1] = array[p2Index]
}
array[p2Index] = temp
return array
}
function shuffler() {
var shuffled = shuffle(team)
var hacked = hack(shuffled, "Jerry Lin*", "Sammy Singh")
var final = hacked
document.getElementById("player-0").innerHTML = final[0];
document.getElementById("player-1").innerHTML = final[1];
document.getElementById("player-2").innerHTML = final[2];
document.getElementById("player-3").innerHTML = final[3];
document.getElementById("player-4").innerHTML = final[4];
document.getElementById("player-5").innerHTML = final[5];
document.getElementById("player-6").innerHTML = final[6];
document.getElementById("player-7").innerHTML = final[7];
}
// var myInterval = setInterval(shuffler, 50);
// clearInterval(myInterval);
document.getElementById("random").addEventListener("click", shuffler);
window.addEventListener("keypress", checkKeyPressed, false);
function checkKeyPressed(e) {
if (e.charCode == "32") {
document.getElementById("random").addEventListener("click", shuffler);
}
}
body {
background-color: #232323;
}
#team {
box-shadow: 0px 0px 50px rgba(255,255,255,.25);
}
#team td {
height: 75px;
width: 300px;
text-align: center;
font-family: Helvetica, Arial, san-serif;
text-transform: uppercase;
font-weight: bold;
background-color: #000000;
color: #ffffff;
font-size: 24px;
padding: 0px;
}
#team .title {
height: 30px;
font-size: 16px;
}
#team .blue {
background-color: dodgerblue;
}
#team .red {
background-color: tomato;
}
#team .green {
background-color: olive;
}
#team .orange {
background-color: orange;
}
#team .grey {
background-color: #686868;
}
.fade {
opacity: 1;
transition: opacity .1s ease-in-out;
-moz-transition: opacity .1s ease-in-out;
-webkit-transition: opacity .1s ease-in-out;
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Random Team Generator</title>
<!-- <link rel="stylesheet" href="./style.css"> -->
</head>
<body>
<!-- partial:index.partial.html -->
<body>
<table align="center" id="team" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2" class="title">
Team 1
</td>
</tr>
<tr>
<td id="player-0" class="blue"></td>
<td id="player-1" class="blue"></td>
</tr>
<tr>
<td colspan="2" class="title">
Team 2
</td>
</tr>
<tr>
<td id="player-2" class="red"></td>
<td id="player-3" class="red"></td>
</tr>
<tr>
<td colspan="2" class="title">
Team 3
</td>
</tr>
<tr>
<td id="player-4" class="green"></td>
<td id="player-5" class="green"></td>
</tr>
<tr>
<td colspan="2" class="title">
Team 4
</td>
</tr>
<tr>
<td id="player-6" class="orange"></td>
<td id="player-7" class="orange"></td>
</tr>
</table>
<table width="600" align="center">
<tr>
<td colspan="2" align="center">
<button id="random">RANDOM</button>
</td>
</tr>
</table>
</body>
<!-- partial -->
<!-- <script src="./script.js"></script> -->
</body>
</html>
Based on your comments:
var team = [
["Sandra Tom*","Jerry Lin*"],
["Josh Renaud*","Katie Bostian"],
["Sammy Singh","Nader Shehayed*"],
["Joseph Tu*","James Kim"]
];
var text = "";
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
var randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
var temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
function shuffler() {
shuffle(team);
document.getElementById("player-0").innerHTML = team[0][0];
document.getElementById("player-1").innerHTML = team[0][1];
document.getElementById("player-2").innerHTML = team[1][0];
document.getElementById("player-3").innerHTML = team[1][1];
document.getElementById("player-4").innerHTML = team[2][0];
document.getElementById("player-5").innerHTML = team[2][1];
document.getElementById("player-6").innerHTML = team[3][0];
document.getElementById("player-7").innerHTML = team[3][1];
}

How to make a partially un-editable table cell compatible with inline JavaScript functions?

So, a few days ago, I posted this question (nearly identical) and received a very helpful response.
However, in order to make a table calculator, I already have a id set to every table row of a certain column to turn the table into a calculator, which kind of messes up the answer for the original question when I try to apply it for myself (the JavaScript parses the unit "kg" in with the number and displays a sum as "NaN").
As well, there is a visible text box displayed inside of every cell with the answer above, which looks kind of ugly. My current code has cells that don't appear as text boxes but are still editable, which makes for a much sleeker experience in my opinion (I know it makes no functional difference, but the appearance is something that bugs me a lot!)
Below is a mock-up of what I'd like the code to look like. I'm trying to make the numbers/input appear on the right side of the text box, but still on the left side of the unit ("kg").
Below is a mock-up of what I am trying to create (except the numbers would be on the right).
Here is the code I have:
<head>
<style>
table {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial, sans-serif;
margin: 5px;
width: 100%;
}
th, td {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial, sans-serif;
margin: 5px;
padding: 5px;
}
</style>
</head>
<body>
<table>
<tr>
<th>header1</th>
<th>header2</th>
</tr>
<tr>
<td>entry1</td>
<td id="entry1" oninput="myFunction()">4000</td>
</tr>
<tr>
<td>entry2</td>
<td id="entry2" oninput="myFunction()">200</td>
</tr>
<tr>
<td>Total</td>
<td id="total"></td>
</tr>
</table>
<script type="text/javascript">
document.getElementById("entry1").contentEditable = true;
document.getElementById("entry2").contentEditable = true;
function myFunction() {
var entry1 = document.getElementById("entry1").innerText;
var entry2 = document.getElementById("entry2").innerText;
var total2 = parseInt(entry1) + parseInt(entry2);
document.getElementById("total").innerHTML = total2;
}
myFunction();
</script>
</body>
As you can see, it adds up the numbers in the right column and displays a sum in the final row. However, I would like units to display here (e.g. "kg") on the side, that aren't editable and, more importantly, don't get parsed as a number in the JavaScript function. Would be great if the ugly textbox outline doesn't appear inside the cell, too.
Is this possible? Any answers appreciated!
You get NaN when you call parseInt on an empty string. To fix this, change following statement from
var total = parseInt(jack2) + parseInt(john2) + parseInt (joe2);
to
var total = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt (joe2) || 0);
and to display the unit alongside the number in the right column, add 2 span elements inside the td element and use flexbox to align them properly.
To make the number editable, add contentEditable attribute on the span element containing the number. span element containing the unit will be non-editable by default.
function myFunction() {
var jack2 = document.getElementById("jack").innerText;
var john2 = document.getElementById("john").innerText;
var joe2 = document.getElementById("joe").innerText;
var total = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);
document.getElementById("total").innerHTML = total;
}
myFunction();
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial, sans-serif;
margin: 5px;
}
th,
td {
padding: 5px;
}
td:last-child {
display: flex;
justify-content: space-between;
border: none;
}
td:last-child span:first-child {
flex-grow: 1;
margin-right: 10px;
outline: none;
text-align: right;
}
#total {
display: flex;
justify-content: flex-end;
}
<table>
<thead>
<tr>
<th>Person</th>
<th>Weight</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jack</td>
<td id="jack" oninput="myFunction()">
<span contentEditable="true">4</span>
<span>Kg</span>
</td>
</tr>
<tr>
<td>John</td>
<td id="john" oninput="myFunction()">
<span contentEditable="true">2</span>
<span>Kg</span>
</td>
</tr>
<tr>
<td>Joe</td>
<td id="joe" oninput="myFunction()">
<span contentEditable="true">3</span>
<span>Kg</span>
</td>
</tr>
<tr>
<td>Total</td>
<td id="total"></td>
</tr>
</tbody>
</table>
To avoid the result being "NAN", an if is added and we check the one of the seals is empty '' and replace it with a 0.
In the edit cell two divs are added one to edit the value and the other to add the text "kg".
<style>
table {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial, sans-serif;
margin: 5px;
width: 100%;
}
th, td {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial, sans-serif;
margin: 5px;
padding: 5px;
}
.input_{
width: 90%;
float: left;
}
.peso{
width: 10%;
float: right;
}
</style>
<table>
<tr>
<th>Person</th>
<th>Weight</th>
</tr>
<tr>
<td>Jack</td>
<td>
<div class="input_" id="jack" oninput="myFunction()">1</div>
<div class="peso">kg</div>
</td>
</tr>
<tr>
<td>John</td>
<td>
<div class="input_" id="john" oninput="myFunction()">2</div>
<div class="peso">kg</div>
</td>
</tr>
<tr>
<td>Joe</td>
<td>
<div class="input_" id="joe" oninput="myFunction()">3</div>
<div class="peso">kg</div>
</td>
</tr>
<tr>
<td>Total</td>
<td id="total"></td>
</tr>
</table>
<script type="text/javascript">
document.getElementById("jack").contentEditable = true;
document.getElementById("john").contentEditable = true;
document.getElementById("joe").contentEditable = true;
function myFunction() {
var jack2 = document.getElementById("jack").innerText;
var john2 = document.getElementById("john").innerText;
var joe2 = document.getElementById("joe").innerText;
if(jack2==""){
jack2=0;
}
if(john2==""){
john2=0;
}
if(joe2==""){
joe2=0;
}
var total2 = parseInt(jack2) + parseInt(john2) + parseInt (joe2);
document.getElementById("total").innerHTML = total2+" kg";
}
myFunction();
</script>

How to add a number dynamically with Javascript to the first cell

I'm learning Javascript and i'm stuck at the moment. When the user input their first name, last name, age and clicks on the button "add", 1 new row and 4 new cells are being added to the table with the value of the users input.
My question is: how do I get the first cell to be a number? Which in this case should be number 4. If the user adds another row with value it should become number 5. etc.
If somebody could point me in a direction or show me another way to do it, that would help. Thanks! (css added just for visuals)
function allID(id) {
return document.getElementById(id);
}
function allEvents() {
allID("voegdatatoe").onclick = function () {
voegToeGegevens();
};
}
allEvents();
function voegToeGegevens() {
var formulier = allID("invoerformulier");
var nieuweGegevens = [];
for (var i = 0; i < formulier.length; i++) {
nieuweGegevens[i] = formulier.elements[i].value;
}
var uitvoertabel = allID("uitvoertabel");
var nieuweRij = uitvoertabel.insertRow(-1);
for (i = 0; i < 4; i++) {
var NieuweCell = nieuweRij.insertCell(i);
NieuweCell.innerHTML = nieuweGegevens[i];
}
}
var row = document.getElementsByClassName("rownmr");
var i = 0;
for (i = 0; i < row.length; i++) {
row[i].innerHTML = i + 1;
}
table,
th,
td {
border-collapse: collapse;
border: 1px solid black;
}
th,
td {
padding: 5px;
}
th {
text-align: left;
background-color: #c95050;
color: white;
}
.uitvoertabel {
width: 60%;
}
.uitvoertabel tr:nth-child(even) {
background-color: #eee;
}
.uitvoertabel tbody tr td:first-child {
width: 30px;
}
.invoerform {
margin-top: 50px;
width: 30%;
}
.invoerform input,
label {
display: block;
}
.invoerform label {
margin-bottom: 5px;
margin-top: 10px;
}
#voegdatatoe {
margin-top: 30px;
}
input:focus {
border: 1px solid #d45757;
outline: none;
}
<table class="uitvoertabel" id="uitvoertabel">
<thead>
<tr>
<th></th>
<th>Voornaam</th>
<th>Achternaam</th>
<th>Leeftijd</th>
</tr>
</thead>
<tbody>
<tr>
<td class="rownmr"></td>
<td>Johan</td>
<td>cruijff</td>
<td>54</td>
</tr>
<tr>
<td class="rownmr"></td>
<td>Frans</td>
<td>Bauer</td>
<td>47</td>
</tr>
<tr>
<td class="rownmr"></td>
<td>Willem</td>
<td>van Oranje</td>
<td>80</td>
</tr>
</tbody>
</table>
<form action="" id="invoerformulier" class="invoerform">
<label>Voornaam:</label>
<input type="text" name="vnaam" id="voornaam">
<label>Achternaam:</label>
<input type="text" name="anaam" id="achternaam">
<label>Leeftijd:</label>
<input type="text" name="points" id="leeftijd">
</form>
<button id="voegdatatoe">Voeg toe</button>
There are a number of ways you could store this information, from a global variable (not recommended) to some local closure, or even localStorage. But you have the information in the DOM, so it might be simplest to use it.
One way to do this would be to scan the ids, find their maximum, and add one to it. This involves a few changes to your code. First, we would add some code to scan your id cells for the largest value:
var rows = document.getElementsByClassName("rownmr");
var highestId = Math.max(...([...rows].map(row => Number(row.textContent))))
Then we would start your content array with a new value one higher than that maximum:
var nieuweGegevens = [highestId + 1];
And your loop needs to take this into account by adding one to the index
for (var i = 0; i < formulier.length; i++) {
nieuweGegevens[i + 1] = formulier.elements[i].value;
}
Finally, we need to add the right class to that new cell so that on the next call, it will continue to work:
for (i = 0; i < 4; i++) {
var NieuweCell = nieuweRij.insertCell(i);
NieuweCell.innerHTML = nieuweGegevens[i];
if (i === 0) { /**** new ****/
NieuweCell.classList.add("rownmr") /**** new ****/
} /**** new ****/
}
You can see these changes inline in this snippet:
function allID(id) {
return document.getElementById(id);
}
function allEvents() {
allID("voegdatatoe").onclick = function () {
voegToeGegevens();
};
}
allEvents();
function voegToeGegevens() {
var formulier = allID("invoerformulier");
var rows = document.getElementsByClassName("rownmr");
var highestId = Math.max(...([...rows].map(row => Number(row.textContent))))
var nieuweGegevens = [highestId + 1];
for (var i = 0; i < formulier.length; i++) {
nieuweGegevens[i + 1] = formulier.elements[i].value;
}
var uitvoertabel = allID("uitvoertabel");
var nieuweRij = uitvoertabel.insertRow(-1);
for (i = 0; i < 4; i++) {
var NieuweCell = nieuweRij.insertCell(i);
NieuweCell.innerHTML = nieuweGegevens[i];
if (i === 0) {
NieuweCell.classList.add("rownmr")
}
}
}
var row = document.getElementsByClassName("rownmr");
var i = 0;
for (i = 0; i < row.length; i++) {
row[i].innerHTML = i + 1;
}
table,
th,
td {
border-collapse: collapse;
border: 1px solid black;
}
th,
td {
padding: 5px;
}
th {
text-align: left;
background-color: #c95050;
color: white;
}
.uitvoertabel {
width: 60%;
}
.uitvoertabel tr:nth-child(even) {
background-color: #eee;
}
.uitvoertabel tbody tr td:first-child {
width: 30px;
}
.invoerform {
margin-top: 50px;
width: 30%;
}
.invoerform input,
label {
display: block;
}
.invoerform label {
margin-bottom: 5px;
margin-top: 10px;
}
#voegdatatoe {
margin-top: 30px;
}
input:focus {
border: 1px solid #d45757;
outline: none;
}
<table class="uitvoertabel" id="uitvoertabel">
<thead>
<tr>
<th></th>
<th>Voornaam</th>
<th>Achternaam</th>
<th>Leeftijd</th>
</tr>
</thead>
<tbody>
<tr>
<td class="rownmr"></td>
<td>Johan</td>
<td>cruijff</td>
<td>54</td>
</tr>
<tr>
<td class="rownmr"></td>
<td>Frans</td>
<td>Bauer</td>
<td>47</td>
</tr>
<tr>
<td class="rownmr"></td>
<td>Willem</td>
<td>van Oranje</td>
<td>80</td>
</tr>
</tbody>
</table>
<form action="" id="invoerformulier" class="invoerform">
<label>Voornaam:</label>
<input type="text" name="vnaam" id="voornaam">
<label>Achternaam:</label>
<input type="text" name="anaam" id="achternaam">
<label>Leeftijd:</label>
<input type="text" name="points" id="leeftijd">
</form>
<button id="voegdatatoe">Voeg toe</button>
Note that this will continue to work on subsequent adds.
Add additional the length+1 param in the arrays of data
function allID(id) {
return document.getElementById(id);
}
function allEvents() {
allID("voegdatatoe").onclick = function () {
voegToeGegevens();
};
}
allEvents();
function voegToeGegevens() {
var row = document.getElementsByTagName("tr");
var formulier = allID("invoerformulier");
var nieuweGegevens = [];
nieuweGegevens.push(row.length) //length param for first column
for (var i = 0; i < formulier.length; i++) {
nieuweGegevens[i+1] = formulier.elements[i].value; //saving values from i=1
}
var uitvoertabel = allID("uitvoertabel");
var nieuweRij = uitvoertabel.insertRow(-1);
for (i = 0; i < 4; i++) {
var NieuweCell = nieuweRij.insertCell(i);
NieuweCell.innerHTML = nieuweGegevens[i];
}
}
var row = document.getElementsByClassName("rownmr");
var i = 0;
for (i = 0; i < row.length; i++) {
row[i].innerHTML = i + 1;
}
table,
th,
td {
border-collapse: collapse;
border: 1px solid black;
}
th,
td {
padding: 5px;
}
th {
text-align: left;
background-color: #c95050;
color: white;
}
.uitvoertabel {
width: 60%;
}
.uitvoertabel tr:nth-child(even) {
background-color: #eee;
}
.uitvoertabel tbody tr td:first-child {
width: 30px;
}
.invoerform {
margin-top: 50px;
width: 30%;
}
.invoerform input,
label {
display: block;
}
.invoerform label {
margin-bottom: 5px;
margin-top: 10px;
}
#voegdatatoe {
margin-top: 30px;
}
input:focus {
border: 1px solid #d45757;
outline: none;
}
<table class="uitvoertabel" id="uitvoertabel">
<thead>
<tr>
<th></th>
<th>Voornaam</th>
<th>Achternaam</th>
<th>Leeftijd</th>
</tr>
</thead>
<tbody>
<tr>
<td class="rownmr"></td>
<td>Johan</td>
<td>cruijff</td>
<td>54</td>
</tr>
<tr>
<td class="rownmr"></td>
<td>Frans</td>
<td>Bauer</td>
<td>47</td>
</tr>
<tr>
<td class="rownmr"></td>
<td>Willem</td>
<td>van Oranje</td>
<td>80</td>
</tr>
</tbody>
</table>
<form action="" id="invoerformulier" class="invoerform">
<label>Voornaam:</label>
<input type="text" name="vnaam" id="voornaam">
<label>Achternaam:</label>
<input type="text" name="anaam" id="achternaam">
<label>Leeftijd:</label>
<input type="text" name="points" id="leeftijd">
</form>
<button id="voegdatatoe">Voeg toe</button>
As I note that none of the answers made, does not seem to have the approval of Niekket (no validation for anybody),
and that the question asked is accompanied by a very rough example (the author admits to being bloked in his apprenticeship), using a lot of useless code...
So I propose this complete solution, which I hope is enlightening enough on the proper way of coding its problem ( imho ).
const
TableBody_uitvoertabel = document.querySelector('#uitvoertabel > tbody'),
form_invoerformulier = document.querySelector('#invoerformulier'),
in_voornaam = document.querySelector('#voornaam'),
in_achternaam = document.querySelector('#achternaam'),
in_leeftijd = document.querySelector('#leeftijd')
;
var
RowCount = 0; // global..
// place numbers in the first column
document.querySelectorAll('#uitvoertabel > tbody > tr td:first-child').forEach(
elmTR=>{ elmTR.textContent = ++RowCount }
);
form_invoerformulier.onsubmit = function(e) {
e.preventDefault();
let
column = 0,
row = TableBody_uitvoertabel.insertRow(-1)
;
row.insertCell(column++).textContent = ++RowCount;
row.insertCell(column++).textContent = in_voornaam.value;
row.insertCell(column++).textContent = in_achternaam.value;
row.insertCell(column++).textContent = in_leeftijd.value;
this.reset();
}
table, th, td {
border-collapse: collapse;
border: 1px solid black;
}
th, td { padding: 5px; }
th {
text-align: left;
background-color: #c95050;
color: white;
}
table.uitvoertabel { width: 60%; }
table.uitvoertabel tr:nth-child(even) {
background-color: #eee;
}
table.uitvoertabel tbody tr td:first-child {
width: 30px;
}
form.invoerform {
margin-top: 50px;
width: 30%;
}
form.invoerform input,
form.invoerform label {
display: block;
}
form.invoerform label {
margin-bottom: 5px;
margin-top: 10px;
}
form.invoerform button {
margin-top: 30px;
}
form.invoerform input:focus {
border-color: #d45757;
outline: none;
}
<table class="uitvoertabel" id="uitvoertabel">
<thead>
<tr>
<th></th><th>Voornaam</th><th>Achternaam</th><th>Leeftijd</th>
</tr>
</thead>
<tbody>
<tr>
<td></td><td>Johan</td><td>cruijff</td><td>54</td>
</tr>
<tr>
<td></td><td>Frans</td><td>Bauer</td><td>47</td>
</tr>
<tr>
<td></td><td>Willem</td><td>van Oranje</td><td>80</td>
</tr>
</tbody>
</table>
<form id="invoerformulier" class="invoerform">
<label>Voornaam:</label>
<input type="text" name="vnaam" id="voornaam">
<label>Achternaam:</label>
<input type="text" name="anaam" id="achternaam">
<label>Leeftijd:</label>
<input type="text" name="points" id="leeftijd">
<button type="submit">Voeg toe</button>
<button type="reset">Reset</button>
</form>
I think that the main issue is that you only manually set the rownmrs for the first time from line var row = document.getElementsByClassName("rownmr");
rather than every time you click on the "Voeg toe" button.
Ideally, for your hard coded numbers, they would be in the markup and the logic to grab the next rownmr to display and the adding of that cell happens on click.
html
<table class="uitvoertabel" id="uitvoertabel">
<thead>
<tr>
<th></th>
<th>Voornaam</th>
<th>Achternaam</th>
<th>Leeftijd</th>
</tr>
</thead>
<tbody>
<tr>
<td class="rownmr">1</td>
<td>Johan</td>
<td>cruijff</td>
<td>54</td>
</tr>
<tr>
<td class="rownmr">2</td>
<td>Frans</td>
<td>Bauer</td>
<td>47</td>
</tr>
<tr>
<td class="rownmr">3</td>
<td>Willem</td>
<td>van Oranje</td>
<td>80</td>
</tr>
</tbody>
</table>
<form action="" id="invoerformulier" class="invoerform">
<label>Voornaam:</label>
<input type="text" name="vnaam" id="voornaam">
<label>Achternaam:</label>
<input type="text" name="anaam" id="achternaam">
<label>Leeftijd:</label>
<input type="text" name="points" id="leeftijd">
</form>
<button id="voegdatatoe">Voeg toe</button>
js
function allID(id) {
return document.getElementById(id);
}
function allEvents() {
allID("voegdatatoe").onclick = function () {
voegToeGegevens();
};
}
allEvents();
function voegToeGegevens() {
var formulier = allID("invoerformulier");
var nieuweGegevens = [];
for (var i = 0; i < formulier.length; i++) {
nieuweGegevens[i] = formulier.elements[i].value;
}
var allRownmrs = document.getElementsByClassName('rownmr');
var lastRownmr = allRownmrs[allRownmrs.length - 1].innerHTML;
var nextRownmr = parseInt(lastRownmr) + 1;
var uitvoertabel = allID("uitvoertabel");
var nieuweRij = uitvoertabel.insertRow(-1);
for (i = 0; i < 4; i++) {
var NieuweCell = nieuweRij.insertCell(i)
// you probably can refactor here
if (i === 0) {
NieuweCell.innerHTML = nextRownmr
} else {
NieuweCell.innerHTML = nieuweGegevens[i - 1];
}
}
}

Fonts in table get messed up after sorting

I have a following problem I cant wrap my head around.
I have a report of open fault cases that is generated automatically and then send as HTML file to people that need to know.
Previously it was a simple table without any styles, text only. It wasn't very user friendly.
So I added styles and collapsing of cells if they're too long.
Next I wanted to add sorting to it. I've found simple example in JS from w3schools that works.
And here's the problem, when the report is open on mobile device in Chrome (also on desktop in Responsive mode) and the table is sorted, the font size will get messed up.
It affects only some columns and different ones depending on screen width.
This is how it looks like before sorting:
And this is after:
If you expand the cell, you could see that only text that wasn't hidden got messed up:
I tried enclosing the cells in additional DIVs and SPANs, trying different font-size attributes and adding width constraints. Nothing worked so far.
I'm not that proficient with HTML/CSS/JS to figure out what's wrong with it unfortunately.
I would be very glad for any help.
Here is an example report for you to try out:
window.onload = function() {
c = document.getElementsByClassName('expand');
for (i = 0; i < c.length; i++) {
lc = c[i].lastChild;
lc.style.display = "none";
lc.previousSibling.style.display = "inline";
}
c = document.getElementsByClassName('expand');
for (i = 0; i < c.length; i++) {
c[i].addEventListener("click", function(e) {
if (this.lastChild.style.display == "table") {
this.lastChild.style.display = "none";
this.lastChild.previousSibling.style.display = "initial"
} else {
this.lastChild.style.display = "table";
this.lastChild.previousSibling.style.display = "none"
}
console.log(this.id, this.lastChild);
})
}
h = document.getElementsByTagName("th");
for (i = 0; i < h.length; i++) {
h[i].innerHTML += "<br><span>∨ ∧</span>";
}
}
sort_direction = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
function sortTable(column_id, direction) {
// Method from https://www.w3schools.com/howto/howto_js_sort_table.asp
direction = sort_direction[column_id];
sort_direction[column_id] = sort_direction[column_id] * -1;
var table, rows, switching, i, x, y, shouldSwitch;
table = document.getElementById("mainTable");
switching = true;
while (switching) {
switching = false;
rows = table.getElementsByTagName("tbody");
for (i = 1; i < (rows.length - 1); i++) {
shouldSwitch = false;
x = rows[i].getElementsByTagName("td")[column_id];
y = rows[i + 1].getElementsByTagName("td")[column_id];
if (direction == -1) {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
} else if (direction == 1) {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
}
}
}
body {
font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 13px;
}
th,
td,
.e {
background: #fff;
margin: 0 auto;
text-align: center;
/* border-radius */
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
/* box-shadow */
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 3px;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 3px;
box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 3px;
word-wrap: break-word;
}
th:hover {
cursor: pointer;
}
tr {
line-height: 14px;
}
table {
border-style: none;
font-size: 10px;
}
.expand {
border: 1.5px solid DodgerBlue;
}
.expand:hover {
background-color: #eee;
cursor: pointer;
}
.medium_cell {
max-width: 220px;
}
.small_cell {
max-width: 75px;
}
<H1>Report</H1>
<h3>Report generated: 2018-06-05 13:10:07</h3>
<table id="mainTable" border="1" bordercolor="#C0C0C0" cellspasing="0" cellpadding="2">
<tbody><tr id="row0" class="class_row">
<th onclick="sortTable(0)">Case ID</th>
<th onclick="sortTable(1)">Status/Title</th>
<th onclick="sortTable(2)">Reported Date</th>
<th onclick="sortTable(3)">Notes</th>
<th onclick="sortTable(4)">Author</th>
<th onclick="sortTable(5)">Assigned Team</th>
<th onclick="sortTable(6)">Assigned Person</th>
<th onclick="sortTable(7)">Severity</th>
<th onclick="sortTable(8)">Priority</th>
<th onclick="sortTable(9)">Flags</th>
<th onclick="sortTable(10)">Information</th>
</tr></tbody>
<tbody><tr id="row3" class="class_row"> <td><a class="small_cell" href="#">ID654321</a></td>
<td class="medium_cell"><p style="font-weight: bold">Many Many Many Lines Status</p>[TT18][TT00+6*TT18]Title of the reported fault</td>
<td class="small_cell">23 May 2018</td>
<td id="row3c1" class="expand medium_cell" style="font-size: 10px;"><div style="font-weight: bold">2018-05-00 00:00:00</div> xxxx xxxxxxxxx xx xxxxBxxx
x4 - xxxxxRxxx, xx. <p style="font-size: 4px;"/><div style="display:none; font-size: 12px;">⇩ <span style="font-style: oblique; font-size: 10px; font-weight: bold">click to expand</span> ⇩</div><div style="display: table;"><div style="font-weight: bold">2018-05-00 00:00:00</div> xxxx xxxxRxx xx xxxxxxxxx
. xxxxxxx Rxxxxx xxxxxxxx.<BR><div style="font-weight: bold">2018-05-00 00:00:00</div> xxxx xxxxBxxx xx xxxxRxx
xxxxxx xxxxx xxxx xxxx xxx</div></td>
<td class="small_cell">Henry</td>
<td>TEAMBLUE</td>
<td class="small_cell">Maria</td>
<td style="background-color:Orange; color:Black;">B<br>Major</td>
<td style="background-color:Orange; color:Black;">2<br>Critical</td>
<td></td>
<td id="row3c2" class="expand"><span style="font-style: oblique">RC: unknown, LE: yyyy-mm-dd</span><div style="font-weight: bold">2018-05-00</div> xxxx (xxxxxx): xxxxxx xxxxxx xxxxx xx xxxxxxx xxxxxxx xx xxxxxxx; xR xxxx <p style="font-size: 4px;"/><div style="display:none; font-size: 12px;">⇩ <span style="font-style: oblique; font-size: 10px; font-weight: bold">click to expand</span> ⇩</div><div style="display: table; margin: 0 auto;"><div style="font-weight: bold">2018-05-00</div> xxxx (xxxxxx): xxxxxxxxxxxxx</div></td>
</tr></tbody>
<tbody><tr id="row4" class="class_row"> <td><a class="small_cell" href="#">ID345678</a></td>
<td class="medium_cell"><p style="font-weight: bold">Even Longer Status</p>[Title_tag][TT00]Title of the reported fault</td>
<td class="small_cell">24 May 2018</td>
<td class="medium_cell" id="row4c1" style="font-size: 10px;"><div style="font-weight: bold">2018-05-00 00:00:00</div> xxxx xxxxxxxxx xx xxxxBxxx
x4 - xxxxxRxxx, xx.</td>
<td class="small_cell">Doug</td>
<td>TEAMBLUE</td>
<td class="small_cell">Ross</td>
<td style="background-color:Orange; color:Black;">B<br>Major</td>
<td style="background-color:Yellow; color:Black;">3<br>Normal</td>
<td></td>
<td id="row4c2" class="expand"><span style="font-style: oblique">RC: unknown, LE: yyyy-mm-dd</span><div style="font-weight: bold">2018-05-00</div> xxxxxx(xxxxxxxx): xxxxxxx xxx xxxxxxxx xxxxxxx xx xxxxxx. <p style="font-size: 4px;"/><div style="display:none; font-size: 12px;">⇩ <span style="font-style: oblique; font-size: 10px; font-weight: bold">click to expand</span> ⇩</div><div style="display: table; margin: 0 auto;"><div style="font-weight: bold">2018-05-00</div> xxxx (xxxxxx): xxxxxx xxxxxx xxxxx xx xxxxxxx xxxxxxx xx xxxxxxx; xR xxxx
<div style="font-weight: bold">2018-05-00</div> xxxx (xxxxxx): xxxxx xxxxx xx xx xxxxxxx xx xx xx345234</div></td>
</tr></tbody>
</table>
* edit *
If you want a file to download and try out yourself, you can get it here

How do I split a table column into new columns from the nth delimiter onwards

I managed to create some code that splits, at the slash delimiter, the third column into new columns.
What I did not manage to do is make it split from the nth (i.e. 2nd) occurrence onwards.
I could not find a similar question on the internet, that's why I post i here.
The desired outcome should be as follows:
function split() {
var delimiter = "/";
var arr = [];
var highest = 0;
var columnIndex = "";
$('#tbl td:nth-child(3)').each(function() {
ColumnIndex = $(this).index();
var string = $(this).text();
var array = string.split(delimiter);
var nbrCharacter = (string.split(delimiter).length - 1) //COUNT OCCURENCES OF CHARACTER
var temp = (nbrCharacter > highest) ? highest++ : highest = highest;
arr.push(string.split(delimiter));
});
for (i = 0; i < highest; i++) { //ADD EMPTY COLUMNS
$('#tbl').find('tr').each(function() {
$(this).find('td').eq(ColumnIndex).after('<td></td>');
});
}
for (i = 0; i < arr.length; i++) { //POPULATE CELLS FROM ARRAY
var columnTracker = ColumnIndex
for (j = 0; j < arr[i].length; j++) {
$('#tbl').find('tr:eq(' + (i + 1) + ')').find('td:eq(' + columnTracker + ')').html(arr[i][j]);
columnTracker++
}
}
}
th {
height: 15px;
min-width: 30px;
border: 1px solid black;
font-size: 12px;
font-family: Courier, monospace;
padding: 2px 5px 2px 5px;
}
td {
height: 15px;
min-width: 30px;
border: 1px solid black;
font-size: 12px;
font-family: Courier, monospace;
padding: 2px 5px 2px 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" onclick="split()">Split</button>
<br>
<br>
<table id="tbl">
<thead>
<tr class="tbl-header">
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
</tr>
</thead>
<tbody>
<tr>
<td>A/B/C</td>
<td>B/C</td>
<td>C</td>
<td></td>
</tr>
<tr>
<td>A/B</td>
<td>B/C</td>
<td></td>
<td>D/E</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>A/B/C/D</td>
<td></td>
<td>C/D/E</td>
<td>D/E/F</td>
</tr>
<tr>
<td></td>
<td>B/C/D</td>
<td>C/D</td>
<td>D/E/F/G</td>
</tr>
<tr>
<td>A/B/C</td>
<td>B/C/D/E</td>
<td>C/D/E/F</td>
<td></td>
</tr>
</tbody>
</table>

Categories

Resources