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;

1 Answer 1

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>
    );
Sign up to request clarification or add additional context in comments.

4 Comments

Tried it, I get an error that this setState is not a function
Yes, that because onChageTextEvent function has not been boud with "this" object. that should be resolved as this.OnChangeTextEvent.bind(this). I change the code as well. try now.
Could you please explain the bind solution?
stackoverflow.com/questions/50726014/… here is a better explanation. Go through this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.