I have a TextInput and when I autofill my email address I have a space after my email.
I try this
const email = values.email.trim();
and also
const email = values.email.replace(/\s+/g, ' ');
but it's doesn't work. Someone know how to remove the space after the autofill?
return (
<Formik
enableReinitialize={true}
initialValues={{ email: this.props.navigation.getParam("email") }}
validationSchema={yup.object().shape({
email: yup
.string()
})}
onSubmit={async (values) => {
const email = values.email;
}
}
>
{({ handleChange, handleSubmit, values, errors, touched, setFieldTouched }) => (
<View>
{
<View>
<TextInput
value={values.email}
placeholder="Email"
autoCapitalize="none"
autoCorrect={false}
onBlur={() => setFieldTouched("email")}
onChangeText={handleChange("email")}
autoCompleteType={"email"}
/>
<View>
<TouchableOpacity
onPress={handleSubmit}
>
<Text style={styles.textButton}>Valider</Text>
</TouchableOpacity>
</View>
</View>
)}
</Formik>
);
If you haven't found a solution for this situation yet, here's one way that solves it:
onChangeText={(val) => setFieldValue('login', val.trim())}
Instead of using handleChanges, you can use setFieldValue, then "trim" val.
<Text
...
value={this.state.emailID}
/>
Reuse your trim logic and assign the new value to the state variable(emailID) in "onChangeText" of the textinput
Related
In react native I want to make a dynamic controller component. But i cant access errors with it. I using "react-hook-form" for form elements. So Its my component :
const {
control,
handleSubmit,
formState: {errors},
setValue,
} = useForm();
const DynamicController = ({req, pattern, name, label}) => {
return (
<>
<Text style={[t.textBase]}>{label}</Text>
<Controller
control={control}
defaultValue=""
rules={{
required: {
value: true,
message: 'Bu alan boş bırakılamaz!',
},
}}
render={({field: {onChange, onBlur, value}}) => (
<Input
errorText={errors[name].message}
error={errors[name]}
onBlur={onBlur}
placeholder={label}
onChangeText={onChange}
value={value}
/>
)}
name={name}
/>
</>
);
};
My Input Component is basicly simple input. My problem is when i give error name like that example i cant access errors.
Its how i use my component :
<DynamicController
label="Email"
name="Email"
pattern={true}
req={true}
/>
When i dont fill the element and log the submit its not showing any error. Its simple passing validate. So what can i do where do i make wrong ? thank you for answerings!!!
Is your Input a custom wrapper? If not, a better way do this using react-hook-form would be:
const {
control,
handleSubmit,
formState: {errors},
setValue,
} = useForm(
defaultValues: {
firstName: '', // form fields should be populated here so that the error can be displayed appropriately
lastName: ''
}
);
const DynamicController = ({req, pattern, name, label}) => {
return (
<>
<Text style={[t.textBase]}>{label}</Text>
<Controller
control={control}
defaultValue=""
rules={{
required: {
value: true,
message: 'Bu alan boş bırakılamaz!',
},
}}
render={({field: {onChange, onBlur, value}}) => (
<Input
onBlur={onBlur}
placeholder={label}
onChangeText={onChange}
value={value}
/>
)}
name={name}
/>
{errors[name] && <Text>This is required.</Text>}
</>
);
};
Upon entering my screen, there's no error displayed on the input field.
In my form, I take an input and run a graphql mutation on it. Once it's done, I reset the form. However, after resetting, I start seeing a Formik Error because the field is .required() and currently it's empty.
This error should only be shown when I am trying to submit the form without an input. It shouldn't show after I have submitted it once successfully.
const handleSubmitForm = (
values: FormValues,
helpers: FormikHelpers<FormValues>,
) => {
editLocationName({
variables: {
favouritePlaceId: route.params.id,
input: {customisedName: values.locationName}
},
});
helpers.resetForm();
helpers.setErrors({});
};
.....
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
<FieldInput
handleChange={handleChange}
handleBlur={handleBlur}
value={values.locationName}
fieldType="locationName"
placeholderText="Neuer Name"
/>
<ErrorMessage
name="locationName"
render={(msg) => <ErrorText errorMessage={msg} />}
/>
</View>
<View style={styles.buttonContainer}>
<ActionButton buttonText="Save" onPress={handleSubmit} />
</View>
</View>
)}
</Formik>
Validation Schema:
const favouriteLocationNameValidationSchema = yup.object().shape({
locationName: yup
.string()
.label('locationName')
.required('Required Field')
});
How can I reset the error message along with the form?
setErrors({}) did not work for me.
Adding it here, because suggestion requires code . Add following code and let me know if it helped.
helpers.resetForm({
errors: {},
touched: {}
});
Remove helpers.setErrors({});
I have a dummy Login code with formik form in react-native
import React, { Component } from "react";
import {
TextInput,
Text,
Alert,
Image,
View,
TouchableOpacity,
SafeAreaView,
ScrollView
} from "react-native";
import styles from "./Styles/LoginStylesheet";
import { KeyboardAccessoryNavigation } from "react-native-keyboard-accessory";
import { Formik } from "formik";
import schemaObject, { initialValues, refs } from "./Validations/LoginValidations";
export default class LoginView extends Component {
constructor(props) {
super(props);
this.state = {
activeInputIndex: 0
};
}
handleFocus = index => () => {
this.setState({
activeInputIndex: index
});
};
handleFocusNext = () => {
if (this.state.activeInputIndex + 1 >= refs.length) {
return;
}
refs[this.state.activeInputIndex + 1].focus();
};
handleFocusPrevious = () => {
if (this.state.activeInputIndex - 1 < 0) {
return;
}
refs[this.state.activeInputIndex - 1].focus();
};
handleLogin = () => {
console.log("ACTIOn");
// this.formik.handleSubmit();
};
render() {
return (
<View style={styles.safeAreaView}>
<SafeAreaView style={styles.safeAreaView}>
<ScrollView style={styles.superView}>
<Formik {/* LINE 56 */}
initialValues={initialValues}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={schemaObject}
ref={p => (this.formik = p)}
>
{({
values,
handleChange,
errors,
setFieldTouched,
touched,
isValid,
handleSubmit
}) => (
<View style={styles.superView}>
<View style={styles.logoParentView}>
<Image
source={require("../../Resources/Assets/Login/aptihealth_logo.png")}
resizeMode={"contain"}
style={styles.logo}
/>
</View>
<View style={styles.emailParentView}>
<Text style={styles.titleLabel}>Email Id</Text>
<TextInput
value={values.emailId}
onChangeText={handleChange("emailId")}
onBlur={() => setFieldTouched("emailId")}
placeholder="Email Id"
style={styles.textInput}
autoCorrect={false}
onFocus={this.handleFocus(0)}
ref={input => {
refs[0] = input;
}}
/>
{touched.emailId && errors.emailId && (
<Text style={{ fontSize: 10, color: "red" }}>
{errors.emailId}
</Text>
)}
</View>
<View style={styles.passwordParentView}>
<Text style={styles.titleLabel}>Password</Text>
<TextInput
value={values.password}
onChangeText={handleChange("password")}
placeholder="Password"
onBlur={() => setFieldTouched("password")}
style={styles.textInput}
autoCorrect={false}
secureTextEntry={true}
onFocus={this.handleFocus(1)}
ref={input => {
refs[1] = input;
}}
/>
{touched.password && errors.password && (
<Text style={{ fontSize: 10, color: "red" }}>
{errors.password}
</Text>
)}
</View>
<View style={styles.forgotPasswordParentView}>
<TouchableOpacity
style={styles.forgotpasswordButton}
activeOpacity={0.7}
>
<Text>Forgot Password?</Text>
</TouchableOpacity>
</View>
<View style={styles.loginParentView}>
<TouchableOpacity
onPress={() => {
console.log("VALUES: ", values, this.formik);
this.handleLogin();
}}
style={styles.loginButton}
activeOpacity={0.7}
>
<Text style={styles.loginText}>Login</Text>
</TouchableOpacity>
</View>
<View style={styles.seperaterParentView}>
<View style={styles.seperaterView} />
<Text style={styles.seperaterText}>OR</Text>
<View style={styles.seperaterView} />
</View>
<View style={styles.faceIdLoginParentView}>
<Image
source={require("../../Resources/Assets/face_id_small_color/face_id_small_color.png")}
resizeMode={"contain"}
/>
<TouchableOpacity style={styles.faceIdButton}>
<Text>Sign In with Face ID</Text>
</TouchableOpacity>
</View>
<View style={styles.signUpParentView}>
<TouchableOpacity style={styles.signupButton}>
<Text>Sign Up for Account Here</Text>
</TouchableOpacity>
</View>
</View>
)}
</Formik>
</ScrollView>
</SafeAreaView>
<KeyboardAccessoryNavigation
nextDisabled={false}
previousDisabled={false}
nextHidden={false}
previousHidden={false}
onNext={this.handleFocusNext}
onPrevious={this.handleFocusPrevious}
avoidKeyboard
/>
</View>
);
}
}
I am trying to console formik ref in login action getting undefined value with debug error
ExceptionsManager.js:126 Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Check the render method of `LoginView`.
in Formik (at LoginView.js:56)
I have no idea why it's getting undefined ??
You should take a look at this issue.
You problem is here
<Formik
initialValues={initialValues}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={schemaObject}
ref={p => (this.formik = p)} {/* passing this ref will throw the error */}
>
In the latest version of Formik, they changed Formik to a functional component as explained in the issue, which gives you this error if you pass ref's.
You can check for the suggestions on the issue or wait until they release an update with the correction.
Edit:
Formik made an update and now you can use ref with the prop innerRef.
Please see this comment
You should change it to
<Formik
initialValues={initialValues}
onSubmit={values => Alert.alert(JSON.stringify(values))}
validationSchema={schemaObject}
{/* using innerRef instead of ref*/}
innerRef={p => (this.formik = p)} {/* this will give you the formik bag */}
>
And this way you can call this.formik.handleSubmit(), just lik you want to do.
I have a problem with entering data in the database (Couch / Pouch).
Basically I have a form through which I pass the values entered to a function that performs a put in the database, thus entering the data.
The problem is that if by chance one of these fields from the form is left empty, once the put is executed this field is deleted from the database.
So for example, if I have the FirstName: "NameUser" field in the db, and going to compile the form nothing is entered in the field corresponding to FirstName, the value FirstName and "NameUser" are deleted from the db.
How can I solve this problem? Thank you all.
//.....
.then(response => {
let utente = response.docs[0];
utente.Person.FirstName = this.state.FirstName;
utente.Person.LastName = this.state.LastName;
utente.Person.City = this.state.City;
utente.Person.Address = this.state.Address;
return global.utente.db.localdb().put(utente);
})
.catch(function(err) {
console.log(JSON.stringify(err));
}) }
render() {
return (
<View style={style.container}>
<View style={style.page}>
<KeyboardAwareScrollView>
<View style={style.inputContainer}>
<TextInput
style={style.inputs}
placeholder="Name"
placeholderTextColor="#64c7c0"
keyboardType="default"
underlineColorAndroid="grey"
onChangeText={FirstName =>
this.setState({ FirstName })
}
/>
</View>
<View style={style.inputContainer}>
<TextInput
style={style.inputs}
placeholder="Surname"
placeholderTextColor="#64c7c0"
keyboardType="default"
underlineColorAndroid="grey"
onChangeText={LastName =>
this.setState({ LastName })}
/>
</View>
<View style={style.inputContainer}>
<TextInput
style={style.inputs}
placeholder="City"
placeholderTextColor="#64c7c0"
keyboardType="default"
underlineColorAndroid="grey"
onChangeText={City => this.setState({ City })}
/>
</View>
{/*
<View style={style.inputContainer}>
</View>
*/}
<View style={style.inputContainer}>
<TextInput
style={style.inputs}
placeholder="Address"
placeholderTextColor="#64c7c0"
keyboardType="default"
underlineColorAndroid="grey"
onChangeText={Address => this.setState({ Address })}
/>
<View style={style.footer}>
<TouchableOpacity
style={[style.button, style.buttonOK]}
onPress={() => this.findUtente(this.props.cf)}
>
<Text>Save</Text>
</TouchableOpacity>
I'm using react-native-autocomplete-input and I'd like disable the <Autocomplete /> input. I tried adding disabled={this.state.loading} (disabling it while the data loads...right now the user can start typing before the autocomplete is available).
I'm confident there's a way to do so but I haven't been able to figure it out. Code below:
<Autocomplete
data={data}
defaultValue={query}
listStyle={styles.autoCompleteItems}
onChangeText={(text) => this.setState({query: text})}
renderItem={(data) => (
<TouchableOpacity onPress={() =>
this.setState({query: data.name, schoolId: data.id, social: data.social})
}
>
<Text>{data.name}</Text>
</TouchableOpacity>
)}
/>
react-native-autocomplete-input itself does not provide functionality to disable the input field. So passing disabled={this.state.loading} will have no effect.
You can edit the the package by going into your node_modules/react-native-autocomplete-input folder and editing index.js file.
change the render function in index.js to following. Now its accepting isEditable prop and passing it to TextInput
render() {
const { showResults } = this.state;
const { containerStyle, inputContainerStyle, onEndEditing, isEditable, style, ...props } = this.props;
return (
<View style={[styles.container, containerStyle]}>
<View style={[styles.inputContainer, inputContainerStyle]}>
<TextInput
editable={isEditable}
style={[styles.input, style]}
ref="textInput"
onEndEditing={e =>
this._showResults(false) || (onEndEditing && onEndEditing(e))
}
{...props}
/>
</View>
{showResults && this._renderItems()}
</View>
);
}
Now you can pass isEditable={this.loading} as a prop to <Autocomplete />