React Native TextInput sadece sayısal karakterleri kabul eder


102

TextInputYalnızca sayısal karakterlerin (0 - 9) girilmesine izin verecek bir React Native bileşenine ihtiyacım var . Ben ayarlayabilirsiniz keyboardTypeiçin numericneredeyse orada dönemi hariç girişi için beni alır ki (.). Ancak bu, sayısal olmayan karakterleri alana yapıştırmayı durdurmaz.

Şimdiye kadar bulduğum şey OnChangeText, girilen metne bakmak için olayı kullanmak . Metinden sayısal olmayan tüm karakterleri kaldırıyorum. Ardından metni bir durum alanına koyun. Daha sonra özelliği TextInputaracılığıyla güncelleyin Value. Aşağıdaki kod parçacığı.

<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})
}

Bu işe yarıyor gibi görünüyor ama bir hile gibi görünüyor. Bunu yapmanın başka bir yolu var mı?


Bu örnek hiç işe yaramadı. Başka bir şekilde çözmeyi başardınız mı?
amb


React Native 0.54 itibariyle, burada önerilen cevapların çoğunun bozuk olduğuna dikkat edin : github.com/facebook/react-native/issues/18874 (en az 0,56'ya kadar, bu yazım sırasındaki en yeni sürümdür).
Tomty

1
@sumitkumarpradhan Bu blog yazısı, klavye tipinin metin girişini gerçekten engellemeyen 'sayısal' olarak ayarlanmasını öneriyor. Oraya istediğiniz her şeyi kopyalayıp yapıştırabilirsiniz.
jmathew

keyboardType='numeric'TextInput'ta prop kullanıyorum yalnızca Sayısal Klavye'yi (duh) göstermek ve ayrıca metinleri, text.replace(/[^0-9]/g, '')herhangi birinin TextInput içine dizeleri yapıştırmasını önlemek için aşağıda önerildiği gibi regex ile değiştiriyorum . Şimdiye kadar üzerinde Yerli v0.62 Tepki iyi çalışıyor
keshavDulal

Yanıtlar:


28

Böyle bir bileşen (veya TextInput üzerindeki öznitelik) özel olarak geliştirilinceye kadar bunu yapmanın doğru yolu budur.

Web, giriş öğesi için 'sayı' türüne sahiptir, ancak bu web tabanlıdır ve react-native bir web görünümünü kullanmaz.

Bu girdiyi kendi başına bir react bileşeni olarak oluşturmayı düşünebilirsiniz (belki NumberInput'u çağırabilirsiniz): bu, onu yeniden kullanmanıza veya hatta açık kaynak kodlu hale getirmenize olanak sağlar çünkü farklı değer filtreleri / denetleyicileri olan birçok TextInputs oluşturabilirsiniz.

Anında düzeltmenin dezavantajı, değerine ne olduğu konusunda kafa karışıklığını önlemek için kullanıcıya doğru geribildirim verilmesini sağlamaktır.


Ülke kodunu nasıl ayarlayabilirim? (Yani) ülke kodunu metin girişi bileşenindeki herhangi bir sahne ile ayarlayabilir miyim
sejn

101

Rakam olmayan herhangi bir şeyi değiştirmek için bir RegExp kullanmak, diğer yanıtlarda olduğu gibi beyaz listeli bir for döngüsü kullanmaktan daha hızlıdır.

Bunu onTextChange işleyiciniz için kullanın:

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

Performans testi burada: https://jsperf.com/removing-non-digit-characters-from-a-string


Bu yöntemi kullanarak sadece ingilizce alfabesindeki harflere nasıl izin verebilirim?
CraZyDroiD

2
@CraZyDroiD sadece normal ifadeyi ayarlayın. Sadece AZ ile eşleşmek istiyorsan, şöyle bir şeye ihtiyacın olacaktext.replace(/[^A-Za-z]/g, '')
Jake Taylor

1
Ayrıca keyboardType='numeric'prop'u TextInput alanına iletin.
keshavDulal

92

Bunu böyle yapabilirsin. Yalnızca sayısal değerleri kabul eder ve isteğinize göre 10 sayı ile sınırlandırır.

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

Aşağıdaki kodu sayfanıza yazarak girilen değeri görebilirsiniz:

{this.state.myNumber}

OnChanged () işlevinde kod şu şekilde görünür:

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 });
}

