gcanti / tcomb-form-native

Forms library for react-native
MIT License
3.15k stars 458 forks source link

Keep entered values after error #586

Open CharlotteRdn opened 4 years ago

CharlotteRdn commented 4 years ago

Version

Tell us which versions you are using:

Expected behaviour

I did a form using tcomb form native. I would like to keep the values of the previous fields when the user make an error. I guess it's possible but I don't know how...

Actual behaviour

when I validate the form, if there is an error every field value vanishes. How could I keep them ?

const Form = t.form.Form;

const Email = t.refinement(t.String, email => {
  const reg = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; //or any other regexp
  return reg.test(email);
});

const Phone = t.refinement(t.maybe(t.String), phone_number => {
  if (phone_number.length === 0) {
    // => ICI, trouver une condition pour vérifier si c'est vide. Si oui, en renvoi TRUE.
    return true;
  }
  const reg = /^(?:\+\d{1,3}|0\d{1,3}|00\d{1,2})?(?:\s?\(\d+\))?(?:[-\/\s.]|\d)+$/; //or any other regexp
  return reg.test(phone_number);
});

const Pwd = t.refinement(t.String, password => {
  const reg = /^(?=.{8,})/; //or any other regexp
  return reg.test(password);
});

const User = t.struct({
  email: Email,
  password: Pwd,
  phone_number: Phone,
  terms: t.Boolean
});

const formStyles = {
  ...Form.stylesheet
};

const options = {
  fields: {
    email: {
      label: i18n.t("signup.input.email"),
      error: i18n.t("signup.error.email")
    },
    password: {
      password: true,
      secureTextEntry: true,
      label: i18n.t("signup.input.password"),
      error: i18n.t("signup.error.password")
    },
    phone_number: {
      label: i18n.t("signup.input.phone"),
      error: i18n.t("signup.error.phone")
    },
    terms: {
      label: i18n.t("signup.input.terms"),
      error: i18n.t("signup.error.terms")
    }
  },
  stylesheet: stylesheet
};

export default class Signup extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showProgress: null,
      email: "",
      password: "",
      phone_number: "",
      error: "",
      accepted: false,
      secureTextEntry: true
    };
  }

  async onRegisterPressed(email, pwd, phone, terms) {
    //console.log("SIGNUP::email: ", email);
    //console.log("SIGNUP::email: ", pwd);
    //console.log("SIGNUP::email: ", phone);
    // console.log("SIGNUP::term: ", term);

    if (email != "" && pwd != "") {
      this.setState({ showProgress: true });
      try {
        let response = await fetch(
          API_URL +
            "/users?society_id=131&access_token=" +
            "accessToken" +
            "&lang=fr",
          {
            method: "POST",
            headers: {
              Accept: "application/json",
              "Content-Type": "application/json",
              Authorization: "Bearer " + API_SECRETKEY
            },
            body: JSON.stringify({
              email: email,
              password: pwd,
              mobilephone: phone
            })
          }
        )
          .then(response => response.json())
          .then(responseData => {
            //console.log("YOU HAVE SUCCESFULLY LOGGED IN:", responseDocs)
            console.log("ok: ", responseData.status);

            if (responseData.status >= 200 && responseData.status < 300) {
              console.log("data: ", responseData.data);

              //Handle success
              let accessToken = responseData;
              console.log(accessToken);
              //On success we will store the access_token in the AsyncStorage
              this.storeProfileToken(accessToken);
              this.redirect(MyTrips);
            } else {
              //Handle error
              console.log("data-error: ", responseData.data.error);
              let error = responseData;
              throw responseData.data.error;
            }
          });

        return result;
      } catch (error) {
        this.setState({ error: error });
        console.log("error " + error);
        this.setState({ showProgress: false });
      }
    }
  }

  setPasswordVisibility = () => {
    this.setState({ secureTextEntry: false });
  };

  handleSubmit = async () => {
    const data = this._form.getValue();

    if (
      data &&
      data.email &&
      data.password &&
      data.terms &&
      data.terms === false
    ) {
      return alert("error : please accept the terms of I-MyMap");
      // Mettre message erreur ici ! => et si on est dedans, c'est que terms n'a pas été validé. Il faudra mettre une alert pour prévenir l'utilisateur
    } else if (data && data.email && data.password && data.terms) {
      console.log("SIGNUP::term: ", data.terms);
      this.setState({ accepted: true });
      this.onRegisterPressed(
        data.email,
        data.password,
        data.phone_number,
        data.terms
      );
    } /*
  } else {this.props.navigation.navigate("Authentication")}*/
  };
  render() {
    return (
      <ImageBackground
        source={require("../../assets/images/bg_mobile_paysage.jpg")}
        style={{ flex: 1 }}
      >
        <ScrollView>
          <View style={styles.container}>
            <Text style={styles.h5}>{"\n"}</Text>
            <Text style={styles.h1}>{i18n.t("signup.title")}</Text>
            <Text style={styles.h5}>{"\n"}</Text>
            <Form ref={c => (this._form = c)} type={User} options={options} />
            <TouchableOpacity
              activeOpacity={0.8}
              style={styles.touachableButton}
              onPress={this.setPasswordVisibility}
            >
              <Image
                source={
                  this.state.secureTextEntry
                    ? require("../../assets/images/hide.png")
                    : require("../../assets/images/view.png")
                }
                style={styles.buttonImage}
              />
            </TouchableOpacity>
            <Button
              containerStyle={[styles.mybtnContainer]}
              style={styles.mybtn}
              onPress={this.handleSubmit}
            >
              {i18n.t("signup.action.subscribe").toUpperCase()}
            </Button>
            <Button
              onPress={() => this.props.navigation.navigate("Login")}
              containerStyle={[styles.mybtnContainer, styles.btnContainerMuted]}
              style={styles.mybtn}
            >
              {i18n.t("signup.action.haveAccount").toUpperCase()}
            </Button>
          </View>
        </ScrollView>
      </ImageBackground>
    );
  }
}
vrishty commented 2 years ago

Hello @CharlotteRdn , has this issue been resolved since then? I am facing the same issue.