只有数字。反应中的输入数字

我试图从输入中排除正负号,但是出错了:

handleChange(event) {
const value = event.target.value.replace(/\+|-/ig, '');
this.setState({financialGoal: value});
}

渲染输入码:

<input style={{width: '150px'}} type="number" value={this.state.financialGoal} onChange={this.handleChange}/>
304874 次浏览

我试图模仿你的代码,并注意到 “反应”有个问题<input type='number' />。为了解决这个问题,检查这个示例并自己尝试: https://codepen.io/zvona/pen/WjpKJX?editors=0010

您需要将其定义为普通输入(type = ‘ text’) ,并且只对数字使用模式:

    <input type="text" pattern="[0-9]*"
onInput={this.handleChange.bind(this)} value={this.state.financialGoal} />

然后比较输入的有效性:

const financialGoal = (evt.target.validity.valid) ?
evt.target.value : this.state.financialGoal;

这种方法最大的警告是当它涉及到移动-> ,键盘不是数字,而是正常的字母格式。

  • 要停止输入,请使用 onKeyPress而不是 onChange

  • onKeyPress中使用 event.preventDefault()意味着停止按压事件。

  • 因为 keyPress处理程序是在 onChange之前触发的,所以您必须检查按下的键(event.keyCode) ,而不是输入的当前值(event.target.value)

    onKeyPress(event) {
    const keyCode = event.keyCode || event.which;
    const keyValue = String.fromCharCode(keyCode);
    if (/\+|-/.test(keyValue))
    event.preventDefault();
    }
    

Demo below 👇🏻

const {Component} = React;


class Input extends Component {
  



onKeyPress(event) {
const keyCode = event.keyCode || event.which;
const keyValue = String.fromCharCode(keyCode);
if (/\+|-/.test(keyValue))
event.preventDefault();
}
render() {
  

return (
<input style=\{\{width: '150px'}} type="number" onKeyPress={this.onKeyPress.bind(this)} />


)
}
 

}


