Nikos
Nikos

Reputation: 7552

How to make a react native input which gives validation state feedback to the user. [Valid, Printine, Error, Editing]

I would like to have an input that updates continuously as the user types and then loses focus. The feedback will be a border around the input.

1 Green: when valid
2 Amber: when typing and is in error state (Green when valid)
3 Red: when in error state and unfocused
4 Nothing: when input is pristine (not touched and empty)

What is the best way to achieve this?

Ideally this will work with both iOS and Android.

Upvotes: 6

Views: 9204

Answers (1)

Nader Dabit
Nader Dabit

Reputation: 53681

TextInput has two functions that will be useful to achieve this:

onBlur and onChangeText

To dynamically set the style on the TextInput, you could attach a variable for the bordercolor like below:

<TextInput
  onBlur={ () => this.onBlur() }
  onChangeText={ (text) => this.onChange(text) }
  style={{ borderColor: this.state.inputBorder, height: 70, backgroundColor: "#ededed", borderWidth: 1 }} />

Then, pass the result from the onChangeText function through a regex or pattern matcher to achieve whatever result you are trying to achieve.

I've set up a working project here that checks if there is whitespace, and throws the errors you are wanting. You can take it and edit it to be more specific to your needs, but the basic premise should work the same. I've also put the code below for the working project that implements the functionality:

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TextInput
} = React;

var SampleApp = React.createClass({

  getInitialState: function() {
    return {
        inputBorder: '#eded',
      defaultVal: ''
    }
  },

  onBlur: function() {
    console.log('this.state.defaultVal', this.state.defaultVal)
    if(this.state.defaultVal.indexOf(' ') >= 0) {
        this.setState({
        inputBorder: 'red'
      })
    }
  },

  onChange: function(text) {
    this.setState({
        defaultVal: text
    })
    if(text.indexOf(' ') >= 0) {
        this.setState({
        inputBorder: '##FFC200'
      })
    } else {
        this.setState({
        inputBorder: 'green'
      })
    }
  },

  render: function() {
    return (
      <View style={styles.container}>
        <View style={{marginTop:100}}>
            <TextInput
            onBlur={ () => this.onBlur() }
            onChangeText={ (text) => this.onChange(text) }
            style={{ height: 70, backgroundColor: "#ededed", borderWidth: 1, borderColor: this.state.inputBorder }} />
        </View>
        <View style={{marginTop:30}}>
            <TextInput 
          style={{ height: 70, backgroundColor: "#ededed" }} />
        </View>
      </View>
    );
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,  
  }
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);

Upvotes: 8

Related Questions