React Native TextInput chỉ chấp nhận các ký tự số


101

Tôi cần có một TextInputthành phần React Native sẽ chỉ cho phép nhập các ký tự số (0 - 9). Tôi có thể thiết lập keyboardTypeđể numericmà gần như được tôi có cho đầu vào ngoại trừ dấu chấm (.). Tuy nhiên, điều này không có gì ngăn cản việc dán các ký tự không phải số vào trường.

Những gì tôi đã nghĩ ra cho đến nay là sử dụng OnChangeTextsự kiện để xem văn bản đã nhập. Tôi xóa mọi ký tự không phải số khỏi văn bản. Sau đó đặt văn bản vào một trường trạng thái. Sau đó cập nhật tài sản TextInputcủa nó Value. Đoạn mã bên dưới.

<TextInput 
  style={styles.textInput}
  keyboardType = 'numeric'
  onChangeText = {(text)=> this.onChanged(text)}
  value = {this.state.myNumber}
/> 

onTextChanged(text) {
  // code to remove non-numeric characters from text
  this.setState({myNumber: text})
}

Điều này có vẻ hiệu quả nhưng nó có vẻ giống như một vụ hack. Có một cách khác để làm điều này?


Không bao giờ có ví dụ này để làm việc. Bạn có quản lý để giải quyết nó theo cách nào khác không?
amb


Lưu ý rằng kể từ React Native 0.54, hầu hết các câu trả lời được đề xuất ở đây đều bị hỏng: github.com/facebook/react-native/issues/18874 (tối thiểu là 0.56, là phiên bản mới nhất tại thời điểm viết bài).
Tomty

1
@sumitkumarpradhan Bài đăng trên blog đó đề xuất đặt loại bàn phím thành 'số', điều này không thực sự ngăn việc nhập văn bản. Bạn có thể sao chép, dán bất cứ thứ gì bạn muốn vào đó.
jmathew

Tôi đang sử dụng keyboardType='numeric'prop trong TextInput để chỉ hiển thị Bàn phím số (duh) và cũng thay thế văn bản bằng regex text.replace(/[^0-9]/g, '')như được đề xuất bên dưới để ngăn bất kỳ ai dán chuỗi bên trong TextInput. Cho đến nay vẫn hoạt động tốt trên React Native v0.62
keshavDulal

Câu trả lời:


28

Đó là cách chính xác để làm điều đó cho đến khi một thành phần như vậy (hoặc thuộc tính trên TextInput) được phát triển cụ thể.

Trang web có loại 'số' cho phần tử đầu vào, nhưng đó là dựa trên web và phản ứng gốc không sử dụng chế độ xem web.

Bạn có thể xem xét việc tạo đầu vào đó như một thành phần phản ứng của riêng nó (có thể gọi NumberInput): điều đó sẽ cho phép bạn sử dụng lại nó hoặc thậm chí có thể là nguồn mở nó vì bạn có thể tạo nhiều TextInput có các bộ lọc / kiểm tra giá trị khác nhau.

Nhược điểm của việc sửa chữa ngay lập tức là đảm bảo phản hồi chính xác được cung cấp cho người dùng để tránh nhầm lẫn về những gì đã xảy ra với giá trị của họ


