problem
In business development, we often encounter the problem of pop-up numeric keyboard , The manufacturer hopes to pop up a pure numeric keyboard with a decimal point .
The following code :
<input type='number'/>
stay android Next can pop up the number and decimal point keyboard , And it automatically blocks illegal characters , Perfect. .
but iOS It's not a pure numeric keyboard , It's just that the first line of the keyboard is a number :
and iOS There is no way to prevent Chinese 、 Letter 、 Space 、 And all kinds of special symbols . And after entering these symbols, the bound value becomes empty , Unable to get the currently displayed content .
This keyboard is hard to handle , stay keydown input Wait for the event to do input interception 、 Filter , It's hard to deal with all the situations . Especially after switching to the Jiugongge keyboard, there is no way to deal with it .
Expected results
We want a keyboard like this :
This keyboard is used in many app Inside , And some component libraries .iOS It's easy to implement this numeric keyboard natively ,h5 It's more troublesome .
The solution is as follows :
This is a paragraph. vue Code :
<input v-model="purchaseMoney" type="text" inputmode="decimal" maxlength="12" placeholder=" No less than 0.01 element " @input="onInputAmount($event)" @blur="onInputBlur($event)">
utilize inputmode This attribute , Please refer to :https://developer.mozilla.org...
good , Now the keyboard is a number keyboard with a decimal point . stay iOS Next safari, Wechat and others have read about it , It's OK for now .
The keyboard is coming out , And then you need to write some logic to deal with illegal situations : Prevent copy and paste in special characters 、 Mask expression 、 Multiple decimal points coexist 、 There are many at the beginning 0、 Replace the beginning 0 For the new numbers 、 Control the decimal to 2 I'm waiting for you .
onInputAmount() {
let temp = this.purchaseMoney;
if (temp) {
temp = temp.replace(/[^0-9.]/g, '');
// There are multiple points in the string , Keep only the first , Filter out the rest
if (temp && temp.length && temp.indexOf('.') != temp.lastIndexOf('.')) {
var arr = temp.split('.');
let first = arr.shift();
temp = first + '.' + arr.join('');
}
// If the decimal part is intercepted most 2 position
if (temp.indexOf('.') != -1) {
let intergerPart = temp.split('.')[0];
let decimalPart = temp.split('.')[1];
if (decimalPart.length > 2) {
decimalPart = decimalPart.substring(0, 2);
}
temp = intergerPart + '.' + decimalPart;
}
// Remove the extra head 0
while (/^0[0-9]/.test(temp)) {
temp = temp.substring(1);
}
}
this.purchaseMoney = temp;
},
thus , The main functions are basically satisfied , If you find problems later, update it .