Blog: Creating a Cash Counter #1 (More Posts)
In this blog, or series of blogs I want to run through my latest project, which goes together nicely with what I’m doing with the Cashflow Forecaster and Budget Organiser. I want to build an application that counts money to help with banking deposits. It’s also another way to help count and organise your money.
I am of course seeking to do this with the help of AI.
When I’m using AI to code, I like to talk with it like I’m working collaboratively with another person.
We're going to build a cash counter application together. Here's the HTML I'm starting with. I wonder if you can figure out what it's going to do?
[HTML Code Snipped Out]
The HTML I did start with has 3 main structural elements at the top. A header element, a main element, and a footer element.
<header> . . . </header>
<main id="container"> . . . </main>
<footer> . . . </footer>
Inside, the <main> element, there are 2 direct child article elements. One element will hold all the input fields where users interact and add data, and the second is where all the calculated values will go.
<article class="input_bracket_container"> . . . </article>
<article class="calculations_container"> . . . </article>
The engine of this app is in the thing is the input brackets container element. Here are the main money denominations. That is in the left column. The second column is the number counted, the the final column is the multiplied calculation.
£50.00 3 £150.00
£20.00 2 £40.00
£10.00 15 £0.00
£5.00 1 £0.00
S&I 1 £0.00
£2.00 1 £0.00
£1.00 1 £0.00
£0.50 1 £0.00
£0.20 1 £0.00
£0.10 1 £0.00
£0.05 1 £0.00
£0.02 1 £0.00
£0.01 1 £0.00
Below there will be a similar table for inputing up to 10 cheque amounts. This one will be a slightly different table as people can write cheques for all sorts of amounts and are not restricted by denomination amounts.
Items - Cheques
Reverse Side
1 £0.00
2 £0.00
3 £0.00
4 £0.00
5 £0.00
6 £0.00
7 £0.00
8 £0.00
9 £0.00
10 £0.00
TOTAL 0.00
Initially, I asked ChatGPT to describe the app based on the HTML I gave it. And I was pleased to see that it accurately described what I wanted the app to do.
That's correct. We're going to build this step by step. I forgot to provide a reference to the script file where all the magic will happen.
<script type="text/javascript" src="app.js"></script>
Let's start with the £50 denomination in the .input_brackets class. We need to multiply 50 by the value in #input_50 and display that value in real time in #calc_50.
We can now start doing some counting calculations. The goal is to allow the user to enter any positive number and multiply that number by the money denomination. e.g. 3 multiplied by 50 would be £150.00. We can do that by selecting the input and calculation elements individually and attaching event listeners to them. Each input element needs to be checked that it is a valid number. But we’ve kind of made sure of that by giving the input elements the “number” type because it now only accepts a non negative number by default.
// Wait for the DOM content to be fully loaded
document.addEventListener('DOMContentLoaded', function() {
// Get the input field for £50 denomination
var input50 = document.getElementById('input_50');
// Get the output field for the calculated total
var calc50 = document.getElementById('calc_50');
// Add event listener for input changes in the £50 input field
input50.addEventListener('input', function() {
// Get the value entered in the £50 input field and convert it to a number
var inputValue = parseFloat(input50.value);
// Check if the entered value is a valid number
if (!isNaN(inputValue)) {
// Calculate the total by multiplying the value by 50
var total = inputValue * 50;
// Display the total in the calculated total field
calc50.value = '£' + total.toFixed(2); // Format the total with 2 decimal places and prepend £
} else {
// If the entered value is not a valid number, display 0.00 in the calculated total field
calc50.value = '£0.00';
}
});
});
With this function, we have the total sum of £50 notes updating in real-time according to the value of the £50 number input. At this point, I “told” ChatGPT about some fixes to some bugs I noticed and went on to fix for myself. I removed the string concatenation on the calculated value to remove the £ sterling character and added min attributes to the input fields, to make sure users are unable to input negative numbers which would mess up the app.
This is a good start. And it has worked. I've added a min attribute to #input_50 and set it to 0 so the user cannot input a negative value. I've also edited the placeholder attribute to 0 which reflects all of the initial values in the table.
Finally I've removed the sting concatenation applied to cal50.value as the currency is displayed via a character entity. So that fixes a few bugs.
Let's repeat this for the £20 denomination.
With this, I went on to repeat the input50 listener for the £20 denomination.
// Add event listener for input changes in the £20 input field
input20.addEventListener('input', function() {
// Get the value entered in the £20 input field and convert it to a number
var inputValue = parseFloat(input20.value);
// Check if the entered value is a valid number
if (!isNaN(inputValue)) {
// Calculate the total by multiplying the value by 20
var total = inputValue * 20;
// Display the total in the calculated total field
calc20.value = total.toFixed(2); // Format the total with 2 decimal places
} else {
// If the entered value is not a valid number, display 0.00 in the calculated total field
calc20.value = '0.00';
}
});
This would introduce 25 lines of code for every money denomination we want to calculate. There’s probably a better way to write this code.
We now have 2 sets of code that do the same thing. I can already see code bloat happening that needs to be improved. But before that, let's get the .cash_total element up and running. We need this element to update dynamically so that it shows is the sum total of the calculated £50 and £20 denominations
So, before we set about to work out that problem, we need to make sure that the .cash_total element works so that it calculates the total sum of each of the money denominations and does this in real time.
Start by selecting the .cash_total element.
// Get the output field for the cash total
var cashTotal = document.querySelector('.cash_total');
And then attaching an event listener on both of the number input fields
// Add event listeners for input changes in the £50 and £20 input fields
input50.addEventListener('input', updateCashTotal);
input20.addEventListener('input', updateCashTotal);
// Initialize the cash total when the page loads
updateCashTotal();
Now it’s time to write the function. In this function, we retrieve the numbers from the value elements and convert them to floating-point number. We then get the total value by multiplying the numbers by each integer representing the money bracket.
// Function to update the cash total
function updateCashTotal() {
// Get the values entered in the £50 and £20 input fields and convert them to numbers
var value50 = parseFloat(input50.value) || 0; // Default to 0 if input is invalid or empty
var value20 = parseFloat(input20.value) || 0; // Default to 0 if input is invalid or empty
// Calculate the sum total of £50 and £20 denominations
var total = (value50 * 50) + (value20 * 20);
// Display the total in the cash total element
cashTotal.textContent = '£' + total.toFixed(2); // Format the total with 2 decimal places and prepend £
}
We now have the sum total working in real-time. But only for the 2 cash denominations.
There are at least 12 different cash denominations for the app to calculate. So let’s go back to that problem I mentioned earlier about reducing the code bloat.
Let's see if we can find a better way to do the many money denominations.
[code snipped]
These event listeners take up approximately 25 lines of code. How can we refactor this code to reduce this unneeded code bloat?
We can refactor the code by creating a reusable function that handles the input event for any money denomination. This function will take the input field, the output field, and the denomination value as parameters.
function handleMoneyInput(inputField, outputField, denomination) {
}
We can then use a single event listener called, .inputField to handle all the calculation logic for us.
inputField.addEventListener('input', function() {
}
Rather than using an integer in the function, we can pass in the value, when we need it, using the denomination parameter.
// Function to handle input event for money denomination
function handleMoneyInput(inputField, outputField, denomination) {
// Add event listener for input changes in the input field
inputField.addEventListener('input', function() {
// Get the value entered in the input field and convert it to a number
var inputValue = parseFloat(inputField.value);
// Check if the entered value is a valid number
if (!isNaN(inputValue)) {
// Calculate the total by multiplying the value by the denomination
var total = inputValue * denomination;
// Display the total in the output field
outputField.value = '£' + total.toFixed(2); // Format the total with 2 decimal places and prepend £
} else {
// If the entered value is not a valid number, display 0.00 in the output field
outputField.value = '£0.00';
}
});
}
// Get the input field and output field for £50 denomination
var input50 = document.getElementById('input_50');
var calc50 = document.getElementById('calc_50');
// Call the function to handle input for £50 denomination
handleMoneyInput(input50, calc50, 50);
// Get the input field and output field for £20 denomination
var input20 = document.getElementById('input_20');
var calc20 = document.getElementById('calc_20');
// Call the function to handle input for £20 denomination
handleMoneyInput(input20, calc20, 20);
The way this is organised can be looked at later. What’s happening here is the DOM selections, event listener and function calls are all being compartmentalised by denomination. But it all does the trick. It doesn’t repeat the underlying logic in the event listener. All are handled by arguments passed to the same function, which we can call as many times as we need in a way that is easy to read and maintain.
Conclusion
I think we can leave things there for this part of the project. We have calculated 2 money denominations and dynamically updated the grand total in real-time. Next, we’re going to try and hook up all the other money calculations for both notes and coins.


