web-dev-qa-db-fra.com

Comment utiliser case à cocher et les boutons radio avec Formik, Yup, UI Kitten in React Natif

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'
  }
});
4
Imdad Ali

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.

0
artyorsh

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>

Les références:

0
Diogo Paschoal