Last active
July 18, 2023 15:18
-
-
Save BananaAcid/30600d75c102dbac8906298d74c8bee5 to your computer and use it in GitHub Desktop.
HTML number input with rules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Nabil Redmann, ISC | |
/* | |
<input type="number" maxlength="3" data-digits="2" placeholder="format xxx.xx" /> | |
<br><br><br> | |
<input type="number" maxlength="3" data-digits="0" placeholder="no fractions" /> | |
<br><br><br> | |
<input type="number" maxlength="0" data-digits="3" placeholder="only dot first and digits " /> | |
*/ | |
export default function numberFieldsMagic() { | |
//document.addEventListener('DOMContentLoaded', e => { | |
// '[type="number"][maxlength]' | |
document.querySelectorAll('[type="number"]').forEach( (element) => { | |
let el = element as HTMLInputElement; | |
console.log(el); | |
// prepare element | |
el.dataset.type = el.dataset.type ?? el.type; | |
el.type = 'text'; | |
el.dataset.maxLength = el.dataset.maxLength ?? ''+el.maxLength; | |
if (el.attributes.getNamedItem('maxlength')) | |
el.attributes.removeNamedItem('maxlength'); | |
el.addEventListener('input', oIe => { | |
//console.log(oIe); | |
let t = oIe.target as HTMLInputElement; | |
let digits = +(t.dataset.digits ?? 2); | |
let pos = t.selectionStart ?? 0; // only works, if type="text" | |
let x = 0; | |
let dataStart = t.value; | |
let data = t.value; | |
data = data | |
// only allow: - , . 01234567890 | |
.replace(/[^-,.0-9]/g, '') | |
// comma will become dots | |
.replaceAll(',', '.') | |
// only one dot | |
.replace(/\./g, (c, i, text) => text.indexOf(c) === i ? c : '') | |
// no .00 | |
.replace(/\.00/g, '') | |
// limit digits | |
.replace(/\.\d+/, (c, i, text) => {x++; return c.slice(0, digits + 1);}) | |
; | |
if (data && data[0] == '0' && data[1] !== '.') { | |
data = data.slice(1); | |
} | |
// digits before dot, allow 0 as length | |
if (t.dataset.maxLength !== undefined && t.dataset.maxLength !== '-1') { | |
// regex needs a leading digit to work | |
if (data[0] == '.') { | |
data = '0' + data; | |
x++ | |
}; | |
data = data | |
.replace(/(\d+)([\.]|$)/, (complete, group1, group2) => group1.slice(0, t.dataset.maxLength) + group2.trim()) | |
} | |
if (data !== dataStart) { | |
t.value = data; | |
let substract = (data.length < dataStart.length) ? -1 : 0; | |
substract += x; | |
t.selectionStart = pos + substract; | |
t.selectionEnd = pos + substract; | |
} | |
}); | |
el.addEventListener('blur', oBe => { | |
let t = oBe.target as HTMLInputElement; | |
let dataStart = t.value; | |
let data = t.value; | |
// no trailing dot | |
data = data.replace(/\.$/, ''); | |
if (data && data[0] == '0' && data[1] !== '.') { | |
data = data.slice(1); | |
} | |
if (data[0] == '.') { | |
data = '0' + data; | |
} | |
/* Force '0' on leaving field | |
if (data.trim() == '') | |
data = '0'; | |
*/ | |
if (data !== dataStart) { | |
t.value = data; | |
} | |
}); | |
});//querySelectorAll.forEach | |
//});//DOMContentLoaded | |
}//FN |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment