Reputation: 2439
I want let users enter only integer or floating numbers. Right now I can only enter integer numbers,it does allow type dot or comma . Cant find proper regex to validate both integer and floating numbers.
<input
type="text"
id="depositedAmount"
maxLength={9}
placeholder="Enter amount"
onChange={(e) => this.handleInputChange(e, currentComProfile)}
value={depositedAmount}
/>
handleInputChange=(e, currentComProfile) => {
const re = /^[+-]?\d+(\.\d+)?$/;
if (e.target.value === '' || re.test(e.target.value)) {
if (e.target.id === 'depositedAmount') {
this.props.updateDepositedAmount(e.target.value, currentComProfile);
}
if (e.target.id === 'willBeCreditedAmount') {
this.props.updateWillBeCreditedAmount(e.target.value, currentComProfile);
}
}
}
Upvotes: 2
Views: 5010
Reputation: 13
function App() {
const [budget, setBudget] = useState(0);
const handleKeyPress = (ev) => {
let charC = (ev.which) ? ev.which : ev.keyCode;
if(charC == 46) {
if(ev.target.value.indexOf('.') === -1) {
let caretPos = ev.target.selectionStart;
if(caretPos <= (ev.target.value.length - 3)) {
ev.preventDefault();
return false;
}
return true;
}
else {
ev.preventDefault();
return false;
}
}
else {
if(charC > 31 && (charC < 48 || charC > 57)) {
ev.preventDefault();
return false;
}
}
if(ev.target.value.indexOf('.') !== -1) {
let numComp = ev.target.value.split('.');
if(numComp[1].length > 1) {
let caretPos = ev.target.selectionStart;
let dotPos = ev.target.value.indexOf('.');
if(caretPos <= dotPos) {
return true;
}
ev.preventDefault();
return false;
}
}
return true;
}
const handleChange = (ev) => {
setBudget(ev.target.value);
}
return (
<div className="App">
<div className="input-control">
<label>
Iznos proračuna:
<input
type="text"
value={budget}
onKeyPress={(event) => handleKeyPress(event) }
onChange={(event) => handleChange(event)}
/>
</label>
</div>
</div>
);
}
export default App;
Explanation: React is a bit different than 'pure' JavaScript. 'handlePress' function is like already suggested solutions in pure JavaScript but instead returning 'false' one should use ev.preventDefault() prior to returning false to prevent displaying unwanted characters. Displaying decimal dot is allowed only once in input field and input is limited to max 2 decimal places, so decimal point can be in front of max 2 last digits on the right. Code can be customized for other purposes as well :)
Upvotes: 0
Reputation: 626738
You may use
const rx_live = /^[+-]?\d*(?:[.,]\d*)?$/;
for live validation. For the final validation, use
const rx_final = /^[+-]?\d+(?:[.,]\d+)?$/;
Or, better, just use the regex in the pattern
attribute: pattern="[+-]?\d*(?:[.,]\d*)?"
.
NOTE
^
- start of string[+-]?
- an optional +
or -
\d*
- 0 or more digits(?:[.,]\d*)?
- an optional sequence of .
or ,
and then 0 or more digits$
- end of string.In final validation, \d+
is used instead of \d*
to match one or more digits as opposed tozero or more digits.
See the JS demo:
const rx_live = /^[+-]?\d*(?:[.,]\d*)?$/;
class TestForm extends React.Component {
constructor() {
super();
this.state = {
depositedAmount: ''
};
}
handleDepositeAmountChange = (evt) => {
if (rx_live.test(evt.target.value))
this.setState({ depositedAmount : evt.target.value });
}
render() {
return (
<form>
<input
type="text"
id="depositedAmount"
maxLength={9}
pattern="[+-]?\d+(?:[.,]\d+)?"
placeholder="Enter amount"
onChange={this.handleDepositeAmountChange}
value={this.state.depositedAmount}
/>
</form>
)
}
}
ReactDOM.render( < TestForm /> , document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Upvotes: 1
Reputation: 6735
Your regex should match dots, but it doesn't seem to match commas. You could try something like:
^[0-9]+([,.][0-9]+)?$
For reference:
[0-9] matches digits 0-9.
+ matches between one and unlimited times, as many times as possible.
[,.] matches comma or dot.
There might be a way to simplify this regex, but I think it should work.
You can test it here: https://regex101.com/r/V0J63U/1
--Update--
To match leading signs also (i.e., +/-), you can add ^[+-]?
to the beginning of the pattern:
^[+-]?[0-9]+([,.][0-9]+)?$
You can test it here: https://regex101.com/r/cQylX3/1
Thank you to @CodeManiac for the tips!
Upvotes: 0