Umarım bu başkalarına yardımcı olur.


Küçük düzeltme: onChanged (metin) {var newText = ''; var numaraları = '0123456789'; eğer (text.length <1) {this.setState ({myNumber: ''}); } for (var i = 0; i <text.length; i ++) {if (numbers.indexOf (text [i])> -1) {newText = newText + text [i]; } this.setState ({myNumber: newText}); }}
Bheru Lal Lohar

1
Güzel cevap, ama neden '9' sayısından nefret ediyorsunuz
Stanley Luo

19
Çünkü 7, 9'dan nefret mi ediyor?
boatcoder

4
Titremeyi önlemenin bir yolu var mı?
Waltari

siz en iyi arkadaşlarsınız
Khadam Ikhwanus

17

React Native TextInput, aşağıdaki olası değerlere sahip keyboardType aksesuarları sağlar: varsayılan sayısal tuş takımı ondalık tuş takımı sayısal e-posta adresi telefon-pedi

bu nedenle, sizin durumunuz için yalnızca sayıları kabul etmek için keyboardType = 'number-pad' kullanabilirsiniz. Buna "." Dahil değildir.

yani,

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

sizin durumunuzda kullanmanız gereken şeydir.

Daha fazla ayrıntı için lütfen TextInput için resmi belge bağlantısına bakın: https://facebook.github.io/react-native/docs/textinput#keyboardtype


10

Girişi doğrulama işlevi:

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')}
/>

Umarım bu yardımcı olur.


bu daha verimli bir yol, döngü yöntemi yerine takip edilmeli
Asif Ali

10

Yalnızca normal ifade kullanan sayılara izin ver

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

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

Birden fazla doğrulamaya sahip olmak isteyebilirsiniz


<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
}


Bu ilk iki işlevi oluşturmanıza gerek yok, sadece şunları kullanabilirsiniz:validations(value: string) { return /0/.test(value) && /^\d+$/.test(value) ? this.setState({ numColumns: value }) : false; }
Frederiko Cesar

2
@FrederikoCesar Tek sorumluluk ilkesine bir göz atın
jasonleonhard

9

İlk Çözüm

keyboardType = 'numeric'Sayısal klavye için kullanabilirsiniz .

  <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>

İlk durumda noktalama işaretleri dahil edilir, örn: - . ve -

İkinci Çözüm

Noktalama işaretlerini kaldırmak için normal ifade kullanın.

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

Lütfen atıştırmalık bağlantısını kontrol edin

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


8

"OnChangeText" in iOS'ta TextInput değerini beklendiği gibi değiştiremeyeceği sorunuyla karşılaşanlara nazik bir hatırlatma: bu aslında ReactNative'de bir hatadır ve 0.57.1 ​​sürümünde düzeltilmiştir. Bakın: https://github.com/facebook/react-native/issues/18874


Bu bir yorum olmalı, cevap değil
Haris Nadeem

1
Soruyu yorumlayacak kadar itibarım olmadığı için özür dilerim, bu yüzden bir cevap bulabilirim, umarım işe yarar çözümler arayan insanlara dikkat çekmek için.
Wing

Doğru tespit. Yorum yapmak için 50 itibara ihtiyaç olduğunu görüyorum. Maalesef bu kısıtlamayı kaldıramıyorum, ancak size 10 itibar verebilir ve umarım bazı kısıtlamaları kaldırabilirim.
Haris Nadeem

Yorum sağlamak için 10 tane daha al ... Şerefe @Wing
Venkatesh

Teşekkürler :) @VenkateshSomu
Wing

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

ve onChanged yöntemi:

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 });
    }
}

