0

I'm trying to build a custom input component which does the following:

  • accept props - done
  • if onFocus true, render a "V" Icon - done
  • validate input: if text input is "filled with text" then check if validation is true, if true: change "V" icon color and ButtomBorderColor to green, if false: change "V" icon color and ButtomBorderColor to red, keep this styles until inputField is empty again
import React from "react";
import { View, TextInput, StyleSheet, Text } from "react-native";
import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import { MaterialCommunityIcons, AntDesign } from "@expo/vector-icons";

class RegisterTextBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      borderColor: "",
      isFocused: false,
    };
  }
  onBlur() {
    this.setState({ isFocused: false });
  }
  onFocus() {
    this.setState({ isFocused: true });
  }

  render() {
    const { isFocused } = this.state;
    const {
      value,
      placeholder,
      onChangeText,
      secureTextEntry,
      inputStyle,
      viewStyle,
      showIcon = this.state.showIcon,
      eyeIcon = false,
    } = this.props;
    return (
      <View style={[styles.container, viewStyle]}>
        <TextInput
          style={[styles.main, { borderBottomColor: this.state.borderColor }]}
          value={value}
          onChangeText={onChangeText}
          onBlur={() => this.onBlur()}
          onFocus={() => this.onFocus()}
          placeholder={placeholder}
          secureTextEntry={secureTextEntry}
          onChangeText={(val) => this.updateInputVal(val, "confirmPassword")}
        />
        {isFocused ? (
          <AntDesign
            name="checkcircle"
            size={18}
            color="black"
            style={{ paddingTop: 8 }}
          />
        ) : (
          <View />
        )}
        {eyeIcon ? (
          <MaterialCommunityIcons
            name="eye-off"
            size={24}
            color="black"
            style={{ paddingTop: 5, paddingLeft: 5 }}
          />
        ) : (
          <View />
        )}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    height: hp(5.4),
    width: wp(65.2),
    borderBottomWidth: 1,
    flexDirection: "row",
    justifyContent: "space-between",
  },
  main: {
    flex: 1,
  },
});

export default RegisterTextBox;

Niko Konovalov
  • 161
  • 1
  • 13

1 Answers1

1

I suggest you to keep a state value to be known whether TextInput filled with a text or not.

constructor(props) {
    super(props);
    this.state = {
      isTextFill: false,
      isFocused: false,
    };
}

Then check for input field has been filled the text or not when onChangeText triggers. I created a function to keep condition and rest of your code which has been figured onChangeText in TextInput.

onChangeTextEvent(text){
   if(text.length > 0){
      this.setState({
         isTextFill : true
      })
   } else {
      this.setState({
         isTextFill : false
      })
   }
   this.updateInputVal(text, "confirmPassword"); //the function that you had called. I don't know why and where that is. 
}

Then you can use conditional operator to manage your code.

return (
      <View style={[styles.container, viewStyle]}>
        <TextInput
          style={[styles.main, { borderBottomColor: this.state.isTextFill ? "green" : "red" }]}
          value={value}
          onBlur={() => this.onBlur()}
          onFocus={() => this.onFocus()}
          placeholder={placeholder}
          secureTextEntry={secureTextEntry}
          onChangeText={this.onChangeTextEvent.bind(this)}
        />
        {isFocused ? (
          <AntDesign
            name="checkcircle"
            size={18}
            color={this.state.isTextFill ? "green" : "red"}
            style={{ paddingTop: 8 }}
          />
        ) : (
          <View />
        )}
        {eyeIcon ? (
          <MaterialCommunityIcons
            name="eye-off"
            size={24}
            color={this.state.isTextFill ? "green" : "red"}
            style={{ paddingTop: 5, paddingLeft: 5 }}
          />
        ) : (
          <View />
        )}
      </View>
    );
Chanuka Sandeepa
  • 680
  • 6
  • 10