最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use Checkbox and Radio Buttons with Formik, Yup, Ui Kitten in React Native - Stack Overflow

programmeradmin5浏览0评论

I am using Formik and yup for forms in my app. I am not able to implement checkbox with Formik, implemented this solution but its not working with me. Below is the code I have tried so far. After implementing this solution when i click on checkbox the form bee invalid and submit button does not call handleSubmit method. I also tried using React Native Elements instead of UI Kitten but result was the same.

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

I am using Formik and yup for forms in my app. I am not able to implement checkbox with Formik, implemented this solution but its not working with me. Below is the code I have tried so far. After implementing this solution when i click on checkbox the form bee invalid and submit button does not call handleSubmit method. I also tried using React Native Elements instead of UI Kitten but result was the same.

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'
  }
});
Share Improve this question asked Dec 16, 2019 at 8:38 Imdad AliImdad Ali 7371 gold badge8 silver badges20 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 8

I'm using Formik with Chakra UI's Checkbox and ended up using the onChange event to solve this issue like so:

<Field name="terms">
  {({ field }) => (
    <Checkbox
      id="terms"
      name="terms"
      onChange={(e) => setFieldValue('terms', e.target.checked)}
    >
      <Text fontSize="sm" textAlign="left">
        I agree to the Terms and Conditions.
      </Text>
    </Checkbox>
  )}
</Field>

I believe something similar with work with UI Kitten.

This GitHub ment was really helpful for Yup validation.

Formik expects to receive ChangeEvent as argument of handleChange function. You can do it with Input, but not with Radio or CheckBox because, in a few words, these ponents simulate this event by handling regular onPress from TouchableOpacity.

My solution was using hooks to handle these changes and then bining state with resulting object from Formik.

I'm using material-ui, but i believe the solution can be similar. If you have problems linking formik with any library, try to expose the form/field api and manually set the properties. When it works, try to remove some of the properties handled automatically by formik to avoid recreate the wheel.

This is how i implemented 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>

References:

  • Material UI
  • Formik Material UI
  • Formik Field API

Uı kits or elements don't matter. You can easily handle with formik and yup.

  • Add your initial values
  • Add your radio element to your validation schema and set your requirement like required.
  • Use setFieldValue or manipulate values
  • Then boom!

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论