react-native-form-generator icon indicating copy to clipboard operation
react-native-form-generator copied to clipboard

handleFormChange (onChange) only passing one value at form level

Open dchersey opened this issue 7 years ago • 1 comments

I'm using code lifted straight from the example:

handleFormChange(formData) {
    const { onFormChange } = this.props;
    /*
    formData will contain all the values of the form,
    in this example.

    formData = {
    first_name:"",
    last_name:"",
    gender: '',
    birthday: Date,
    has_accepted_conditions: bool
    }
    */

    // r1 = refs[fields.remindersEnabled];
    // r2 = refs[fields.reminderCount];

    this.setState({
      formData,
    });

    if (onFormChange) { onFormChange(formData); }
  }

  // handleFormFocus(e, component) {
  //   console.log(e, component);
  // }

  render() {
    const { formData, sounds } = this.state;
    const { fields } = this;
    return (
      <ImageBackground
        style={[styles.background]}
        source={Images.backgrounds.main}
      >
        <View style={styles.wrapper}>
          <Form
            ref={(c) => { this.form = c; }}
            onFocus={{/* (e, c) => this.handleFormFocus(e, c) */}}
            onChange={(f) => { this.handleFormChange(f); }}
            label="AWARENESS settings"
          >
            <SwitchField
              containerStyle={styles.container}
              labelStyle={[styles.labelText]}
              label='Enable reminders'
              ref={fields.remindersEnabled}
              value={formData[fields.remindersEnabled]}
            />
            <PickerField
              containerStyle={styles.container}
              labelStyle={[styles.labelText]}
              valueStyle={[styles.value]}
              ref={fields.reminderCount}
              label='Number of reminders each day'
              options={{
                1: '1',
                2: '2',
                3: '3',
                4: '4',
                5: '5',
                6: '6',
                7: '7',
                8: '8',
                9: '9',
                10: '10',
                11: '11',
                12: '12',
                13: '13',
                14: '14',
                15: '15',
                16: '16',
                17: '17',
                18: '18',
                19: '19',
                20: '20',
              }}
              pickerWrapper={<ModalPicker title="Times per day" />}
              iconRight={(
                <Icon
                  style={{ alignSelf: 'center', marginRight: 10, color: '#969696' }}
                  name='ios-arrow-forward'
                  size={30}
                />
              )}
            />

            <TimePickerField
              containerStyle={styles.container}
              placeholderStyle={[styles.labelText]}
              valueStyle={[styles.value]}
              ref={fields.reminderStart}
              placeholder='Start At'
              date={formData[fields.reminderStart]}
              pickerWrapper={<ModalPicker title="Start time" />}
              dateTimeFormat={(date) => {
                if (!date) return '';
                const value = date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
                return value;
              }}
              iconRight={(
                <Icon
                  style={{ alignSelf: 'center', marginRight: 10, color: '#969696' }}
                  name='ios-arrow-forward'
                  size={30}
                />
              )}
            />
            <TimePickerField
              containerStyle={styles.container}
              placeholderStyle={[styles.labelText]}
              valueStyle={[styles.value]}
              ref={fields.reminderEnd}
              placeholder='End At'
              pickerWrapper={<ModalPicker title="End time" />}
              dateTimeFormat={(date) => {
                if (!date) return '';
                const value = date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
                return value;
              }}
              iconRight={(
                <Icon
                  style={{ alignSelf: 'center', marginRight: 10, color: '#969696' }}
                  name='ios-arrow-forward'
                  size={30}
                />
              )}
            />

            <PickerField
              containerStyle={styles.container}
              labelStyle={[styles.labelText]}
              valueStyle={[styles.value]}
              ref={fields.snoozeInterval}
              label='Snooze duration'
              options={{
                1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10',
              }}
              pickerWrapper={<ModalPicker title="Snooze duration" />}
              iconRight={(
                <Icon
                  style={{ alignSelf: 'center', marginRight: 10, color: '#969696' }}
                  name='ios-arrow-forward'
                  size={30}
                />
              )}
            />
            <PickerField
              containerStyle={styles.container}
              labelStyle={[styles.labelText]}
              valueStyle={[styles.value]}
              ref={fields.reminderSound}
              label='Reminder sound'
              options={sounds}
              pickerWrapper={<ModalPicker title="Reminder sound" />}
              iconRight={(
                <Icon
                  style={{ alignSelf: 'center', marginRight: 10, color: '#969696' }}
                  name='ios-arrow-forward'
                  size={30}
                />
              )}
            />

            <SwitchField
              containerStyle={styles.container}
              labelStyle={[styles.labelText]}
              ref={fields.includeMeetings}
              label='Include meetings'
            />
            <SwitchField
              containerStyle={styles.container}
              labelStyle={[styles.labelText]}
              ref={fields.includeWeekends}
              label='Include weekends'
            />

          </Form>

        </View>
      </ImageBackground>

    );
  }
}

The behavior I am seeing is that formData passed to handleFormChange only has the value of my first child (the SwitchField). Subsequent invocations when I change other fields supply an empty hash.

I have debugged this into the Form.js code #handleFieldChange

  handleFieldChange(field_ref, value){
    this.values[field_ref] = value;
    this.props.onChange && this.props.onChange(this.values);
  }

and confirmed that the field_ref and value parameters are correct, but they are not registering properly in this.values ... and I can't see why not.

dchersey avatar Sep 17 '18 19:09 dchersey

Ok, this is working with a few changes. After posting, I was able to make it work with the following code. All I did was remove the call to setState(formData) and removed formData from my component state. Still mystified.

  handleFormChange(formValues) {
   // Store my settings
  }

and JSX

          <Form
            ref={(c) => { this.form = c; }}
            onFocus={{/* (e, c) => this.handleFormFocus(e, c) */}}
            label="AWARENESS settings"
            onChange={f => this.handleFormChange(f)}
          >

dchersey avatar Sep 20 '18 15:09 dchersey