数字のみを受け入れるReactNative TextInput


101

TextInput数字(0〜9)のみを入力できるReactNativeコンポーネントが必要です。ピリオド(。)を除いて、入力のためにほとんどそこに到達するkeyboardTypeまでnumericを設定できます。ただし、これは数値以外の文字をフィールドに貼り付けるのを止めるものではありません。

私がこれまでに思いついたのは、OnChangeTextイベントを使用して入力されたテキストを確認することです。テキストから数字以外の文字を削除します。次に、テキストを状態フィールドに入力します。次に、そのプロパティTextInputを介して更新しValueます。以下のコードスニペット。

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

これはうまくいくようですが、ハックのようです。これを行う別の方法はありますか?


この例が機能することはありません。他の方法でそれを解決することができましたか?
amb 2016年


React Native 0.54の時点で、ここで提案されている回答のほとんどが壊れていることに注意してください:github.com/facebook/react-native/issues/18874(少なくとも0.56まで、これは執筆時点での最新バージョンです)。
トムティ2018

1
@sumitkumarpradhanそのブログ投稿では、キーボードの種類を「数値」に設定することを提案していますが、これは実際にはテキスト入力を妨げません。好きなものをコピーしてそこに貼り付けることができます。
jmathew

keyboardType='numeric'TextInputでpropを使用して、数字キーボード(duh)のみを表示しtext.replace(/[^0-9]/g, '')、TextInput内に文字列を貼り付けないように、以下に示すようにテキストを正規表現に置き換えています。これまでのところ、React Native v0.62で正常に動作しています
keshavDulal

回答:


28

これは、そのようなコンポーネント(またはTextInputの属性)が具体的に開発されるまで、それを行う正しい方法です。

Webにはinput要素の「number」タイプがありますが、これはWebベースであり、react-nativeはWebビューを使用しません。

その入力をそれ自体でreactコンポーネントとして作成することを検討できます(おそらくNumberInputと呼ばれます)。これにより、さまざまな値のフィルター/チェッカーを持つ多くのTextInputを作成できるため、再利用したり、オープンソースにすることもできます。

即時修正の欠点は、ユーザーの価値に何が起こったのかについて混乱を防ぐために、ユーザーに正しいフィードバックが確実に提供されるようにすることです。


国コードを使用して設定するにはどうすればよいですか。(つまり)テキスト入力コンポーネントの小道具を使用して国コードを設定できますか
sejn

100

他の回答と同様に、RegExpを使用して数字以外を置き換える方が、forループをホワイトリストで使用するよりも高速です。

onTextChangeハンドラーにこれを使用します。

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

ここでのパフォーマンステスト:https//jsperf.com/removing-non-digit-characters-from-a-string


この方法を使用して英語のアルファベットの文字のみを許可するにはどうすればよいですか?
CraZyDroiD 2018

2
@CraZyDroiDは、正規表現を調整するだけです。AZとのみ一致させたい場合は、次のようなものが必要になりますtext.replace(/[^A-Za-z]/g, '')
Jake Taylor

1
また、keyboardType='numeric'propをTextInputフィールドに渡します。
keshavDulal

91

あなたはこのようにそれを行うことができます。数値のみを受け入れ、必要に応じて10個の数値に制限します。

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

ページに次のコードを書き込むと、入力した値を確認できます。

{this.state.myNumber}

onChanged()関数では、コードは次のようになります。

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

これが他の人の役に立つことを願っています。


