Reputation: 39
I am currently trying to make an input that will take in decimal numbers and will auto format with thousand separators at the same time.
However, the only I can do auto format thousand separator is to set input type='text', which I cannot enter decimal numbers. Where as setting input type='number' allows me to input decimal number but it won't auto format with thousand separators
Here is the code:
<input
className="cal__section__form__container--input"
placeholder={0}
type="text"
value={displayVal || ""}
onChange={(e) => {
const targ = e.target.value.replace(/\D/g, "") || 0;
const displayVal = parseFloat(targ).toLocaleString(undefined, {
maximumFractionDigits: 2,
});
console.log(displayVal);
}}
/>
Upvotes: 2
Views: 3299
Reputation: 66
export default function App() {
const [value, setValue] = useState(0);
const addCommas = (num) =>
num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
const removeNonNumeric = (num) => num.toString().replace(/[^0-9]/g, "");
const handleChange = (event) =>
setValue(addCommas(removeNonNumeric(event.target.value)));
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<input type="text" value={value} onChange={handleChange} />
</div>
);
}
For a working example, you can check the sandbox link: Working Example.
Upvotes: 0
Reputation: 388
You're never updating your displayVal state. It's also good practice to handle your event logic outside of onChange. Here's how your code should look:
const handleChange = (e) => {
const value = e.target.value;
const clean = value.replace(/,/g, "");
const regex = /^[0-9]*\.?[0-9]*$/;
if (value && clean.match(regex)) {
if (!value.includes(".")) {
const formatted = new Intl.NumberFormat().format(parseFloat(clean));
setDisplayVal(formatted);
} else {
setDisplayVal(value);
}
} else {
setDisplayVal("");
}
};
<input
className="cal__section__form__container--input"
placeholder={0}
type="text"
value={displayVal}
onChange={handleChange}
/>
Upvotes: 5