I have created two tables. The first table I name it atable and the second table I name it second . On the atable I have 3x3(3 columns x 3 rows) and on the second I have 1x9. I want to fill in the first table with numbers, I have created the begin() function so I will fill the table with random items,using a button named Start.Next, I have created a function named check(), it clicks on the first table(atable). Now, what I want to do is ,when I click on the table(atable) I want each of my clicking to transfer the number into the other table(named :second ).I have created the table second but I didn't find how to send the clicks from one table into the other table.
<!DOCTYPE html>
<html>
<head>
<script>
var timerid;
var secs = 30;
var randomNumber;
var mclics = 0;
var mcorrect = 0;
function begin() {
randomNumber = Math.round(Math.random() * 9);
var atable = document.getElementById("atable");
for (i = 0; i < atable.rows.length; i++) {
for(j = 0; j < atable.rows[i].cells.length; j++) {
var a = Math.ceil(Math.random()*100);
atable.rows[i].cells[j].innerHTML = a;
}
}
}
function check(trgt){
if(trgt.tagName=="TD"){
mclics++
trgt.onclick=false; //for not happen again click//
if((trgt.innerHTML%randomNumber)==0){
mcorrect++ //right clicks
trgt.style.backgroundColor = "green";
}
else{
trgt.style.backgroundColor = "red";
}
}
}
</script>
</head>
<body>
<input type="button" value="Start" onclick="begin()" style="width: 30%"><br>
<p id="anumber"></p>
<table id="atable" border="1" onclick="check(event.target)">
<tr>
<td style="width: 292px; height: 39px;"> </td>
<td style="width: 332px; height: 39px;"></td>
<td style="width: 260px; height: 39px;">
</tr>
<tr>
<td style="width: 292px; height: 46px;"></td>
<td style="width: 332px; height: 46px;"></td>
<td style="width: 260px; height: 46px;">
</tr>
<tr><td style="width: 292px; height: 172px;"></td>
<td style="width: 332px; height: 172px;"></td>
<td style="width: 260px; height: 172px;"> </tr>
</table>
<p >Remaining time: </p>
<p id="atimer"></p>
<table id="second" border="1" >
<tr><td style="width: 292px; height: 39px;"> </td> </tr>
<tr><td style="width: 332px; height: 39px;"></td></tr>
<tr><td style="width: 292px; height: 46px;"></td></tr>
<tr> <td style="width: 332px; height: 46px;"></td></tr>
<tr><td style="width: 332px; height: 39px;"></td></tr>
<tr><td style="width: 332px; height: 39px;"></td></tr>
<tr><td style="width: 332px; height: 39px;"></td></tr>
<tr><td style="width: 332px; height: 39px;"></td></tr>
<tr><td style="width: 332px; height: 39px;"></td></tr>
</table>
</body>
</html>
On the first table I added "EventListener". When you click on a number field, the function is called function getNumbers() which adds the number to the other table. So that one digit cannot be added more than once. When you click on a field with a number, "EventListener" is automatically removed. The function getNumbers() loop the fields in the second table and fills in the next blank field.
I have marked the new things in your code with a comments // NEW CODE LINE
Example:
<!DOCTYPE html>
<html>
<head>
<script>
var timerid;
var secs = 30;
var randomNumber;
var mclics = 0;
var mcorrect = 0;
function begin() {
randomNumber = Math.round(Math.random() * 9);
var atable = document.getElementById("atable");
for (i = 0; i < atable.rows.length; i++) {
for (j = 0; j < atable.rows[i].cells.length; j++) {
var a = Math.ceil(Math.random() * 100);
atable.rows[i].cells[j].innerHTML = a;
// NEW CODE LINE
atable.rows[i].cells[j].addEventListener("click", function () {
getNumbers(this.innerText);
this.removeEventListener("click", arguments.callee);
});
// END NEW CODE LINE
}
}
}
function check(trgt) {
if (trgt.tagName == "TD") {
mclics++
trgt.onclick = false; //for not happen again click//
if ((trgt.innerHTML % randomNumber) == 0) {
mcorrect++ //right clicks
trgt.style.backgroundColor = "green";
}
else {
trgt.style.backgroundColor = "red";
}
}
}
// NEW CODE LINE
function getNumbers(x) {
var target = document.getElementById('second').getElementsByTagName('td');
for (var i = 0; i < target.length; i++) {
if (target[i].innerText.length === 0) {
target[i].innerText = x;
break;
}
}
}
// END NEW CODE LINE
</script>
</head>
<body>
<input type="button" value="Start" onclick="begin()" style="width: 30%"><br>
<p id="anumber"></p>
<table id="atable" border="1" onclick="check(event.target)">
<tr>
<td style="width: 292px; height: 39px;"> </td>
<td style="width: 332px; height: 39px;"></td>
<td style="width: 260px; height: 39px;">
</tr>
<tr>
<td style="width: 292px; height: 46px;"></td>
<td style="width: 332px; height: 46px;"></td>
<td style="width: 260px; height: 46px;">
</tr>
<tr>
<td style="width: 292px; height: 172px;"></td>
<td style="width: 332px; height: 172px;"></td>
<td style="width: 260px; height: 172px;">
</tr>
</table>
<p>Remaining time: </p>
<p id="atimer"></p>
<table id="second" border="1">
<tr>
<td style="width: 292px; height: 39px;"> </td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 292px; height: 46px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 46px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
</table>
</body>
</html>
Version 2:
Does not start before pressing the "Start" button. Cleans the contents of both tables when the "Start" button is pressed again.
<!DOCTYPE html>
<html>
<head>
<script>
var timerid;
var secs = 30;
var randomNumber;
// var mclics = 0;
var mcorrect = 0;
function begin() {
// NEW CODE LINE
mcorrect = 0;
var tableA = document.getElementById('atable').getElementsByTagName('td');
for (var i = 0; i < tableA.length; i++) {
tableA[i].style.backgroundColor = '';
tableA[i].removeEventListener("click", getClick);
}
var tableB = document.getElementById('second').getElementsByTagName('td');
for (var i = 0; i < tableB.length; i++) {
tableB[i].innerText = '';
}
// END NEW CODE LINE
randomNumber = Math.round(Math.random() * 9);
var atable = document.getElementById("atable");
for (i = 0; i < atable.rows.length; i++) {
for (j = 0; j < atable.rows[i].cells.length; j++) {
var a = Math.ceil(Math.random() * 100);
atable.rows[i].cells[j].innerHTML = a;
// NEW CODE LINE
atable.rows[i].cells[j].addEventListener("click", getClick);
// END NEW CODE LINE
}
}
}
// function check(trgt) {
// if (trgt.tagName == "TD") {
// mclics++
// trgt.onclick = false; //for not happen again click//
// if ((trgt.innerHTML % randomNumber) == 0) {
// mcorrect++ //right clicks
// trgt.style.backgroundColor = "green";
// }
// else {
// trgt.style.backgroundColor = "red";
// }
// }
// }
// NEW CODE LINE
function getClick() {
getNumbers(this.innerText, this);
this.removeEventListener("click", getClick);
}
function getNumbers(x, y) {
if ((y.innerHTML % randomNumber) == 0) {
mcorrect++ //right clicks
y.style.backgroundColor = "green";
}
else {
y.style.backgroundColor = "red";
}
var target = document.getElementById('second').getElementsByTagName('td');
for (var i = 0; i < target.length; i++) {
if (target[i].innerText.length === 0) {
target[i].innerText = x;
break;
}
}
}
// END NEW CODE LINE
</script>
</head>
<body>
<input type="button" value="Start" onclick="begin()" style="width: 30%">
<br>
<p id="anumber"></p>
<table id="atable" border="1">
<tr>
<td style="width: 292px; height: 39px;"> </td>
<td style="width: 332px; height: 39px;"></td>
<td style="width: 260px; height: 39px;">
</tr>
<tr>
<td style="width: 292px; height: 46px;"></td>
<td style="width: 332px; height: 46px;"></td>
<td style="width: 260px; height: 46px;">
</tr>
<tr>
<td style="width: 292px; height: 172px;"></td>
<td style="width: 332px; height: 172px;"></td>
<td style="width: 260px; height: 172px;">
</tr>
</table>
<p>Remaining time: </p>
<p id="atimer"></p>
<table id="second" border="1">
<tr>
<td style="width: 292px; height: 39px;"> </td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 292px; height: 46px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 46px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
<tr>
<td style="width: 332px; height: 39px;"></td>
</tr>
</table>
</body>
</html>
So either I did this backward or this is how you wanted it. If you meant like, a long (height) table then this is what you want. If you want a wide table, just switch the secondTable.rows[mclics].cells[0].innerHTML = trgt.innerHTML to secondTable.rows[0].cells[mclics].innerHTML = trgt.innerHTML and reformat the table to only have one row. This code simply takes the innerHTML of the cell that you click and add it to the next table's next spot. There is no check though, so it will error once you fill-up the second table. Good luck!
function check(trgt) {
var secondTable = document.getElementById("second");
if (trgt.tagName == "TD") {
secondTable.rows[mclics].cells[0].innerHTML = trgt.innerHTML
mclics++
trgt.onclick = false; //for not happen again click//
if ((trgt.innerHTML % randomNumber) == 0) {
mcorrect++ //right clicks
trgt.style.backgroundColor = "green";
} else {
trgt.style.backgroundColor = "red";
}
}
}
HTML Table (second):
<table id="second" style="border: 1;" >
<tr><td style="width: 292px; height: 39px;"></td></tr>
<tr><td style="width: 292px; height: 39px;"></td></tr>
<tr><td style="width: 292px; height: 39px;"></td></tr>
<tr><td style="width: 292px; height: 46px;"></td></tr>
<tr><td style="width: 292px; height: 46px;"></td></tr>
<tr><td style="width: 292px; height: 46px;"></td></tr>
<tr><td style="width: 292px; height: 172px;"></td></tr>
<tr><td style="width: 332px; height: 172px;"></td></tr>
<tr><td style="width: 260px; height: 172px;"></td></tr>
</table>```
Related
I have the following script calculating a simple sum. If sum exceed or is below 100 a display error is shown. Despite the error message the user is still allow to proceed to the following page. I would like that until the value is == 100 he can't move to the next page.
<table class="table-bordered" style=" width: 80%; margin-left: 10%;" >
<tr style="background-color:#ffb380">
<td scope="col" colspan="1" style="text-align:center"> Quante Palline per la Scelta 1 </td>
<td scope="col" colspan="1" style="text-align:center"> Quanti Palline per la Scelta 2 </td>
<td scope="col" colspan="1" style="text-align:center"> Totale Palline Assegnate </td>
</tr>
<tr style="background-color:#ffe0cc">
<td> <input class="pref_input" id="pref1" type="number" name="pref1" min="0" max="100" style="width: 50%; margin-left: 25%"> </td>
<td> <input class="pref_input" id="pref2" type="number" name="pref2" min="0" max="100" style="width: 50%; margin-left: 25%"> </td>
<td> <span id="sum_token" style="width: 50%; margin-left: 37%" ></span> su 100</td>
</tr>
</table>
<div id="error" class="hide"><b>La somma dei gettoni deve essere 100</b></div>
<script>window.onload = init_sum_token();
function init_sum_token() {
sum_token = document.getElementById("sum_token");
pref1 = document.getElementById("pref1");
pref2 = document.getElementById("pref2");
document.querySelectorAll(".pref_input").forEach((item) => {
item.addEventListener("change", (event) => {
sum_prefs =
get_input_value(pref1) +
get_input_value(pref2);
let sum = parseFloat(sum_prefs);
if (sum != 100) {
sum = sum_prefs;
document.getElementById("error").className = "show";
} else {
document.getElementById("error").className = "hide";
}
sum_token.innerHTML = sum;
});
});
}
function get_input_value(input) {
if (input.value == "") {
return 0;
} else {
return parseFloat(input.value);
}
if (input.value != 100) {
return "error";
}
}
</script>
please compare the sum correctly in get_input_value() function it should be like this:
if (input.value > 100 || input.value < 100 ) {
return "error";
}
also correct it:
if (sum > 100 || sum < 100) {
sum = sum_prefs;
....
So I've been searching this site for weeks trying to find a solution to this and have looked at EVERY question asked about getting the sum of input fields or finding the value of start and stop times but none of them solve my issue.
The included snippet shows a time sheet that I currently am able to input the reg (regular) and ot (overtime) hours and the sum of each row is populated in the total box but at the bottom I have to manually total the column values.
What I would like to do is eliminate the amount of data that has to be input into the form by having javascript calculate the start time and stop time and add the values to the reg, ot and total fields then sum up those columns at the bottom for the grandtotals.
The reason I want to do it like this is that this form is converted into a phone app and the less that is needed to input the fewer mistakes made.
I'm pretty new to this so I'm sure what I have is either incorrect (although it works), or there is a better way to accomplish it with less coding.
Any direction, input or help is greatly appreciated.
function sum() {
var txtFirstNumberValue = document.getElementById('reghours').value;
var txtSecondNumberValue = document.getElementById('othours').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours').value = result;
}
}
function sum2() {
var txtFirstNumberValue = document.getElementById('reghours2').value;
var txtSecondNumberValue = document.getElementById('othours2').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours2').value = result;
}
}
function sum3() {
var txtFirstNumberValue = document.getElementById('reghours3').value;
var txtSecondNumberValue = document.getElementById('othours3').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours3').value = result;
}
}
function sum4() {
var txtFirstNumberValue = document.getElementById('reghours4').value;
var txtSecondNumberValue = document.getElementById('othours4').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours4').value = result;
}
}
function sum5() {
var txtFirstNumberValue = document.getElementById('reghours5').value;
var txtSecondNumberValue = document.getElementById('othours5').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours5').value = result;
}
}
</script>
<script>
$(function() {
$('#BasicExample').timepicker();
});
$(function() {
$('#BasicExample2').timepicker();
});
$(function() {
$('#BasicExample3').timepicker();
});
$(function() {
$('#BasicExample4').timepicker();
});
$(function() {
$('#BasicExample5').timepicker();
});
$(function() {
$('#BasicExample6').timepicker();
});
$(function() {
$('#BasicExample7').timepicker();
});
$(function() {
$('#BasicExample8').timepicker();
});
$(function() {
$('#BasicExample9').timepicker();
});
$(function() {
$('#BasicExample10').timepicker();
});
.ui-timepicker-wrapper {
overflow-y: auto;
height: 150px;
width: 6.5em;
background: #fff;
border: 1px solid #ddd;
-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);
-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);
box-shadow:0 5px 10px rgba(0,0,0,0.2);
outline: none;
z-index: 10001;
margin: 0;
}
.ui-timepicker-wrapper.ui-timepicker-with-duration {
width: 13em;
}
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-30,
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-60 {
width: 11em;
}
.ui-timepicker-list {
margin: 0;
padding: 0;
list-style: none;
}
.ui-timepicker-duration {
margin-left: 5px; color: #888;
}
.ui-timepicker-list:hover .ui-timepicker-duration {
color: #888;
}
.ui-timepicker-list li {
padding: 3px 0 3px 5px;
cursor: pointer;
white-space: nowrap;
color: #000;
list-style: none;
margin: 0;
}
.ui-timepicker-list:hover .ui-timepicker-selected {
background: #fff; color: #000;
}
li.ui-timepicker-selected,
.ui-timepicker-list li:hover,
.ui-timepicker-list .ui-timepicker-selected:hover {
background: #1980EC; color: #fff;
}
li.ui-timepicker-selected .ui-timepicker-duration,
.ui-timepicker-list li:hover .ui-timepicker-duration {
color: #ccc;
}
.ui-timepicker-list li.ui-timepicker-disabled,
.ui-timepicker-list li.ui-timepicker-disabled:hover,
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
color: #888;
cursor: default;
}
.ui-timepicker-list li.ui-timepicker-disabled:hover,
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
background: #f2f2f2;
}
.auto-style1 {
text-align: right;
}
body {
font-family: sans-serif;
}
#summation {
font-size: 16px;
font-weight: bold;
color:#174C68;
}
.txt {
background-color: #FEFFB0;
font-weight: bold;
text-align: center;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://jemtech.us/scripts/jquery.timepicker.min.js"></script>
<script src="http://jemtech.us/scripts/jquery.timepicker.js"></script>
<body>
<form action="process_form.php" method="post">
<table align="center" style="width: 498px">
<td class="auto-style1"> </td>
<td class="auto-style1"> </td>
<td class="auto-style1" style="width: 127px"> </td>
</table>
<table align="center" class="auto-style6" style="width: 857px">
<th class="auto-style5" style="width: 47px">Start</th>
<th class="auto-style5" style="width: 47px">Stop</th>
<th class="auto-style5" style="width: 43px">Reg</th>
<th class="auto-style5" style="width: 45px">OT</th>
<th class="auto-style5" style="width: 51px">Total</th>
<th class="auto-style5"></th>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample2" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 43px;">
<input type="text" class="txt" name="RegularHours" id="reghours" onkeyup="sum()" style="width: 45px" />
</td>
<td style="height: 26px; width: 45px;">
<input type="text" class="txt" name="OTHours" id="othours" value="0" onkeyup="sum()" style="width: 45px" />
</td>
<td style="height: 26px; width: 51px;">
<input type="text" class="txt" name="TotalHours" id="totalhours" style="width: 50px" readonly/>
</td>
<td style="height: 26px">
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample3" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample4" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 43px;">
<input type="text" class="txt" name="RegularHours2" id="reghours2" onkeyup="sum2()" style="width: 45px" />
</td>
<td style="height: 26px; width: 45px;">
<input type="text" class="txt" name="OTTotal2" id="othours2" value="0" onkeyup="sum2()" style="width: 45px" />
</td>
<td style="height: 26px; width: 51px;">
<input type="text" class="txt" name="TotalHours2" id="totalhours2" style="width: 50px" readonly/>
</td>
<td style="height: 26px">
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample5" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample6" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 17px; width: 43px;">
<input type="text" class="txt" class="txt" name="RegularHours3" id="reghours3" onkeyup="sum3()" style="width: 45px" />
</td>
<td style="height: 17px; width: 45px;">
<input type="text" class="txt" class="txt" name="OTHours3" id="othours3" value="0" onkeyup="sum3()" style="width: 45px" />
</td>
<td style="height: 17px; width: 51px;">
<input type="text" class="txt" class="txt" name="TotalHours3" id="totalhours3" style="width: 50px" readonly/>
</td>
<td style="height: 17px">
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample7" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample8" type="text" class="time" style="width: 85px" />
</td>
<td style="width: 43px">
<input type="text" class="txt" name="RegularHours4" id="reghours4" onkeyup="sum4()" style="width: 45px" />
</td>
<td style="width: 45px">
<input type="text" class="txt" name="OTHours4" id="othours4" value="0" onkeyup="sum4()" style="width: 45px" />
</td>
<td style="width: 51px">
<input type="text" class="txt" name="TotalHours4" id="totalhours4" style="width: 50px" readonly/>
</td>
<td>
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample9" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample10" type="text" class="time" style="width: 85px" />
</td>
<td style="width: 43px">
<input type="text" class="txt" name="RegularHours5" id="reghours5" onkeyup="sum5()" style="width: 45px" />
</td>
<td style="width: 45px">
<input type="text" class="txt" name="OTHours5" id="othours5" value="0" onkeyup="sum5()" style="width: 45px" />
</td>
<td style="width: 51px">
<input type="text" class="txt" name="TotalHours5" id="totalhours5" style="width: 50px" readonly/>
</td>
<td>
</td>
</tr>
</table>
<div class="auto-style1" style="width: 640px; height: 26px">
<td><strong>Total Hours</strong>
</td>
<td>
<input type="text" class="txt" name="RegTotal" id="total" style="width: 45px" readonly />
</td>
<td>
<input type="text" class="txt" name="OTTotal" id="total" style="width: 45px" readonly/>
</td>
<td style="width: 45px">
<tr id="summation">
<td style="width: 50px">
<input type="text" class="txt" name="GrandTotal" id="grandtotal" style="width: 50px" readonly/>
</td>
<td style="height: 23px"></td>
</tr>
</td>
</div>
<div style="height: 35px"></div>
<hr />
<br/>
<input type="submit" name="submit" value="Submit" />
</form>
</body>
Please consider using a jQuery TimePicker Plugin as mentioned in https://www.sitepoint.com/10-jquery-time-picker-plugins/ together with https://momentjs.com/ for calculations.
As others have mentioned a date picker will make this easier for both you and your users. Either way, you will need to parse your inputs to get date objects
// With date picker
var startDate = new Date(startPicker.value);
or
// With current select inputs
// Get AM/PM hours - hourSelect should be the select element for hours
var startHrs = periodSelect.value === 'PM'
? parseInt(hourSelect.options[hourSelect.selectedIndex].value, 10)
: parseInt(hourSelect.options[hourSelect.selectedIndex].value, 10) + 12;
// No date provided so use dummy date (1970-1-1)
var startDate = new Date(
1970,
1,
1,
startHrs,
minuteSelect.options[minuteSelect.selectedIndex].value; // minuteSelect should be the select element for minutes
);
Then calculate the difference between your start and end dates. As mentioned you can use moment.js for this but the regular date object should be sufficient.
function getDifference(startDate, endDate) {
return new Date(endDate.getTime() - startDate.getTime());
}
Now you can use difference.getUTCHours() and difference.getUTCMinutes to get the total time worked. It should be trivial to get regular and overtime from the total. Remember to check that the start time is before the end.
... or there is a better way to accomplish it with less coding.
The essence of the question seems to be about how to keep the code DRY, not about whether or not to use a date-picker (though that is also an important decision).
The golden rules in spreadsheet-like apps like this with repeated rows are :
use classes for elements in the repeated rows
use ids only for non-repeating element
Here's a general framework :
jQuery(function($) {
var overtimeAfter = 8.0; // hours per day
// *** utility Constructor ***
function Hours(std, ot) {
return {'std':std, 'ot':ot};
}
Hours.prototype.add = function(otherHours) {
return new Hours(this.std+otherHours.std, this.ot+otherHours.ot);
}
// *** utility functions ***
function getTime(input) {
// Here, do whatever is necessary to convert input values to some standard abstraction:
// for example, 24H string or js Date() object.
return Number(input.val()); // simplest case
}
function timeDiffernce(t1, t2) {
// Here do whatever is necessary to calculate the time difference
// between t2 and t1, in whatever abstraction was returned by getTime().
// For example:
var t = t2 - t1; // simplest case
return (t < 0) ? 24 + t : t; // allow for t1...t2 to span midnight
}
// *** core functions ***
function calcDayHours(tr) {
// here is where you benefit from classes within the table row
var time1 = getTime($('.time1', tr));
var time2 = getTime($('.time2', tr));
var hours = timeDiffernce(time1, time2);
var std = Math.min(hours, overtimeAfter);
var ot = Math.max(0, hours - overtimeAfter);
var total = std + ot;
$('.reghours', tr).val(std);
$('.othours', tr).val(ot);
$(".totalhours", tr).val(total);
return new Hours(std, ot);
}
function calcWeekHours(hours) {
var weekHours = hours.reduce(function(week, day) {
return week.add(day);
}, new Hours(0, 0));
// these elements are unique, therefore identified by id.
$("#regTotal").val(weekHours.std);
$("#otTotal").val(weekHours.ot);
$("#grandTotal").val(weekHours.std + weekHours.ot);
return weekHours;
}
// *** master function ***
function sum() {
// Assume a table or tbody with id="timesheet"
var dayHours = $("#timesheet tr").get().map(calcDayHours);
var weekHours = calcWeekHours(dayHours);
// if you want wage calculations, then pass `weekHours` to a `calcWages()` function.
// var wages = calcWages(weekHours);
}
// Then attach `sum` as the handler for all kinds of keyup/tap/click/focus/blur events.
});
As I say, that's just a framework. There are still decisions to make, eg :
what you write in getTime() will depend on the expected date/time input format (text vs date-picker ...)
what you write in timeDiffernce() will depend on what you decide to return from getTime() (Number vs Date ...).
which ui event(s) should trigger sum().
how to specify the overtime threshold overtimeAfter - hardcoding as above will get you started.
how to accommodate overtime thresholds on a "per day", "per week" or "per month" basis - wage systems vary.
I'm trying to write code to detect if a ship has been hit or not. I have 3 ships on the board and each takes up 3 cells. Using js I placed the 3 ships on the board. And when I run the fire method, only the last two ships show they've been hit, but the first ship at location 00,01,02 doesn't indicate that it's been hit, even once. Where did I go wrong?
var view = {
showMessage: function(msg) {
var message = document.getElementById('message');
message.innerHTML = msg;
},
showHit: function(location) {
var cell = document.getElementById(location);
cell.setAttribute('class', 'hit');
},
showMiss: function(location) {
var cell = document.getElementById(location);
cell.setAttribute('class', 'miss');
}
}
var model = {
boardSize: 7,
numShips: 3,
shipsSunk: 3,
ships: [{
location: [00, 01, 02],
hits: ['', '', '']
},
{
location: [10, 11, 12],
hits: ['', '', '']
},
{
location: [20, 21, 22],
hits: ['', '', '']
}
],
fire: function(guess) {
for (var i = 0; i < this.numShips; i++) {
var ship = this.ships[i];
var index = ship.location.indexOf(guess);
if (index >= 0) {
ship.hits[index] = 'hit';
view.showHit(guess);
}
}
}
};
model.fire(10);
model.fire(11);
model.fire(12);
model.fire(20);
model.fire(21);
model.fire(22);
/*
model.fire(00);
model.fire(01);
model.fire(02); */
* {
margin: 0px;
padding: 0px;
}
body {
background-color: grey;
}
#message {
color: green;
font-size: 2em;
text-transform: uppercase;
font-family: sans-serif;
}
#board {
background: url('board.jpg') no-repeat;
width: 863px;
height: 1024px;
margin: auto;
position: relative;
}
table {
position: absolute;
left: 173px;
top: 98px;
}
td {
height: 94px;
width: 94px;
}
form input {
position: absolute;
right: 0px;
bottom: 0px;
background-color: green;
}
.hit {
background: url('ship.png') no-repeat center center;
}
.miss {
background: url('miss.png') no-repeat center center;
}
<div id='board'>
<div id='message'></div>
<table>
<tr>
<td id='00'></td>
<td id='01'></td>
<td id='02'></td>
<td id='03'></td>
<td id='04'></td>
<td id='05'></td>
<td id='06'></td>
</tr>
<tr>
<td id='10'></td>
<td id='11'></td>
<td id='12'></td>
<td id='13'></td>
<td id='14'></td>
<td id='15'></td>
<td id='16'></td>
</tr>
<tr>
<td id='20'></td>
<td id='21'></td>
<td id='22'></td>
<td id='23'></td>
<td id='24'></td>
<td id='25'></td>
<td id='26'></td>
</tr>
<tr>
<td id='30'></td>
<td id='31'></td>
<td id='32'></td>
<td id='33'></td>
<td id='34'></td>
<td id='35'></td>
<td id='36'></td>
</tr>
<tr>
<td id='40'></td>
<td id='41'></td>
<td id='42'></td>
<td id='43'></td>
<td id='44'></td>
<td id='45'></td>
<td id='46'></td>
</tr>
<tr>
<td id='50'></td>
<td id='51'></td>
<td id='52'></td>
<td id='53'></td>
<td id='54'></td>
<td id='55'></td>
<td id='56'></td>
</tr>
<tr>
<td id='60'></td>
<td id='61'></td>
<td id='62'></td>
<td id='63'></td>
<td id='64'></td>
<td id='65'></td>
<td id='66'></td>
</tr>
</table>
<form action='#' method='get'>
<input type='text' id='guessInput' placeholder='enter location: A0' />
<input type='button' name='submit' value='Fire!' name='fire' />
</form>
</div>
Your coordinates 00, 01, and 02 are interpreted as ints and are therefore resolved to 0, 1, and 2, because it is assumed that the leading zero is not needed for an int value. You can fix this by using strings to represent and compare the coordinates. Instead of model.fire(00), you will need model.fire("00"). Then to compare the input coordinates, you will need to compare guess.charAt(0) and guess.charAt(1) to determine if that coordinate is a hit.
I'm relatively new to jQuery but more seasoned using html and css.
I'm currently working on creating a new report that displays a nested table with quarterly results.Sample Quarterly Report
When a user clicks the img next to Q1 or Q2 table row - my expectation is for the Week (wk1 - wkn) columns to hide/show (toggle) as needed.
Additionally, when week columns are hidden, i would like the Quartely column(s) to collapse and dynamically show the sum of hidden weeks (wk1 - wkn).
Most of the code is borrowed from other posts but unfortunately, i was unable to find one that collapses and sums nested columns.
Thanks in advance for your help!
$(document).ready(function () {
var mImg = "http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png";
var pImg = "http://t3.gstatic.com/images?q=tbn:4TZreCjs_a1eDM:http://www.venice.coe.int/images/plus.png";
var sum1 = 0;
$('tr').find('.combat1').each(function () {
var combat1 = $(this).text();
if (!isNaN(combat1) && combat1.length !== 0) {
sum1 += parseFloat(combat1);
}
});
var sum2 = 0;
$('tr').find('.combat2').each(function () {
var combat2 = $(this).text();
if (!isNaN(combat2) && combat2.length !== 0) {
sum2 += parseFloat(combat2);
}
});
var sum3 = 0;
$('tr').find('.combat3').each(function () {
var combat3 = $(this).text();
if (!isNaN(combat3) && combat3.length !== 0) {
sum3 += parseFloat(combat3);
}
});
$('.total-combat1').html(sum1);
$('.total-combat2').html(sum2);
$('.total-combat3').html(sum3);
$('.header').click(function() {
//$('td:nth-child(2)').hide();
// if your table has header(th), use this
$('td:nth-child(2),th:nth-child(2)').toggle();
});
});
body {
background: #80dfff;
color: #d5d4d4;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
margin: 0;
overflow-x: auto;
padding: 30px;
}
table {
background: white;
border-collapse: collapse;
border: 1px #393939 solid;
color: black;
margin: 1em 1em 1em 0;
}
thead {
border-collapse: collapse;
color: black;
}
th, td {
border: 1px #aaa solid;
padding: 0.2em;
}
<table>
<thead>
<tr><th colspan=8>2015</th></tr>
<tr><th colspan=4 class="header">Q1
<img src="http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png" />
</th>
<th colspan=3 class="header">Q2
<img src="http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png" />
</th>
<th></th>
</tr>
<tr>
<th>WK1</th>
<th>WK2</th>
<th>WK3</th>
<th>WK4</th>
<th>WK1</th>
<th>WK2</th>
<th>WK3</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="combat1">8170</td>
<td class="combat1">6504</td>
<td class="combat1">6050</td>
<td class="combat1">6050</td>
<td class="combat1">7050</td>
<td class="combat1">7050</td>
<td class="combat1">7050</td>
<td class="total-combat1"></td>
</tr>
<tr>
<td class="combat2">8500</td>
<td class="combat2">10200</td>
<td class="combat2">7650</td>
<td class="combat2">7650</td>
<td class="combat2">8650</td>
<td class="combat2">8650</td>
<td class="combat2">8650</td>
<td class="total-combat2"></td>
</tr>
<tr>
<td class="combat3">9185</td>
<td class="combat3">5515</td>
<td class="combat3">6185</td>
<td class="combat3">7185</td>
<td class="combat3">9185</td>
<td class="combat3">9185</td>
<td class="combat3">9185</td>
<td class="total-combat3"></td>
</tr>
</tbody>
</table>
If you need to toggle the visibility of Q1 or Q2 you can change the header click event in order to obtain the effect produced in the following snippet.
The problem is to select all the cells of your interest and than toggle the visibility.
One way is to limit the cells selected using the jQuery :lt and :gt plus the css
$(function () {
var mImg = "http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png";
var pImg = "http://t3.gstatic.com/images?q=tbn:4TZreCjs_a1eDM:http://www.venice.coe.int/images/plus.png";
var sum1 = 0;
$('tr').find('.combat1').each(function () {
var combat1 = $(this).text();
if (!isNaN(combat1) && combat1.length !== 0) {
sum1 += parseFloat(combat1);
}
});
var sum2 = 0;
$('tr').find('.combat2').each(function () {
var combat2 = $(this).text();
if (!isNaN(combat2) && combat2.length !== 0) {
sum2 += parseFloat(combat2);
}
});
var sum3 = 0;
$('tr').find('.combat3').each(function () {
var combat3 = $(this).text();
if (!isNaN(combat3) && combat3.length !== 0) {
sum3 += parseFloat(combat3);
}
});
$('.total-combat1').html(sum1);
$('.total-combat2').html(sum2);
$('.total-combat3').html(sum3);
// The new header click event
$('.header').click(function(e) {
var isVisible = false;
var strSelector = '';
var everyTotIndex = 4;
if (this.innerText.trim() == 'Q1') {
everyTotIndex = 4;
strSelector = 'td:not([colspan="4"]):lt(4), th:not([colspan="4"]):lt(4)';
} else {
everyTotIndex = 3;
strSelector = 'td:not([colspan="3"]):lt(7):gt(3), th:not([colspan="3"]):lt(7):gt(3)';
}
$(this).parents('table').find('tr:eq(2), tbody > tr').find(strSelector).css('display', function(index, value) {
if (this.style.display == 'none') {
isVisible = true;
if ((index % everyTotIndex) == 0) {
$(this).parent().find('td[colspan="' + everyTotIndex + '"], th[colspan="' + everyTotIndex + '"]').remove();
}
return '';
}
if ((index % everyTotIndex) == 0) {
if (this.tagName.toLowerCase() == 'th') {
$('<th colspan="' + everyTotIndex + '" class="total">Total</th>').insertBefore($(this));
} else {
$('<td colspan="' + everyTotIndex + '" class="combat1 total">0</td>').insertBefore($(this));
var obj = $(this).parent().find('td[colspan="' + everyTotIndex + '"]');
obj.text(+obj.text() + parseInt(this.textContent));
}
} else {
if (this.tagName.toLowerCase() == 'td') {
var obj = $(this).parent().find('td[colspan="' + everyTotIndex + '"]');
obj.text(+obj.text() + parseInt(this.textContent));
}
}
return 'none';
});
if (isVisible) {
$(this).find('img').attr('src', "http://www.unesco.org/ulis/imag/minus.png");
} else {
$(this).find('img').attr('src', "http://www.unesco.org/ulis/imag/plus.png");
}
});
});
body {
background: #80dfff;
color: #d5d4d4;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
margin: 0;
overflow-x: auto;
padding: 30px;
}
table {
background: white;
border-collapse: collapse;
border: 1px #393939 solid;
color: black;
margin: 1em 1em 1em 0;
}
thead {
border-collapse: collapse;
color: black;
}
th, td {
border: 1px #aaa solid;
padding: 0.2em;
}
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<table>
<thead>
<tr><th colspan=8>2015</th></tr>
<tr><th colspan=4 class="header">Q1
<img src="http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png" />
</th>
<th colspan=3 class="header">Q2
<img src="http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png" />
</th>
<th></th>
</tr>
<tr>
<th>WK1</th>
<th>WK2</th>
<th>WK3</th>
<th>WK4</th>
<th>WK1</th>
<th>WK2</th>
<th>WK3</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="combat1">8170</td>
<td class="combat1">6504</td>
<td class="combat1">6050</td>
<td class="combat1">6050</td>
<td class="combat1">7050</td>
<td class="combat1">7050</td>
<td class="combat1">7050</td>
<td class="total-combat1"></td>
</tr>
<tr>
<td class="combat2">8500</td>
<td class="combat2">10200</td>
<td class="combat2">7650</td>
<td class="combat2">7650</td>
<td class="combat2">8650</td>
<td class="combat2">8650</td>
<td class="combat2">8650</td>
<td class="total-combat2"></td>
</tr>
<tr>
<td class="combat3">9185</td>
<td class="combat3">5515</td>
<td class="combat3">6185</td>
<td class="combat3">7185</td>
<td class="combat3">9185</td>
<td class="combat3">9185</td>
<td class="combat3">9185</td>
<td class="total-combat3"></td>
</tr>
</tbody>
</table>
I tried to figure out what you was trying to do... Correct if me I wrong: you're trying to toggle the set of columns under, for e.g. Q1, when you click on the header column? If so, here the code. I modified your code, I added to nested tables under the main table to organize/ divide the two sets of information so I can select easily with jQuery which one I'm going to toggle.
$(document).ready(function() {
var mImg = "http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png";
var pImg = "http://t3.gstatic.com/images?q=tbn:4TZreCjs_a1eDM:http://www.venice.coe.int/images/plus.png";
var sum1 = 0;
$('tr').find('.combat1').each(function() {
var combat1 = $(this).text();
if (!isNaN(combat1) && combat1.length !== 0) {
sum1 += parseFloat(combat1);
}
});
var sum2 = 0;
$('tr').find('.combat2').each(function() {
var combat2 = $(this).text();
if (!isNaN(combat2) && combat2.length !== 0) {
sum2 += parseFloat(combat2);
}
});
var sum3 = 0;
$('tr').find('.combat3').each(function() {
var combat3 = $(this).text();
if (!isNaN(combat3) && combat3.length !== 0) {
sum3 += parseFloat(combat3);
}
});
$('.header-1').click(function() {
$("#table1").toggle();
});
$('.header-2').click(function() {
$("#table2").toggle();
});
});
body {
color: #d5d4d4;
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
margin: 0;
overflow-x: auto;
padding: 30px;
}
table {
background: white;
border-collapse: collapse;
border: 1px #393939 solid;
color: black;
margin: 0;
padding: 0;
}
thead {
border-collapse: collapse;
color: black;
}
th,
td,
tr {
border: 1px #aaa solid;
padding: 0;
}
td.combat {
padding: 0.2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr>
<th colspan=2>2015</th>
</tr>
<tr>
<th class="header-1">Q1
<img src="http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png" />
</th>
<th class="header-2">Q2
<img src="http://t1.gstatic.com/images?q=tbn:1PS9x2Ho4LHpaM:http://www.unesco.org/ulis/imag/minus.png" />
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<table id="table1">
<tr>
<th>WK1</th>
<th>WK2</th>
<th>WK3</th>
<th>WK4</th>
</tr>
<tr>
<td class="combat combat1">8170</td>
<td class="combat combat1">6504</td>
<td class="combat combat1">6050</td>
<td class="combat combat1">6050</td>
</tr>
<tr>
<td class="combat combat1">8170</td>
<td class="combat combat1">6504</td>
<td class="combat combat1">6050</td>
<td class="combat combat1">6050</td>
</tr>
</table>
</td>
<td>
<table id="table2">
<tr>
<th>WK1</th>
<th>WK2</th>
<th>WK3</th>
</tr>
<tr>
<td class="combat combat2">7050</td>
<td class="combat combat2">7050</td>
<td class="combat combat2">7050</td>
</tr>
<tr>
<td class="combat combat2">7050</td>
<td class="combat combat2">7050</td>
<td class="combat combat2">7050</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
I have an employee extension list table with employee name and employees thumb-nail image next to it.
I have a requirement to provide the user with small medium large radio button (or drop down) options and display the employee image accordingly. I was wondering if this can be done using CSS? Or can I create a CSS class in java script based on the radio button selection? I tried to do it through java script but it only works on my first row. rest of the rows are unchanged. Here is a glimpse of my code.
<Script type="text/javascript">
function changeClass(){
alert(document.getElementById("lastName").getAttribute("style"));
var imgSize = document.getElementById("lastName").getAttribute("style");
if(document.getElementById('ImgSizeSmall').checked == true) {
document.getElementById('lastName').setAttribute("style", "width:75px;" );
} else if(document.getElementById('ImgSizeMedium').checked == true) {
document.getElementById('lastName').setAttribute("style", "width:100px;" );
} else if(document.getElementById('ImgSizeLarge').checked == true) {
document.getElementById('lastName').setAttribute("style", "width:150px;" );
}
</Script>
<Div style="width:385px;height: 950px; float:left; background-color:#A5B3D8;">
<p align="left">
<p align="left"><b>Image Size:</b><br>
<input id="ImgSizeSmall" type="radio" name="ImgSize" value="small" checked="checked" onclick="changeClass()"> <b><i>Small</i></b>
<input id="ImgSizeMedium" type="radio" name="ImgSize" value="medium"> <b><i>Medium</i></b>
<input id="ImgSizeLarge" type="radio" name="ImgSize" value="large"> <b><i>Large</i></b>
</p>
</DIV>
<table id="table_firstname_lastname">
<thead>
<tr>
<th style="width: 208px;">First Name</th>
<th style="width: 208px;">Last Name</th>
<th style="width: 208px;">Phone Number</th>
<th style="width: 275px;">Location</th>
<th style="width: 208px;">Cell</th>
<th style="width: 275px;">Team(s)</th>
</tr>
</thead>
<tbody>
<tr>
<td>first name</td>
<td>last name
<img id="lastName" style="width: 75px;" src="http://imagesource/image.jpg" align="right"></a></td>
<td>9999999999</td>
<td>location 1</td>
<td>8888888888</td>
<td>team name</td>
</tr>
</tbody>
</table>
Thanks,
M
I remembered an article from CSS Tricks that led to Fiddeling this: Fiddle
HTML:
<div>
<input type="radio" id="tab-1" name="tab-group-1" checked>
<input type="radio" id="tab-2" name="tab-group-1">
<input type="radio" id="tab-3" name="tab-group-1">
<img src="http://www.mycatspace.com/wp-content/uploads/2013/08/adopting-a-cat.jpg"/>
</div>
CSS:
#tab-1[type=radio]:checked ~ img
{
height: 500px;
width: 500px;
}
#tab-2[type=radio]:checked ~ img
{
height: 200px;
width: 200px;
}
#tab-3[type=radio]:checked ~ img
{
height: 50px;
width: 50px;
}
This might help you on your way..
I wrote the following java script class which solved my problem pretty well :)
function changeClass(){
var imgSize = document.getElementById("lastName").getAttribute("style");
var table;
if(document.getElementById('radio_firstname_lastname').checked == true) {
table = document.getElementById('table_firstname_lastname');
} else {
table = document.getElementById('table_lastname_firstname');
}
if(document.getElementById('ImgSizeSmall').checked == true) {
for (var r = 1; r < table.rows.length; r++) {
var x = table.rows[r].cells.item(0);
x.getElementsByTagName('img')[0].style.width="75px";
}
} else if(document.getElementById('ImgSizeMedium').checked == true) {
for (var r = 1; r < table.rows.length; r++) {
var x = table.rows[r].cells.item(0);
x.getElementsByTagName('img')[0].style.width="100px";
}
} else if(document.getElementById('ImgSizeLarge').checked == true) {
for (var r = 1; r < table.rows.length; r++) {
var x = table.rows[r].cells.item(0);
x.getElementsByTagName('img')[0].style.width="150px";
}
}
}