Làm cách nào để đặt mã quốc gia. (
Tức

100

Sử dụng RegExp để thay thế bất kỳ chữ số nào sẽ nhanh hơn so với sử dụng vòng lặp for với danh sách trắng, giống như các câu trả lời khác.

Sử dụng cái này cho trình xử lý onTextChange của bạn:

onChanged (text) {
    this.setState({
        mobile: text.replace(/[^0-9]/g, ''),
    });
}

Kiểm tra hiệu suất tại đây: https://jsperf.com/removing-non-digit-characters-from-a-string


Làm cách nào để tôi có thể chỉ cho phép các chữ cái trong bảng chữ cái tiếng Anh bằng phương pháp này?
CraZyDroiD

2
@CraZyDroiD chỉ cần điều chỉnh regex. Nếu bạn chỉ muốn để phù hợp với AZ, bạn sẽ cần một cái gì đó giống nhưtext.replace(/[^A-Za-z]/g, '')
Jake Taylor

1
Đồng thời chuyển phần keyboardType='numeric'hỗ trợ vào trường TextInput.
keshavDulal

91

Bạn có thể làm điều đó như thế này. Nó sẽ chỉ chấp nhận các giá trị số và giới hạn ở 10 số như mong muốn của bạn.

<TextInput 
   style={styles.textInput}
   keyboardType='numeric'
   onChangeText={(text)=> this.onChanged(text)}
   value={this.state.myNumber}
   maxLength={10}  //setting limit of input
/>

Bạn có thể xem giá trị đã nhập bằng cách viết mã sau vào trang của mình:

{this.state.myNumber}

Trong hàm onChanged (), mã trông như thế này:

onChanged(text){
    let newText = '';
    let numbers = '0123456789';

    for (var i=0; i < text.length; i++) {
        if(numbers.indexOf(text[i]) > -1 ) {
            newText = newText + text[i];
        }
        else {
            // your call back function
            alert("please enter numbers only");
        }
    }
    this.setState({ myNumber: newText });
}

Tôi hy vọng điều này sẽ hữu ích cho những người khác.


Chỉnh sửa nhỏ: onChanged (text) {var newText = ''; var number = '0123456789'; if (text.length <1) {this.setState ({myNumber: ''}); } for (var i = 0; i <text.length; i ++) {if (number.indexOf (text [i])> -1) {newText = newText + text [i]; } this.setState ({myNumber: newText}); }}
Bheru Lal Lohar

1
Câu trả lời tốt, nhưng tại sao bạn ghét số '9'
Stanley Luo

19
Vì 7 ghét 9?
boatcoder

4
Có cách nào để ngăn chặn hiện tượng nhấp nháy không?
Waltari

bạn là những người bạn tốt nhất
Khadam Ikhwanus

17

React Native TextInput cung cấp các đạo cụ keyboardType với các giá trị có thể có sau: mặc định số-pad thập phân-pad số-địa chỉ email phone-pad

vì vậy đối với trường hợp của bạn, bạn có thể sử dụng keyboardType = 'number-pad' để chỉ chấp nhận các số. Điều này không bao gồm '.'

vì thế,

<TextInput 
  style={styles.textInput}
  keyboardType = 'number-pad'
  onChangeText = {(text)=> this.onChanged(text)}
  value = {this.state.myNumber}
/>

là những gì bạn phải sử dụng trong trường hợp của bạn.

để biết thêm chi tiết, vui lòng tham khảo liên kết tài liệu chính thức cho TextInput: https://facebook.github.io/react-native/docs/textinput#keyboardtype


10

Chức năng xác thực đầu vào:

validateInputs(text, type) {
let numreg = /^[0-9]+$/;
  if (type == 'username') {
    if (numreg.test(text)) {
      //test ok
    } else {
      //test not ok
    } 
  }
}



<TextInput
   onChangeText={text => this.validateInputs(text, 'username')}
/>

Tôi hy vọng điều này là hữu ích.


đó là cách hiệu quả hơn, nó nên được làm theo thay vì phương pháp lặp
Asif Ali

10

Chỉ cho phép các số sử dụng biểu thức chính quy

<TextInput 
  keyboardType = 'numeric'
  onChangeText = {(e)=> this.onTextChanged(e)}
  value = {this.state.myNumber}
/> 

onTextChanged(e) {
  if (/^\d+$/.test(e.toString())) { 
    this.setState({ myNumber: e });
  }
}

Bạn có thể muốn có nhiều hơn một xác thực


<TextInput 
  keyboardType = 'numeric'
  onChangeText = {(e)=> this.validations(e)}
  value = {this.state.myNumber}
/> 

numbersOnly(e) {
    return /^\d+$/.test(e.toString()) ? true : false
}

notZero(e) {
    return /0/.test(parseInt(e)) ? false : true
}

validations(e) {
    return this.notZero(e) && this.numbersOnly(e)
        ? this.setState({ numColumns: parseInt(e) })
        : false
}


Không cần phải tạo ra hai chức năng đầu tiên này, bạn chỉ có thể sử dụng:validations(value: string) { return /0/.test(value) && /^\d+$/.test(value) ? this.setState({ numColumns: value }) : false; }
Frederiko Cesar

2
@FrederikoCesar Đi một peek tại nguyên tắc trách nhiệm duy nhất
jasonleonhard

9

Giải pháp đầu tiên

Bạn có thể sử dụng keyboardType = 'numeric'cho bàn phím số.

  <View style={styles.container}>
        <Text style={styles.textStyle}>Enter Number</Text>
        <TextInput
          placeholder={'Enter number here'}
          style={styles.paragraph}
          keyboardType="numeric"
          onChangeText={value => this.onTextChanged(value)}
          value={this.state.number}
        />
      </View>

Trong trường hợp đầu tiên, các dấu câu được bao gồm, ví dụ: - . -

Giải pháp thứ hai

Sử dụng biểu thức chính quy để xóa dấu chấm câu.

 onTextChanged(value) {
    // code to remove non-numeric characters from text
    this.setState({ number: value.replace(/[- #*;,.<>\{\}\[\]\\\/]/gi, '') });
  }

Vui lòng kiểm tra liên kết đồ ăn nhẹ

https://snack.expo.io/@vishal7008/numeric-keyboard


8

Một lời nhắc nhỏ cho những ai gặp phải sự cố rằng "onChangeText" không thể thay đổi giá trị TextInput như mong đợi trên iOS: đó thực sự là một lỗi trong ReactNative và đã được sửa trong phiên bản 0.57.1. Tham khảo tại: https://github.com/facebook/react-native/issues/18874


Đây phải là một bình luận và không phải là một câu trả lời
Haris Nadeem

1
Xin lỗi rằng tôi không có đủ uy tín để bình luận về câu hỏi nên tôi kết thúc bằng một câu trả lời, hy vọng sẽ thu hút sự chú ý của những người đang tìm kiếm giải pháp khả thi.
Cánh

Điểm công bằng. Tôi thấy rằng một người sẽ cần 50 danh tiếng để bình luận. Rất tiếc, tôi không thể xóa hạn chế đó, nhưng tôi có thể cung cấp cho bạn 10 danh tiếng và hy vọng loại bỏ một số hạn chế.
Haris Nadeem

mang nó 10 hơn để có được cung cấp bình luận ... Cheers @Wing
Venkatesh Somu

Cảm ơn :) @VenkateshSomu
Wing

4
<TextInput autoCapitalize={'none'} maxLength={10} placeholder='Mobile Number'  value={this.state.mobile} onChangeText={(mobile) => this.onChanged(mobile)}/>

và phương thức onChanged:

onChanged(text){
   var newText = '';
   var numbers = '0123456789';
   if(text.length < 1){
     this.setState({ mobile: '' });
   }
   for (var i=0; i < text.length; i++) {
        if(numbers.indexOf(text[i]) > -1 ) {
             newText = newText + text[i];
        }
        this.setState({ mobile: newText });
    }
}

Giải pháp của bạn, mặc dù giải quyết được vấn đề của tôi, nhưng lại đưa ra cảnh báo: "This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property 'type' on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See fb>react-event-pooling for more information."Tôi không biết phải làm gì với điều này. Bạn có thể giúp?
Mike

@ Mike một số sức mạnh sự kiện gây ra điều này, bạn có thể chia sẻ mã thành phần của bạn qua jsfiddle hoặc rnplay.org
Bheru Lal Lohar

Tôi đã giải quyết vấn đề đó ngay sau khi bình luận ở đây, nhưng không may có thể tìm ra vấn đề là gì.
Mike

sử dụng regex sẽ là một lựa chọn thông minh hơn
Asif Ali

4

Tôi gặp sự cố tương tự trong iOS, khi sử dụng sự kiện onChangeText để cập nhật giá trị của văn bản do người dùng nhập. Tôi không thể cập nhật giá trị của TextInput, vì vậy người dùng vẫn sẽ thấy các ký tự không phải số mà anh ta đã nhập.

Điều này là do, khi một ký tự không phải số được nhấn, trạng thái sẽ không thay đổi vì this.setState sẽ sử dụng cùng một số (số vẫn còn sau khi loại bỏ các ký tự không phải số) và khi đó TextInput sẽ không hiển thị.

Cách duy nhất tôi tìm thấy để giải quyết vấn đề này là sử dụng sự kiện keyPress xảy ra trước sự kiện onChangeText và trong đó, sử dụng setState để thay đổi giá trị của trạng thái thành một trạng thái khác, hoàn toàn khác, buộc kết xuất khi sự kiện onChangeText được gọi . Không hài lòng lắm với điều này nhưng nó đã hoạt động.


4
if (!/^[0-9]+$/.test('123456askm')) {
  consol.log('Enter Only Number');
} else {
    consol.log('Sucess');
}

! / ^ [0-9] + $ /. Test ('123456askm') nó sẽ kiểm tra chuỗi đầu vào là số hay không .test (Giá trị của bạn)
ANKIT-DETROJA

1
Xin chào, vui lòng mở rộng câu trả lời của bạn tại sao đây sẽ là giải pháp cho vấn đề của OP. Điều này sẽ giúp OP và những khách truy cập trong tương lai của trang web. Cảm ơn!
d_kennetz

3

Tôi đã viết hàm này mà tôi thấy là hữu ích để ngăn người dùng không thể nhập bất kỳ thứ gì khác ngoài tôi sẵn sàng chấp nhận. Tôi cũng đã sử dụng keyboardType="decimal-pad"onChangeText={this.decimalTextChange}

  decimalTextChange = (distance) =>
{
    let decimalRegEx = new RegExp(/^\d*\.?\d*$/)
    if (distance.length === 0 || distance === "." || distance[distance.length - 1] === "."
        && decimalRegEx.test(distance)
    ) {
        this.setState({ distance })
    } else {
        const distanceRegEx = new RegExp(/^\s*-?(\d+(\.\d{ 1, 2 })?|\.\d{ 1, 2 })\s*$/)
        if (distanceRegEx.test(distance)) this.setState({ distance })
    }
}

Khối đầu tiên iflà xử lý lỗi cho sự kiện người dùng xóa tất cả văn bản hoặc sử dụng dấu thập phân làm ký tự đầu tiên hoặc nếu họ cố gắng đặt nhiều hơn một chữ số thập phân, ifkhối thứ hai đảm bảo họ có thể nhập bằng nhiều số như họ muốn trước vị trí thập phân, nhưng chỉ tối đa hai chữ số thập phân sau dấu chấm.


2

Sử dụng RegExp để thay thế bất kỳ chữ số nào. Hãy cẩn thận, mã tiếp theo sẽ cung cấp cho bạn chữ số đầu tiên anh ta tìm thấy, vì vậy nếu người dùng dán đoạn văn có nhiều hơn một số (xx.xx), mã sẽ cung cấp cho bạn số đầu tiên. Điều này sẽ hữu ích nếu bạn muốn thứ gì đó như giá, không phải điện thoại di động.

Sử dụng cái này cho trình xử lý onTextChange của bạn:

onChanged (text) {
    this.setState({
        number: text.replace(/[^(((\d)+(\.)\d)|((\d)+))]/g,'_').split("_"))[0],
    });
}

2

Bạn có thể xóa các ký tự không phải số bằng regex

onTextChanged (text) {
    this.setState({
        myNumber: text.replace(/\D/g, ''),
    });
}

1

Điều này không hoạt động trên IOS, setState -> render -> không thay đổi văn bản, nhưng có thể thay đổi khác. Textinput không thể tự thay đổi giá trị khi textOnChange.

Nhân tiện, tính năng này hoạt động tốt trên Android.


Vui lòng giải thích bằng mã ví dụ để người khác có thể hiểu.
Bheru Lal Lohar


1

Đây là câu trả lời đơn giản khác của tôi để chỉ chấp nhận các số trong hộp văn bản bằng Biểu thức chính quy.

onChanged(text){
    this.setState({ 
         myNumber: text.replace(/[^0-9]/g, '') 
    });
}

1

Đối với số thập phân / dấu phẩy động, chỉ thử điều này

    onChangeMyFloatNumber(text){
let newText = '';
let numbers = '0123456789.';

for (var i=0; i < text.length; i++) {
    if(numbers.indexOf(text[i]) > -1 ) {
        newText = newText + text[i];
        if(text[i]=="."){
          numbers = '0123456789'
        }
    }
    else {
        // your call back function
        alert("please enter numbers only");
    }
}
this.setState({ MyFloatNumber: newText });

}


0

Đây là một cách rất đơn giản để xác nhận một số khác 0.

if (+inputNum)

Nó sẽ là NaN nếu inputNum không phải là số hoặc false nếu nó là 0

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.