ReactDOM.render(<Input /> , document.querySelector('#app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


<section id="app"></section>

一行代码

<input value={this.state.financialGoal} onChange={event => this.setState({financialGoal: event.target.value.replace(/\D/,'')})}/>

如果您想维护输入 type='number'(可能是为了移动设备触发数字键盘) ,您应该使用 onInput而不是 onChange来捕获事件更改。

使用 onInput修正了一个错误,在数字输入中键入文本将绕过我在 onChange中分配给它的验证。一旦我修复了这个函数在 onInput中被调用,它就会在所有实例中触发。

下面是我正在做的一个例子:

<input
type='number'
id={`player${index}Score`}
className='form-control'
pattern='[0-9]{0,5}'
onInput={(event) => this.enterScore(event, index)}
value={this.props.scoreLabel(this.state.scores[index])}
/>

希望这个能帮上忙!

编辑: 2018年8月3日:

我想出了一个更好的解决方案,在输入组件本身中使用 type = ‘ tel’和模式 regex。

我接线的具体细节如下:

class Input extends React.Component {
state = {message: '3'};


updateNumber = (e) => {
const val = e.target.value;
// If the current value passes the validity test then apply that to state
if (e.target.validity.valid) this.setState({message: e.target.value});
// If the current val is just the negation sign, or it's been provided an empty string,
// then apply that value to state - we still have to validate this input before processing
// it to some other component or data structure, but it frees up our input the way a user
// would expect to interact with this component
else if (val === '' || val === '-') this.setState({message: val});
}


render() {
return (
<input
type='tel'
value={this.state.message}
onChange={this.updateNumber}
pattern="^-?[0-9]\d*\.?\d*$"
/>
);
}
}


ReactDOM.render(<Input />, document.getElementById('main'));

我有一个在 我是 Codepen上工作的例子

也许对某些人会有帮助
最近我在我的应用程序中使用了这个解决方案
我不确定这是否是一个正确的解决方案,但它确实有效。

this.state = {
inputValue: "",
isInputNotValid: false
}


handleInputValue = (evt) => {
this.validationField(evt, "isInputNotValid", "inputValue");
}


validationField = (evt, isFieldNotValid, fieldValue ) => {
if (evt.target.value && !isNaN(evt.target.value)) {
this.setState({
[isFieldNotValid]: false,
[fieldValue]: evt.target.value,
});
} else {
this.setState({
[isFieldNotValid]: true,
[fieldValue]: "",
});
}
}


<input className={this.state.isInputNotValid ? "error" : null} type="text" onChange="this.handleInputValue" />

主要的思想是,状态不会更新,直到条件不为真,值为空。
不需要使用 onKeyPress,Down 等等,< br/> 如果你使用这些方法,它们在触摸设备上不起作用

解决方案

今天我发现使用 parseInt()也是一个很好的干净的实践。

密码

onChange(e){
this.setState({[e.target.id]: parseInt(e.target.value) ? parseInt(e.target.value) : ''})
}

解释

  1. 如果参数不是数字,则 parseInt()将返回 NaN
  2. parseInt('12a')将返回12。

使用 onChange()方法定义一个输入,如下所示(在我的示例中,child State 包含状态,并传递给这个子组件)。

<input
...
value={this.props.childState.volume}
...
onChange={(e) => handleChangeInteger(e, {volume: e.target.value})}
/>

我使用的一种方法是安装 校验器 JS(npm install validator --save)

然后,我定义了一个函数 handleChangeInteger,它接受一个用于更改状态的对象,在本例中为 {volume: e.target.value}。注意: 我需要 OR 条件来允许我的输入为空,否则它不会让用户退格(删除)最后一个整数,如果他们希望字段为空。

const handleChangeInteger = (e, obj_to_return) => {
if (validator.isInt(e.target.value) || e.target.value == '') {
this.props.childSetState(obj_to_return)
}
}

用户现在不允许输入任何东西,除了回退空间,0-9,或 e (这是一个数字。.)在输入域中。

我引用这篇文章来创建我的解决方案: https://stackoverflow.com/a/45676912/6169225

我找到的最有效、最简单的解决办法是:

<input
type="number"
name="phone"
placeholder="Phone number"
onKeyDown={e => /[\+\-\.\,]$/.test(e.key) && e.preventDefault()}
/>

2019年推迟回答,但希望能帮到别人

这将确保在空文本字段上不会得到 null

  • 文本字段值始终为0
  • 后退时,结束时将为0
  • 当值为0并开始键入时,0将被替换为实际数字
// This will make sure that value never is null when textfield is empty


const minimum = 0;


export default (props) => {
const [count, changeCount] = useState(minimum);


function validate(count) {
return parseInt(count) | minimum
}


function handleChangeCount(count) {
changeCount(validate(count))
}


return (
<Form>
<FormGroup>
<TextInput
type="text"
value={validate(count)}
onChange={handleChangeCount}
/>
</FormGroup>
<ActionGroup>
<Button type="submit">submit form</Button>
</ActionGroup>
</Form>
);
};

在你的输入栏上设置类:

$(".digitsOnly").on('keypress',function (event) {
var keynum
if(window.event) {// IE8 and earlier
keynum = event.keyCode;
} else if(event.which) { // IE9/Firefox/Chrome/Opera/Safari
keynum = event.which;
} else {
keynum = 0;
}


if(keynum === 8 || keynum === 0 || keynum === 9) {
return;
}
if(keynum < 46 || keynum > 57 || keynum === 47) {
event.preventDefault();
} // prevent all special characters except decimal point
}

限制你的输入栏上的粘贴和拖放:

$(".digitsOnly").on('paste drop',function (event) {
let temp=''
if(event.type==='drop') {
temp =$("#financialGoal").val()+event.originalEvent.dataTransfer.getData('text');
var regex = new RegExp(/(^100(\.0{1,2})?$)|(^([1-9]([0-9])?|0)(\.[0-9]{1,2})?$)/g); //Allows only digits to be drag and dropped
if (!regex.test(temp)) {
event.preventDefault();
return false;
}
} else if(event.type==='paste') {
temp=$("#financialGoal").val()+event.originalEvent.clipboardData.getData('Text')
var regex = new RegExp(/(^100(\.0{1,2})?$)|(^([1-9]([0-9])?|0)(\.[0-9]{1,2})?$)/g); //Allows only digits to be pasted
if (!regex.test(temp)) {
event.preventDefault();
return false;
}
}
}

在 Component entDidMount ()中调用这些事件,以便在页面加载后立即应用该类。

在阅读了所有的答案,但没有真正工作的数字只有复制和粘贴我想出了这个解决方案。

  • parseInt解决方案: 失败,因为 parseInt("2a")是有效的;
  • onKeyup sulution:复制粘贴失败,退格;
  • 解决方案: 复制粘贴可能失败;
  • Type = “ number”解决方案: 当 javascript将40817810000000023511转换为40817810000000023500时,长数失败,因为它是53位语言
<input
name="address.line1"
value={values.address.line1}
onChange={(event: any) => {
if (isFinite(event.target.value)) {
// UPDATE YOUR STATE (i am using formik)
setFieldValue("address.line1", event.target.value);
}
}}
/>
 <input
className="input-Flied2"
type="TEXT"
name="userMobileNo"
placeholder="Moble No"
value={phonNumber}
maxLength="10"
onChange={handleChangeInput}
required
/>


const handleChangeInput = (e) => {
const re = /^[0-9\b]+$/; //rules
if (e.target.value === "" || re.test(e.target.value)) {
setPhoneNumber(e.target.value);
}

};

这里有一个解决方案与 onBlur,它可以是非常有帮助的,因为它还允许您格式化的数字,您需要它的方式,而不需要任何黑魔法或外部库。

2020反应钩

const toNumber = (value: string | number) => {
if (typeof value === 'number') return value
return parseInt(value.replace(/[^\d]+/g, ''))
}


const formatPrice = (price: string | number) => {
return new Intl.NumberFormat('es-PY').format(toNumber(price))
}
<input
defaultValue={formatPrice(price)}
onBlur={e => {
const numberValue = toNumber(e.target.value)
setPrice(numberValue)
e.target.value = formatPrice(numberValue)
}}
type='tel'
required
/>

工作原理:

  • 通过 defaultValue设置初始值
  • 允许用户自由输入他们感觉到的任何东西
  • OnBlur (一旦输入失去焦点) :
    • 用空字符串替换非数字的任何字符
    • SetState ()或 send ()来管理状态
    • 将输入字段的值设置为数值并应用可选的格式设置

注意: 如果您的值来自异步源(例如,提取) : 因为 defaultValue 只会在第一次呈现时设置值,所以您需要确保只在数据存在时才呈现组件。

以下是我的普通 Javascript 解决方案

keyup事件附加到您选择的 input字段-本例中为 id
在事件处理函数中,只需用给定的正则表达式测试 event.key的键。

在这种情况下,如果它不匹配,我们阻止了元素的默认操作-所以一个“错误的”按键在输入框中将不会被注册,因此它将永远不会出现在输入框中。

  let idField = document.getElementById('id');


idField.addEventListener('keypress', function(event) {
if (! /([0-9])/g.test(event.key)) {
event.preventDefault();
}
});

这种解决方案的好处可能是它的灵活性,通过更改和/或逻辑链接正则表达式可以满足许多需求。 例如,正则表达式 /([a-z0-9-_])/g应该只匹配小写英文字母数字字符,没有空格,只允许 -_

注意: 如果使用 /[a-z]/gi(注意最后的 )将忽略 信箱,并将仍然接受大写字母。

简单的反应

<input
onKeyPress={(event) => {
if (!/[0-9]/.test(event.key)) {
event.preventDefault();
}
}}
/>

您可以尝试这个解决方案,因为 onkeypress 将直接附加到 DOM 元素,并从一开始就防止用户输入无效数据。

所以在反应方面没有副作用。

<input type="text" onKeyPress={onNumberOnlyChange}/>


const onNumberOnlyChange = (event: any) => {
const keyCode = event.keyCode || event.which;
const keyValue = String.fromCharCode(keyCode);
const isValid = new RegExp("[0-9]").test(keyValue);
if (!isValid) {
event.preventDefault();
return;
}
};

我使用的是 JS 的 isNaN 函数来验证它是否是数字。

const handleChange2 = (e) => {
if (isNaN(e.target.value)) {
return;
}
const onlyNums = e.target.value.replace(/[^0-9]/g, "");
setFormData({
...formData,
[e.target.name]: onlyNums,
});
};


const [formData, setFormData] = useState({
name: "",
phone: "",
email: "",
address: "",
});


<input
value={phone}
onChange={(e) => handleChange2(e)}
placeholder="Phone"
type="text"
name="phone"
required
/>

注意: 存储在状态中的值将是字符串,如果您希望它是一个数字/整数,只需使用数字将其转换为整数。例如: let phone = Number (formData.phone)

我们可以像这样使用 Terinary 操作符,也可以使用 useState 来设置对象的值

<input id="cost" name="cost" type="text" onChange = {e=>isNaN(e.target.value)?e.target.value="":setItem({...item,cost:parseInt(e.target.value)})} />


                   

我找到的最快的方法是添加一个 onKeyPress:

<input
type="text"
name="example"
value="Type here"
onKeyPress={(event) => {
if (!/[0-9]/.test(event.key)) {
event.preventDefault();
}
}}
>
handleChange(event) {
const value = event.target.value
let finalValue;
Number.isNaN(parseInt(value)) ? finalValue = 0 : finalValue = parseInt(value)


this.setState({financialGoal: finalValue});


}

使用模式验证以允许 点(用于小数点)而不允许空格。需要在 setState ()中传递一个箭头函数,以便在将状态值放回输入字段后立即更新状态值。

* 考虑类组件

给出状态变量的一些上下文。

constructor(props) {
super(props);
this.state = {inputValue: ''};
};

输入字段内容是根据 pattern正则表达式计算的。如果两者都匹配,则将事件的 validity.valid属性指定为 true,否则为 false:

<input
pattern = '[0-9]*\.?[0-9]*'
type = 'text'
value = {this.state.inputValue}
onChange = {this.handleChange}
...>

handleChange中,如果 validity.valid为 true,状态将立即更新,否则将保留以前的值(并且输入字段中的文本不会更改)。

handleChange = (e) => {
this.setState((prevState) => (
e.target.validity.valid ? {inputValue: e.target.value} : prevState)
)
};

如果你想同时处理 ., (无)作为一个数字的输入,那么你可以使用这个组合:

<input
type='number'
pattern='[0-9]+([\,|\.][0-9]+)?'
step='1'
value={this.state.financialGoal}
onChange={this.handleChange}
/>

e.target.value将是一个 string,然后可以在需要时解析它以浮动(就像传递给后端调用时一样)。这意味着 financialGoal仍然是一个数字,但应该是字符串格式。

默认情况下,十进制值或无数字通常不能很好地处理,所以这样我就有了一个作为数字的受控字符串输入。

class FinancialApp extends React.Component {
constructor(props) {
super(props)
this.state = {
financialGoal: '5,5'
}
this.handle
}


handleChange = (e) => {
this.setState({
financialGoal: e.target.value
})
console.log(`${e.target.validity.valid} ${this.state.financialGoal}`)
}


render() {
return ( <
div >
<
p > {
this.state.financialGoal
} < /p> <
input placeholder = 'finanical goal'
type = 'number'
pattern = '[0-9]+([\,|\.][0-9]+)?'
step = '1'
value = {
this.state.financialGoal
}
onChange = {
this.handleChange
}
/> <
/div>
)
}
}


ReactDOM.render( < FinancialApp / > , document.querySelector("#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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="app"></div>