How do I combine `final-form-calculate` with `final-form-array`

强颜欢笑 提交于 2020-05-15 10:05:08

问题


I have a form which uses react-final-form-array in order to have many "Attendees". I'm wanting each of the Attendee.Email inputs to do a web lookup and then set the Attendee.FirstName and Attendee.Surname based off the result.

I'm not sure how this should be expressed with a final-form-calculate decorator. Specifically, I don't know how to reference the individual form item within the array.

Here's what I've got as a start:

const MyForm = props => {

  const calculator = createDecorator(
    {
      field: 'Attendees.Email', // <-- this needs to happen for each Email
      updates: {
        // ... do some lookups and set FirstName and Surname based off database query
        Attendees.FirstName: (email, allValues) =>
          someLookup(email).FirstName
      }
    },

  );

  const submit = values => {
    console.log(values);

  };
  return (<Form onSubmit={submit}
                mutators={{
                  ...arrayMutators,
                }}
                decorators={[calculator]}
                render={({handleSubmit, pristine, invalid, mutators: {push, pop}}) => {
                  return (
                    <form onSubmit={handleSubmit}>
                      <fieldset>
                        <legend>Attendees</legend>
                        <div className="fieldset">

                          <p><Button bsStyle="primary" onClick={() => push('Attendees', undefined)}>
                            Add attendee
                          </Button></p>

                          <FieldArray name="Attendees">
                            {({fields}) =>
                              fields.map((name, index) => (
                                <div key={name}>
                                  <label>Attendee #{index + 1} {index > 0 && <span
                                    onClick={() => {
                                      const attendee = fields.remove(index);
                                    }}
                                    style={{cursor: 'pointer'}}
                                    role="img"
                                    aria-label="delete">❌</span>}</label>
                                  <Field
                                    name={`${name}.Email`}
                                    component={TextField}
                                    label="Email address"
                                    validate={required}
                                  />
                                  <Field
                                    name={`${name}.FirstName`}
                                    component={TextField}
                                    label="First name"
                                    validate={required}
                                  />
                                  <Field
                                    name={`${name}.Surname`}
                                    component={TextField}
                                    label="Surname"
                                    validate={required}

                                  />

                                </div>
                              ))}
                          </FieldArray>
                        </div>
                      </fieldset>

                      <Button type="submit" bsStyle="primary"
                              disabled={invalid}>Next</Button>
                    </form>
                  );
                }}
  />);
};

export default MyForm;

回答1:


Took me a bit of hunting but it's actually pretty simple - from the website i noticed they have it listed (but not clearly)

So for my case, i just picked up the name and changed the last part of the text to reflect the object property i wanted to modify.

Below, i use regex to match a field, then replace the last part of the name value to match a different field (stored in fieldName) and then return an array containing the new field i am changing and the new value.

{
    field: /fields\[\d+\]\.field\.text/, // when a field matching this pattern changes...
    updates: (value, name, allValues) => {
        console.log('Update called', value, name);
        const fieldName = name.replace('.text', '.name');
        return {
            [fieldName]: value.replace(/\W+/gi, '-').toLowerCase()
        };
    }
}


来源:https://stackoverflow.com/questions/49714512/how-do-i-combine-final-form-calculate-with-final-form-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!