JSFiddle - React, Tailwind, and code Playground
by Grax_
HTML
<div id="container">
<div>
<h1>General pattern</h1>
<input type="text" id="generalInput" />
<span>
<p>Output:</p>
<p id="generalOutput"></p>
</span>
</div>
<div>
<h1>Specific pattern</h1>
<input type="text" id="specificInput" />
<span>
<p>Output:</p>
<p id="specificOutput"></p>
</span>
</div>
</div>
CSS
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
body,
#container {
display: flex;
justify-content: space-evenly;
align-items: center;
}
#container {
width: 100%;
flex-direction: row;
}
p {
margin-top: 10px;
font-size: 24px;
min-height: 24px;
}
input,
input:focus-visible {
font-size: 24px;
border: 2px solid;
outline: none;
}
.error {
border-color: red;
color: red;
}
.success {
border-color: green;
color: green;
}
JavaScript
const generalRegex =
/^ ?(?:\d{1,3}[,. ](?=\d{3}))*?\d*(?:(?<=\d)|(?=[,.]\d))([,.])?\d* ?$/
const specificRegex =
/^ ?(?:\d{1,3}[. ](?=\d{3}))*?\d*(?:(?<=\d)|(?=[,]\d))([,])?\d* ?$/
const generalIn = document.getElementById("generalInput")
const generalOut = document.getElementById("generalOutput")
const specificIn = document.getElementById("specificInput")
const specificOut = document.getElementById("specificOutput");
[generalIn, specificIn].forEach((input) => {
input.addEventListener("input", (_) => {
// Only allow numbers, commas, dots and spaces.
// Disallow more than one comma, dot or space.
input.value = input.value
.replace(/[^\d,. ]/g, "")
.replace(/([,. ]){2,}/g, "$1")
const value = input.value.trim()
if (input.id.includes("general")) {
if (value === "" || generalRegex.test(value)) {
input.classList.remove("error")
generalOut.previousElementSibling.classList.remove("error")
generalOut.classList.remove("error")
input.classList.add("success")
generalOut.previousElementSibling.classList.add("success")
generalOut.classList.add("success")
} else {
input.classList.add("error")
generalOut.previousElementSibling.classList.add("error")
generalOut.classList.add("error")
input.classList.remove("success")
generalOut.previousElementSibling.classList.remove("success")
generalOut.classList.remove("success")
}
generalOut.textContent = parseGeneralNumber(value)
} else {
if (value === "" || specificRegex.test(value)) {
input.classList.remove("error")
specificOut.previousElementSibling.classList.remove("error")
specificOut.classList.remove("error")
input.classList.add("success")
specificOut.previousElementSibling.classList.add("success")
specificOut.classList.add("success")
} else {
input.classList.add("error")
...