Tip calculator made in vanilla JavaScript

Solution retrospective
I am quite happy with the UX of the calculator, the implementation of the custom tip button, and how I handled invalid inputs. Using regex testing on the keydown
event, I made sure that only digits can be entered (and dots/commas if the input allows decimals). The calculator also removes any leading zeros live as you type.
Next time, I would probably use <input type="text">
instead of <input type="number">
, because <input type="number">
has some quirks (for example, it returns an empty value if the input is invalid), which made some of the features harder to implement. Or better yet, I would try using an external library for validation and input restrictions instead of doing it all manually.
There were many challenges. I will try to describe the biggest ones:
-
The custom button styling and logic
My solution: a
<label>
covers the whole custom button. When clicked, it becomes invisible and reveals the custom tip input field under it. It also instantly focuses it, allowing the user to type the custom tip value. In case the user doesn't type anything and clicks away, the custom button returns to its initial state. -
Giving the custom tip input field a placeholder % symbol that moves live with entered text
My solution: wrap the input field inside a
<div>
together with a<span>%</span>
. Give the wrapperdisplay: flex
, center both elements, and make sure the input is only as wide as the text inside it using JavaScript:customTipInput.addEventListener("input", () => { const length = customTipInput.value.length; customTipInput.style.setProperty("--dynamic-width", `${Math.max(length, 1)}ch`); });
-
Restrict what the user can type inside the input fields and how many digits can they type before and after decimal dot
My solution: If you'd like to see the code, it's the
restrictInput
function inscript.js
. On input of type text this wouldn't be challenging to do, but browser quirks and differences on<input type="number">
made it frustrating (e.g. when retrieving value from the input field to manipulate it, Chrome returns an empty value if the input is currently invalid, while Firefox returns the last valid one in that case). However, the (hopefully) working code that I reached after many iterations turns out to be fairly simple.
If you test the calculator and notice anything that doesn't feel right, please mention it. It's important to me that it works properly. In case you also take the time to look at the code and have suggestions, don't hesitate to comment; I am happy to hear any feedback.
Please log in to post a comment
Log in with GitHubCommunity feedback
- @nerdynischal
Everything works really well, liked that the input was restricted to avoid any faulty inputs like letters. It is also identical to the design and really well done.
Join our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord