它是html5输入的包装器,带有自定义验证。遇到输入类型编号的无数限制,我决定切换到文本类型。不幸的是,这个应用程序必须在移动环境中运行,客户要求当用户专注于输入时,数字键盘会出现。我尝试使用onFocus和onBlur事件实现动态类型切换,这些事件在iOS设备上运行良好。然而,此代码在Android设备上中断:似乎类型不会更改,并且正则表达式不会应用于输入。
我正在创建一个反应输入组件
class InputNumber extends Component {
constructor(props) {
super(props);
this.re = props.regex ? props.regex : /^(?:[1-9]\d*(?:\.\d{0,2})?)?$/;
}
componentWillReceiveProps(nextProps) {
// check new props and reassign the stake if needed
if (this.input && this.currentVal !== nextProps.newValue) {
if (nextProps.newValue === "0") {
this.input.value = "";
} else {
this.input.value = nextProps.newValue;
}
}
}
makeTypeText = e => {
e.target.type = "text";
};
makeTypeNumber = e => {
e.target.type = "number";
};
setValue = e => {
const re = this.re; // pattern that we will validate our input against
const currentVal = e.target.value.split(""); // in order to validate we need to know what would be the next value
const newChar = e.key; // we transform the current value into an array and
let nextVal = [...currentVal]; // create a new array with previous values
const start = e.target.selectionStart; // and then place the input char into the current cursor position
const end = e.target.selectionEnd;
if (e.key === "Backspace") {
// if backspace is typed
if (start === end) {
nextVal.splice(start - 1, 1); // if there is no selection just delete the digit before the cursor
} else {
nextVal.splice(start, end - start); // if the user has selected several digits just replace them with empty string
}
} else if (e.key === "Delete") {
// if delete is typed
if (start === end) {
nextVal.splice(start, 1); // delete a digit before after the cursor if no selection
} else {
nextVal.splice(start, end - start); // delete selection
}
} else {
nextVal.splice(start, end - start, e.key); // insert digit before the cursor or replace selection with a digit
}
const valueAfterInput = nextVal.join("");
// check the value that would result from input against the regular expression
if (!re.test(valueAfterInput)) {
e.preventDefault(); // if the next value is invalid we prevent the user action
} else {
this.currentVal =
valueAfterInput.slice(-1) === "."
? valueAfterInput.substr(0, valueAfterInput.length - 1)
: valueAfterInput; // assign the current value to a class variable so we can check it against incoming props
this.props.action(valueAfterInput); // dispatch an action
}
};
render() {
return (
<div className="form-field__input">
<input
type="number"
onKeyDown={this.setValue}
onFocus={this.makeTypeText}
onBlur={this.makeTypeNumber}
ref={input => (this.input = input)}
className={cn("form-input", "form-input_focus", {
"form-input_orange": this.props.hideCurrency
})}
placeholder={t("Stake...")}
/>
<span
className={cn(
"form-field__action",
"form-field__action_showed",
"form-field__action_text",
{hidden: this.props.hideCurrency}
)}
>
₽
</span>
</div>
);
}
}
InputNumber.propTypes = {
newValue: PropTypes.string,
hideCurrency: PropTypes.bool.isRequired,
action: PropTypes.func.isRequired,
regex: PropTypes.object
};
export default InputNumber;
有关如何纠正这种情况的任何想法?
P.S。:在理解问题之前停止标记为重复。