Çözümünüz, sorunumu çözmesine rağmen uyarı üretiyor: "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."Bununla ne yapacağımı bilmiyorum. Yardım edebilir misin?
Mike

Bu neden bazı olay kudretini @ Mike, sen jsfiddle veya rnplay.org aracılığıyla bileşen kod paylaşabilir
Bheru Lal Lohar

Burada yorum yaptıktan kısa bir süre sonra bunu çözdüm ama ne yazık ki sorunun ne olduğunu anlayabiliyorum.
Mike

bir normal ifade kullanmak daha akıllıca bir seçim olacaktır
Asif Ali

4

Kullanıcı tarafından yazılan metnin değerini güncellemek için onChangeText olayını kullanan iOS'ta da aynı sorunu yaşadım, TextInput değerini güncelleyemiyordum, böylece kullanıcı yine de yazdığı sayısal olmayan karakterleri görebiliyordu.

Bunun nedeni, sayısal olmayan bir karaktere basıldığında, this.setState'in aynı sayıyı (sayısal olmayan karakterleri kaldırdıktan sonra kalan sayı) kullanması ve ardından TextInput'un yeniden oluşturulmaması nedeniyle durumun değişmemesiydi.

Bunu çözmenin tek yolu, onChangeText olayından önce meydana gelen keyPress olayını kullanmak ve bunun içinde, setState'i, onChangeText olayı çağrıldığında yeniden oluşturmayı zorlayarak, durumun değerini başka bir tamamen farklı bir şekilde değiştirmek için kullanmaktı. . Bundan pek memnun değilim ama işe yaradı.


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

! / ^ [0-9] + $ /. Test ('123456askm') giriş dizesinin sayısal olup olmadığını kontrol eder
.test

1
Merhaba, lütfen bunun neden OP sorununa bir çözüm olacağına dair cevabınızı genişletin. Bu, OP'ye ve sitenin gelecekteki ziyaretçilerine yardımcı olacaktır. Teşekkürler!
d_kennetz

3

Kullanıcının kabul etmeye istekli olduğum dışında herhangi bir şeye girmesini engellemek için yararlı bulduğum bu işlevi yazdım. Ben de kullandım keyboardType="decimal-pad"ve benimonChangeText={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 })
    }
}

İlk ifblok, kullanıcının tüm metni silmesi veya ilk karakter olarak bir ondalık nokta kullanması durumunda veya birden fazla ondalık basamak koymaya çalışırlarsa, ikinci ifblok, ondalık basamaktan önce istedikleri kadar sayı, ancak noktadan sonra yalnızca iki ondalık basamak.


2

Rakam olmayanları değiştirmek için bir RegExp kullanma. Dikkatli olun, sonraki kod size bulduğu ilk rakamı verecektir, bu nedenle kullanıcı birden fazla sayı (xx.xx) içeren bir paragraf yapıştırırsa, kod size ilk numarayı verecektir. Cep telefonu değil, fiyat gibi bir şey istiyorsanız bu yardımcı olacaktır.

Bunu onTextChange işleyiciniz için kullanın:

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

2

Normal ifade kullanarak sayısal olmayan karakterleri kaldırabilirsiniz

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

1

Bu IOS üzerinde çalışmaz, setState -> render -> metni değiştirmez, ancak diğerini değiştirebilir. Textinput, textOnChange olduğunda kendi değerini değiştiremez.

bu arada, Bu Android'de iyi çalışıyor.


Lütfen başkalarının anlayabilmesi için örnek kodla açıklayın.
Bheru Lal Lohar


1

Normal İfadeler kullanarak yalnızca metin kutusundaki sayıları kabul etmek için diğer basit cevabım.

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

1

Ondalık / Kayan nokta numarası için yalnızca bunu deneyin

    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

Bu, 0'dan farklı bir sayıyı doğrulamanın çok basit bir yoludur.

if (+inputNum)

İnputNum bir sayı değilse NaN, 0 ise false olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.