小さな修正:onChanged(text){var newText = ''; 変数番号= '0123456789'; if(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 2016

1
良い答えですが、なぜ数字「9」が嫌いなのですか
Stanley Luo

19
7は9が​​嫌いなので?
ボートコーダー2017年

4
ちらつきを防ぐ方法はありますか?
ワルタリ2017年

あなたは最高の
仲間です

17

React Native TextInputは、keyboardType小道具に次の可能な値を提供します:デフォルトの数字パッド10進数パッド数字電子メールアドレス電話パッド

したがって、あなたの場合、keyboardType = 'number-pad'を使用して数字のみを受け入れることができます。これには「。」は含まれません。

そう、

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

あなたの場合に使用しなければならないものです。

詳細については、TextInputの公式ドキュメントリンクを参照してください:https//facebook.github.io/react-native/docs/textinput#keyboardtype


10

入力を検証する関数:

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

これがお役に立てば幸いです。


それはより効率的な方法です。ループする方法の代わりにそれに従う必要があります
AsifAli19年

10

正規表現を使用した数値のみを許可する

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

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

複数の検証が必要になる場合があります


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


これらの最初の二つの機能を作成する必要はありません、あなただけ使用することができます:validations(value: string) { return /0/.test(value) && /^\d+$/.test(value) ? this.setState({ numColumns: value }) : false; }
Frederikoセザール

2
単一責任の原則でかいま見を取る@FrederikoCesar
jasonleonhard

9

最初の解決策

keyboardType = 'numeric'テンキーに使用できます。

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

最初のケースでは、句読点が含まれています。例:- および-

2番目の解決策

正規表現を使用して句読点を削除します。

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

スナックリンクを確認してください

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


8

「onChangeText」がiOSで期待どおりにTextInput値を変更できないという問題に遭遇した人への親切なリマインダー:これは実際にはReactNativeのバグであり、バージョン0.57.1​​で修正されています。参照:https//github.com/facebook/react-native/issues/18874


これはコメントであり、答えではありません
HarisNadeem19年

1
質問にコメントするのに十分な評判がないことをお詫びします。そのため、実行可能な解決策を探している人々に注意を向けることができれば、答えになります。
ウィング

フェアポイント。コメントするには50の評判が必要だと思います。残念ながら、その制限を取り除くことはできませんが、10の評判を与えることができ、うまくいけばいくつかの制限を取り除くことができます。
HarisNadeem19年

コメントの提供を得るためにさらに10を取ります...乾杯@ウィング
ソム

ありがとう:)@ VenkateshSomu
ウィング

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

および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 });
    }
}

あなたの解決策は私の問題を解決しますが、警告を出します:"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."私はこれをどうしたらいいのかわかりません。手伝ってくれますか?
マイク

@Mike何らかのイベントがこれを引き起こす可能性がありますが、jsfiddleまたはrnplay.orgを介してコンポーネントコードを共有できますか
Bheru Lal

ここにコメントした直後に解決しましたが、残念ながら何が問題だったのか理解できます。
マイク

正規表現を使用する方が賢明です
AsifAli19年

4

iOSでも同じ問題が発生し、onChangeTextイベントを使用して、ユーザーが入力したテキストの値を更新しました。TextInputの値を更新できなかったため、ユーザーは入力した数字以外の文字を引き続き表示していました。

これは、数字以外の文字が押されたときに、this.setStateが同じ数字(数字以外の文字を削除した後に残った数字)を使用し、TextInputが再レンダリングされないため、状態が変更されないためです。

これを解決する唯一の方法は、onChangeTextイベントの前に発生するkeyPressイベントを使用し、その中でsetStateを使用して状態の値を別の完全に異なるものに変更し、onChangeTextイベントが呼び出されたときに再レンダリングを強制することでした。 。これにはあまり満足していませんが、うまくいきました。


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

!。/ ^ [0-9] + $ /テスト( '123456askm')は、入力文字列をチェックします.TEST数値またはではありません(使用値)
ANKIT-DETROJA

1
こんにちは、これがOPの問題の解決策になる理由についての回答を拡大してください。これは、OPおよびサイトの将来の訪問者に役立ちます。ありがとう!
d_kennetz

3

私はこの関数を作成しました。これは、ユーザーが自分が受け入れたいと思っている以外のものを入力できないようにするのに役立つことがわかりました。私も使用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 })
    }
}

最初のifブロックは、ユーザーがすべてのテキストを削除したり、最初の文字として小数点を使用したりする場合のエラー処理です。または、小数点以下1桁以上を入力しようとすると、2番目のifブロックで次のように入力できるようになります。小数点以下の桁数は必要ですが、小数点以下2桁までです。


2

RegExpを使用して数字以外を置き換えます。次のコードで見つけた最初の数字が表示されるので、ユーザーが複数の数字(xx.xx)を含む段落を貼り付けると、コードで最初の数字が表示されることに注意してください。これは、携帯電話ではなく、価格のようなものが必要な場合に役立ちます。

onTextChangeハンドラーにこれを使用します。

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

2

正規表現を使用して数字以外の文字を削除できます

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

1

これはIOSでは機能しません。setState-> render->テキストは変更されませんが、その他は変更できます。textOnChangeの場合、textinputはそれ自体の値を変更できません。

ちなみに、これはAndroidでうまく機能します。


他の人が理解できるように、サンプルコードで説明してください。
Bheru Lal Lohar 2017


1

正規表現を使用してテキストボックス内の数値のみを受け入れるためのもう1つの簡単な答えは次のとおりです。

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

1

10進数/浮動小数点数の場合はこれのみを試してください

    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

さて、これは0とは異なる数を検証する非常に簡単な方法です。

if (+inputNum)

inputNumが数値でない場合はNaNになり、0の場合はfalseになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.