I’m creating some calculators for a mobile game that I play. I’m going to have 6 of the same type of calculator on the same page. Each one should look and operate like so:
const speedupInputs = document.querySelectorAll('input');
const results = document.getElementById('results');
const submit = document.getElementById('submit');
submit.addEventListener('click', function() {
let total = 0;
results.textContent = '';
speedupInputs.forEach((input) => {
if(input.value != '') {
if(input.classList.contains('minutes')) {
total += input.value * input.name;
} else if (input.classList.contains('hours')) {
total += (input.value * input.name) * 60;
} else if (input.classList.contains('days')) {
total += (input.value * input.name) * 60 * 24;
}
}
})
results.textContent = toTime(total * 60);
});
function toTime(seconds) {
const secsPerDay = 86400;
const secsPerHour = 3600;
const secsPerMinute = 60;
var minus = (this < 0) ? '-' : '';
var days = Math.floor(seconds / secsPerDay);
seconds = (seconds % secsPerDay);
var hours = Math.floor(seconds / secsPerHour);
seconds = (seconds % secsPerHour);
var minutes = Math.floor(seconds / secsPerMinute);
seconds = (seconds % secsPerMinute);
var sDays = new String(days).padStart(1, '0');
var sHours = new String(hours).padStart(2, '0');
var sMinutes = new String(minutes).padStart(2, '0');
return `${minus}${sDays}d ${sHours}:${sMinutes}:00`;
}
table, tr, td {
border: 1px solid black;
border-collapse: collapse;
}
table {
width: 100px;
margin: 40px;
}
input {
width: 90%;
outline: 0;
border: none;
}
td {
text-align: center;
}
<table>
<colgroup>
<col span="1" style="width: 50%;">
<col span="1" style="width: 50%;">
</colgroup>
<thead>
<th colspan="2">
Speed-Ups
</th>
</thead>
<tbody>
<tr>
<td>
1m
</td>
<td>
<input type="number" class="minutes" id="1m" name="1" min="0">
</td>
</tr>
<tr>
<td>
3m
</td>
<td>
<input type="number" class="minutes" id="3m" name="3" min="0">
</td>
</tr>
<tr>
<td>
5m
</td>
<td>
<input type="text" class="minutes" id="5m" name="5" min="0">
</td>
</tr>
<tr>
<td>
10m
</td>
<td>
<input type="number" class="minutes" id="10m" name="10" min="0">
</td>
</tr>
<tr>
<td>
15m
</td>
<td>
<input type="number" class="minutes" id="15m" name="15" min="0">
</td>
</tr>
<tr>
<td>
30m
</td>
<td>
<input type="number" class="minutes" id="30m" name="30" min="0">
</td>
</tr>
<tr>
<td>
45m
</td>
<td>
<input type="number" class="minutes" id="45m" name="45" min="0">
</td>
</tr>
<tr>
<td>
60m
</td>
<td>
<input type="number" class="minutes" id="60m" name="60" min="0">
</td>
</tr>
<tr>
<td>
3h
</td>
<td>
<input type="number" class="hours" id="3h" name="3" min="0">
</td>
</tr>
<tr>
<td>
8h
</td>
<td>
<input type="number" class="hours" id="8h" name="8" min="0">
</td>
</tr>
<tr>
<td>
15h
</td>
<td>
<input type="number" class="hours" id="15h" name="15" min="0">
</td>
</tr>
<tr>
<td>
24h
</td>
<td>
<input type="number" class="hours" id="24h" name="24" min="0">
</td>
</tr>
<tr>
<td>
3d
</td>
<td>
<input type="number" id="3d" class="days" name="3" min="0">
</td>
</tr>
<tr>
<td>
7d
</td>
<td>
<input type="number" id="7d" class="days" name="7" min="0">
</td>
</tr>
<tr>
<td>
30d
</td>
<td>
<input type="number" id="30d" class="days" name="30" min="0">
</td>
</tr>
<tr>
<td colspan="2">
<button id="submit" class="submitbtn">Submit</button>
</td>
</tr>
<tr>
<td colspan="2">
<p id="results" class="resultarea"></p>
</td>
</tr>
</tbody>
</table>
Because there are 6 and because I’m trying to follow the DRY way of coding, I’m trying to create the least amount of code to do the job of scripting all 6 calculators. I mean, they’re all identical si this shouldn’t be hard, right?
This is the code that I thought would work. I don’t know what the problem is because it isn’t throwing any errors in the console. In a nutshell, the code is pretty similar to the first, except I tried to reference all tables via a .forEach
function. Also, I read that one way to reference children of an element is to give all of the children a class name and then use parentName.querySelectorAll('className')
(hence me trying to use it with table as the “parentName”).
const submitBtns = document.querySelectorAll('.subitbtn');
const tables = document.querySelectorAll('table');
const speedupInputs = document.querySelectorAll('.tableinput');
submitBtns.forEach((btn) => {
btn.addEventListener('click', myFunction);
});
function myFunction() {
tables.forEach((table) => {
const results = table.querySelector('.resultsarea');
let total = 0;
results.textContent = '';
speedupInputs.forEach((input) => {
if(input.value != '') {
if(input.classList.contains('minutes')) {
total += input.value * input.name;
} else if (input.classList.contains('hours')) {
total += (input.value * input.name) * 60;
} else if (input.classList.contains('days')) {
total += (input.value * input.name) * 60 * 24;
}
}
});
results.textContent = toTime(total * 60);
});
};
function toTime(seconds) {
const secsPerDay = 86400;
const secsPerHour = 3600;
const secsPerMinute = 60;
var minus = (this < 0) ? '-' : '';
var days = Math.floor(seconds / secsPerDay);
seconds = (seconds % secsPerDay);
var hours = Math.floor(seconds / secsPerHour);
seconds = (seconds % secsPerHour);
var minutes = Math.floor(seconds / secsPerMinute);
seconds = (seconds % secsPerMinute);
var sDays = new String(days).padStart(1, '0');
var sHours = new String(hours).padStart(2, '0');
var sMinutes = new String(minutes).padStart(2, '0');
return `${minus}${sDays}d ${sHours}:${sMinutes}:00`;
}
So yeah. To reiterate: I want 6 identical versions of these tables/calculators on a page, and I want one simple, easy code to script all 6 of them since they’re identical. Thank you.