J'utilise Formik et yup pour les formulaires dans mon application. Je ne suis pas capable d'implémenter la case à cocher avec Formik , mis en œuvre ceci - solution mais ça ne fonctionne pas avec moi. Vous trouverez ci-dessous le code que j'ai essayé jusqu'à présent. Après avoir implémenté cette solution lorsque je clique sur la case à cocher Le formulaire devient invalide et soumettre le bouton n'appelle pas handleSubmit
méthode. J'ai aussi essayé d'utiliser React Native Elements
à la place de UI Kitten
Mais le résultat était le même.
const validationSchema = Yup.object().shape({
service_charge_status: Yup.boolean(),//.oneOf([true], 'Please check the agreement'),
documents_status: Yup.boolean(), //.oneOf([true], 'Please check the agreement'),
security_number: Yup.string()
.label('Security Number *')
.required('Security Number is required'),
note: Yup.string().label('Note')
})
handleSubmit = (values: any) => {
console.log('AD Values', values);
}
render() {
return (
<Formik
initialValues={{
// id: '',
service_charge_status: false,
documents_status: false,
security_number: '',
note: '',
security_personel_number: ''
}}
onSubmit={values => { this.handleSubmit(values) }}
validationSchema={validationSchema}
>
{({ handleChange,
values,
handleSubmit,
errors,
isValid,
isSubmitting,
touched,
handleBlur,
setFieldValue }
) => (<ScrollView>
<Header
noBackButton={true}
navigation={this.props.navigation}
title="Approve Request"
/>
<Layout style={{ padding: 20 }}>
<View style={{ marginVertical: 5 }}>
<Text category="p1" style={{ marginVertical: 5 }}>
Requester Type
</Text>
<View style={{ flexDirection: 'row' }}>
<RadioGroup
selectedIndex={this.state.requestTypeIndex}
onChange={(index) => this.setState({ requestTypeIndex: index })} >
<Radio
text="New Issue"
textStyle={styles.labelColor}
// checked={values.is_new_issue}
status="warning"
/>
<Radio
text="Replacement"
textStyle={styles.labelColor}
// checked={values.is_replacement}
// onChange={handleChange('is_replacement')}
status="warning"
/>
</RadioGroup>
</View>
</View>
<View style={{ marginVertical: 5 }}>
<Text category="p1" style={{ marginVertical: 5 }}>
Check List
</Text>
<Layout style={{ marginVertical: 6 }}>
<CheckBox
text="Service Charges"
textStyle={styles.labelColor}
status="warning"
checked={values.service_charge_status}
onChange={(val) => setFieldValue('service_charge_status', !values.service_charge_status)}
/>
</Layout>
<Layout style={{ marginVertical: 6 }}>
<CheckBox
text="Documents Verification"
textStyle={styles.labelColor}
status="warning"
checked={values.documents_status}
onChange={(val) => setFieldValue('documents_status', !values.documents_status)}
/>
</Layout>
</View>
<View style={{ marginVertical: 5 }}>
<Text category="p1" style={{ marginVertical: 5 }}>
Security Personel Number *
</Text>
<Input
placeholder="Enter Security personel number"
size='small'
multiline={true}
status={touched.security_personel_number ? !errors.security_personel_number ? 'success' : 'danger' : 'warning'}
caption={(touched.security_personel_number && errors.security_personel_number) ? errors.security_personel_number : ''}
value={values.security_personel_number}
onChangeText={handleChange('security_personel_number')}
/>
<Text category="p1" style={{ marginVertical: 5 }}>
Note *
</Text>
<Input
placeholder="Enter Note"
size='small'
multiline={true}
status={touched.note ? !errors.note ? 'success' : 'danger' : 'warning'}
caption={(touched.note && errors.note) ? errors.note : ''}
value={values.note}
onChangeText={handleChange('note')}
/>
</View>
{this.state.formSpinner &&
<View style={styles.centeredContentViewStyle}>
<ActivityIndicator animating size="small" color="#fbaf3a" />
</View>}
{this.state.error ?
<View style={styles.centeredContentViewStyle}>
<Text style={styles.errorMessageStyle}>{this.state.error}</Text>
</View> : null}
<Layout
style={{
justifyContent: 'flex-end',
flexDirection: 'row',
marginVertical: 10,
}}>
<Button
style={styles.cancelButton}
onPress={() => this.props.navigation.goBack()}>
Cancel
</Button>
<Button
style={styles.submitButton}
// type="submit"
// disabled={!isValid || this.state.formSpinner}
>
{isValid + ' Submit'}
</Button>
</Layout>
</Layout>
</ScrollView>)}
</Formik>
);
}
}
const styles = StyleSheet.create({
submitButton: {
borderColor: '#00c851',
backgroundColor: '#00c851',
marginStart: 5,
},
cancelButton: {
borderColor: '#ff3547',
backgroundColor: '#ff3547',
},
labelColor: {
color: '#8F9BB3',
},
centeredContentViewStyle: {
justifyContent: 'center',
alignItems: "center",
padding: 2,
marginVertical: 5
},
errorMessageStyle: {
color: 'red'
}
});
Formik s'attend à recevoir ChangeEvent comme argument de la fonction handleChange
. Vous pouvez le faire avec Input
, mais pas avec Radio
ou CheckBox
parce que, en quelques mots, ces composants simulent cet événement en manipulant régulièrement sur TouchableOpacity.
Ma solution utilisait des crochets pour gérer ces modifications puis la combinaison d'état avec un objet résultant de Formik.
J'utilise Matériel-UI, mais je crois que la solution peut être similaire. Si vous rencontrez des problèmes liés à Formik avec une bibliothèque, essayez d'exposer l'API de formulaire/champ et de définir manuellement les propriétés. Lorsque cela fonctionne, essayez de supprimer certaines des propriétés traitées automatiquement par Formik pour éviter de recréer la roue.
Voici comment j'ai mis en œuvre Radiogroup:
<Field name="fieldName" value={formik.values.fieldName}>
{({ form }) => (
{/* Fragment is used here, to make possible to add a FormHelperText under Field. */}
<React.Fragment>
{/* Remember to use same name as in the parent Field. form.handleEvent will make it work when you click on one of the options. */}
<RadioGroup name="fieldName" onChange={form.handleChange}>
<FormControlLabel value="A" control={<Radio />} label="Value A" />
<FormControlLabel value="B" control={<Radio />} label="Value B" />
<FormControlLabel value="C" control={<Radio />} label="Value C" />
</RadioGroup>
<FormHelperText error={Boolean(form.errors.fieldName) && form.touched.fieldName}>
{form.errors.fieldName}
</FormHelperText>
</React.Fragment>
)}
</Field>