Redux表单:具有多个提交按钮的条件表单验证

时间:2018-10-10 04:35:43

标签: javascript react-redux redux-form

enter image description here

我正在使用带有多个提交按钮的Redux表单以及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]} < / strong>

这是我的两个提交按钮:

      <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 :(得分:1)

在经历了许多头痛和挠头之后,我终于找到了解决方案,但并不使外观看起来很难看。感谢这个解决方案的开发者。最初的想法是在单击按钮时设置一个标志,并有条件地验证字段。 (PS:我正在使用字段级别验证)。但是,问题在于,验证是在标志设置之前执行的,因为在所有验证均已修复之前,onClick处理程序将不会触发,并且逻辑被深埋在redux表单内(使用库不必要地使简单的事情变得过于复杂) )。

这是解决方案:

提交处理程序

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,然后调用redux-forms内置的提交处理程序。另外,我提取了redux-form的提交处理程序,因为上面只是为了更清楚。

dispatchAction()

     dispatchAction={({ draftAction }) =>
        new Promise(resolve => {
          this.setState({ isDraftAction: draftAction }, resolve);
        })
      }

答案 1 :(得分:0)

使用状态变量作为 isSaveDraft ,并将其默认设置为 false 添加按钮的 onClick 操作以设置 state.isSaveDraft = true

答案 2 :(得分:0)

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 example

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可以是action,也可以像这样使它成为Form组件的一部分(我发现这很容易,因为您已经将change绑定到了表单):

setDraftFlag(value) {
    this.props.change('isDraft', value));
}