Форма Redux: условные проверки формы с несколькими кнопками отправки - PullRequest
0 голосов
/ 10 октября 2018

enter image description here

Я использую формы Redux с несколькими кнопками отправки вместе с избыточной формой <Field />.Мне нужно контролировать проверку этих полей на основе нажатия этих кнопок.НапримерМне нужно установить флажок True / False на основе нажатия этих кнопок, чтобы я мог условно проверить свои поля, как показано ниже:

        <Field
          name="date"
          component={DateFormField}
          validate={isSaveDraft && [validateRequiredText]}
          floatingLabelText="Date"
          fullWidth
          helpText="blablabla"
        />
        <Field
          name="title"
          component={TextFormField}
          normalizeOnBlur={normalizeTextOnBlur}
          validate={!isSaveDraft && [validateRequiredText]}
          floatingLabelText="Project title"
          fullWidth
          helpText="blablabla"
        />

Как вы можете видеть из кода выше, я условно проверяю свойполя с validate = {isSaveDraft && [validateRequiredText]} и validate = {! isSaveDraft && [validateRequiredText]}

Вот мои две кнопки отправки:

      <RaisedButton
        label={submitting ? 'Saving Draft...' : 'Save Draft'}
        type="button"
        onClick={handleSubmit(values => onSubmit())}
        disabled={submitting}
        primary
      />
    <RaisedButton
      label={submitting ? 'Submitting Brief...' : 'Submit Brief'}
      type="button"
      onClick={handleSubmit(values => onSubmit())}
      disabled={submitting}
      primary
    />

Однако я не могу этого достичь.Пожалуйста, помогите.

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

validate={(isSaveDraft && [validateRequiredText]} не будет работать, так как validate ожидает функцию все время.Кроме того, проверка на уровне поля происходит onTouch или onBlur и т. Д., Что слишком рано, так как вы не будете знать, какая кнопка будет нажата.

Что вам нужно сделать, это использовать дополнительный флажок для удержания какой кнопкищелкнул, а затем использовать это в проверке уровня формы.

Таким образом, ваши поля будут выглядеть следующим образом (не более проверки уровня поля):

<Field
    name="date"
    component={DateFormField}
    floatingLabelText="Date"
    fullWidth
    helpText="blablabla"
/>
...
<RaisedButton
    label={submitting ? 'Saving Draft...' : 'Save Draft'}
    onMouseDown={() => this.setDraftFlag(true)}        
    ...
/>
<RaisedButton
    label={submitting ? 'Submitting Brief...' : 'Submit Brief'}
    onMouseDown={() => this.setDraftFlag(false)}        
    ...
/>

Я использую onMouseDown для захвата флага, так как вы уже используете onClickдля отправки формы.Кроме того, нам все равно нужно выполнить проверку перед отправкой.

А затем в validate вашей формы (на основе Пример SyncValidation )

const validate = values => {
    const errors = {}
    const {isDraft, ...rest} = values

    if(isDraft) {
        // draft validations
    } else {
        // other validations
    }
    return errors
}

export default reduxForm({
    form: 'myForm', // a unique identifier for this form
    validate, // <--- validation function given to redux-form
})(MyForm)

setDraftFlagможет быть действием или вы можете сделать его частью своего компонента формы, например, так (я считаю это проще, поскольку вы уже привязали change к своей форме):

setDraftFlag(value) {
    this.props.change('isDraft', value));
}
0 голосов
/ 16 октября 2018

После многих головных болей и царапин на голове я, наконец, нашел решение, не делая вещи уродливыми.Спасибо коллеге-разработчику за это решение.Первоначальной идеей было установить флажок по нажатию кнопки и условно проверить поля.(PS: я использую проверки на уровне поля).Однако проблема заключалась в том, что проверки выполняются ПЕРЕД настройкой флага, поскольку обработчик onClick не будет срабатывать до того, как все проверки будут исправлены, и эта логика скрыта глубоко внутри избыточных форм (льготы, излишне усложняющие простые вещи с помощью библиотеки).).

Вот решение:

обработчик отправки

handleSubmit() {
    const { bookingCreate, modalShow, navigateTo } = this.props;
    const { isDraftAction } = this.state; // my flag

    // create record!
    return bookingCreate(isDraftAction)
      .then(responsePayload => {
        ...
      })
      .catch(handleSubmissionError);
 }

isDraftAction - это флаг, который устанавливается (in local state), когдадействие вызывается на onClick обеих кнопок.

Мои условные проверки уровня поля

    <Field
      name="date"
      component={DateFormField}
      validate={isDraftAction && [validateRequiredText]}
      fullWidth
      helpText="blablabla"
    />
    <Field
      name="title"
      component={TextFormField}
      normalizeOnBlur={normalizeTextOnBlur}
      validate={!isDraftAction && [validateRequiredText]}
      fullWidth
      helpText="blablabla"
    />

Мои 2 кнопки для СОХРАНИТЬ ЗАПИСЬ и ОТПРАВИТЬ ЗАПИСЬ.

  const submit = handleSubmit(values => onSubmit()); // this is redux-form's submit handler which will in-turn call my own submit handler defined above. (That's where the library hides all the logic and makes developer helpless)

  <RaisedButton
    label={submitting && isDraft ? 'Saving Draft...' : 'Save Draft'}
    type="button"
    onClick={() => {
      this.props.dispatchAction({ draftAction: true }).then(() => {
        submit();
      });
    }}
    disabled={submitting}
    primary
  />
  <RaisedButton
    label={submitting && !isDraft ? 'Submitting Brief...' : 'Submit Brief'}
    type="button"
    onClick={() => {
      this.props.dispatchAction({ draftAction: false }).then(() => {
        submit();
      });
    }}
    disabled={submitting}
    primary
  />

dispatchAction() - это моя функция действия, которая ПЕРВЫМ установит флаг в значение true / false, ТО затем вызовите встроенный обработчик отправки в избыточных формах.Кроме того, я извлек обработчик отправки избыточной формы, как указано выше, только для большей ясности.

dispatchAction ()

     dispatchAction={({ draftAction }) =>
        new Promise(resolve => {
          this.setState({ isDraftAction: draftAction }, resolve);
        })
      }
0 голосов
/ 10 октября 2018

используйте переменную состояния как isSaveDraft и установите для нее значение по умолчанию false Добавить onClick действие кнопки для установки state.isSaveDraft = true

...