Невозможно получить проверку только для формы Antd с Formik - ошибочные поля отображаются только при фактической попытке отправки - PullRequest
0 голосов
/ 31 октября 2018

У меня проблемы с получением моей формы, которая является формой Antd, только для проверки (без отправки), нажав кнопку, а не отправляя ее. Единственный способ проверить и обновить поля с ошибками - это попытаться отправить их. Есть ли способ сделать это? Или я застрял при отправке формы?

У меня есть кнопка для отправки и одна только для проверки - кнопка только для проверки вызывает метод validateForm, но в форме ничего не обновляется.

РЕДАКТИРОВАТЬ : вот ссылка на codeandbox, чтобы продемонстрировать это : https://codesandbox.io/s/xo5ln7l32p ... еще раз - когда я касаюсь текстового поля или нажимаю кнопку отправки, проверка работает и показывает сообщение об ошибке под текстовым полем, однако при нажатии кнопки «Проверить все» под текстовым полем ошибка не отображается.

Вот мой код для моей базовой формы Antd:

import React from 'react';
import PropTypes from 'prop-types';
import { Form as AntdForm } from 'antd';
import FormValidationAlert from './FormValidationAlert';

function Form({ children, onSubmit, isValid, validationErrors }) {
  return (
    <AntdForm layout="vertical" onSubmit={onSubmit} style={{ margin: 20 }}>
      {!isValid && <FormValidationAlert validationErrors={validationErrors} />}
      {children}
    </AntdForm>
  );
}

Form.propTypes = {
  onSubmit: PropTypes.func.isRequired,
  isValid: PropTypes.bool.isRequired,
  validationErrors: PropTypes.array
};

export default Form;

Вот моя форма:

import React from 'react';
import PropTypes from 'prop-types';
import { Formik } from 'formik';
import * as Yup from 'yup';
import { Col, Row, Steps } from 'antd';
import {
  Form,
  TextInput
} from '../common/forms';

class CreateItemForm extends React.Component {
  render() {
    const formik = {
      initialValues: {
        name: ''
      },
      validationSchema: Yup.object().shape({
        name: Yup.string().required('Name is required.')
      }),
      onSubmit: (values, actions) => {
        this.props.onSubmit(values);
      }
    };

    console.log('this.props', this.props);

    const { setFormRef, status, currentStep } = this.props;

    return (
      <Formik
        ref={setFormRef}
        {...formik}
        render={form => (
          <Form
            onSubmit={form.handleSubmit}
            isValid={status.isValid}
            validationErrors={status.validationErrors}
          >
            <TextInput
              {...form}
              name="name"
              placeholder="Name"
              label="Name"
            />
            <button type="button" onClick={() => validateForm().then(() => console.log(blah))}>
              Validate All
                    </button>
            <button type="submit">Submit</button>
          </ Form>
        )}
      />
    );
  }
}

CreateItemForm.propTypes = {
  onSubmit: PropTypes.func.isRequired,
  status: PropTypes.object.isRequired,
  setFormRef: PropTypes.func.isRequired
};

export default CreateItemForm;

Вот мой TextInput:

import React from 'react';
import PropTypes from 'prop-types';
import { Form, Input } from 'antd';
import ReactInputMask from 'react-input-mask';

function TextInput({
  values,
  errors,
  touched,
  handleSubmit,
  setFieldValue,
  setFieldTouched,
  name,
  label,
  placeholder,
  disabled,
  addOnBeforeValue,
  addOnAfterValue,
  mask,
  maskPermanents
}) {
  return (
    <Form.Item
      label={label}
      hasFeedback={!!errors[name]}
      validateStatus={touched[name] && errors[name] && 'error'}
      help={touched[name] && errors[name]}
    >
      {mask ? (
        <ReactInputMask
          disabled={
            disabled === null || disabled === undefined ? false : disabled
          }
          alwaysShowMask={false}
          value={values[name]}
          onChange={event => setFieldValue(name, event.target.value)}
          onBlur={() => setFieldTouched(name)}
          mask={mask}
          permanents={maskPermanents}
        >
          {inputProps => (
            <Input
              {...inputProps}
              placeholder={placeholder}
              onPressEnter={handleSubmit}
              addonBefore={addOnBeforeValue}
              addonAfter={addOnAfterValue}
            />
          )}
        </ReactInputMask>
      ) : (
          <Input
            disabled={disabled}
            placeholder={placeholder}
            value={values[name]}
            onChange={event => setFieldValue(name, event.target.value)}
            onBlur={() => setFieldTouched(name)}
            onPressEnter={handleSubmit}
            addonBefore={addOnBeforeValue}
            addonAfter={addOnAfterValue}
          />
        )}
    </Form.Item>
  );
}

TextInput.propTypes = {
  values: PropTypes.object,
  errors: PropTypes.object,
  touched: PropTypes.object,
  handleSubmit: PropTypes.func,
  setFieldValue: PropTypes.func,
  setFieldTouched: PropTypes.func,
  name: PropTypes.string.isRequired,
  label: PropTypes.string,
  disabled: PropTypes.bool,
  placeholder: PropTypes.string,
  addOnBeforeValue: PropTypes.string,
  addOnAfterValue: PropTypes.string,
  mask: PropTypes.string,
  maskPermanents: PropTypes.arrayOf(PropTypes.number)
};

export default TextInput;

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

При подтверждении всех нажатий кнопок, вы можете использовать form.submitForm();

Вы можете проверить здесь с рабочей stackblitz demo.

Фрагмент кода

function doSave(values) {
  console.log("saving data", values);
}

function validateAllClick(form) {
  form.submitForm();
  console.log("just validating");
}


function App() {
  return (
    <Layout>
      <h1>Here's My Form</h1>
      <Content>
        <CreateItemForm
          status={editModelStatus}
          setFormRef={setFormRef}
          onSubmit={values => doSave(values)}
          onValidate={validateAllClick}
        />
      </Content>
    </Layout>
  );
}
0 голосов
/ 01 ноября 2018

Я понял это - он не отображал ошибки, потому что Form.Item в TextInput проверял поле, к которому сначала нужно прикоснуться:

<Form.Item
      label={label}
      hasFeedback={!!errors[name]}
      validateStatus={touched[name] && errors[name] && 'error'}
      help={touched[name] && errors[name]}
>

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

<Form.Item
      label={label}
      hasFeedback={!!errors[name]}
      validateStatus={errors[name] && 'error'}
      help={errors[name]}
>
0 голосов
/ 31 октября 2018

Да, вы можете подтвердить нажатие кнопки вместо отправки формы. Некоторые моменты, которые вы должны учитывать.

  1. Вы должны обернуть элементы формы тегом.
  2. Не забудьте использовать перенос метода экспорта с методом создания формы.

    export default Form.create()(SimpleForm);

  3. добавить метод onlick и использовать метод validate, как показано ниже.

    this.props.form.validateFieldsAndScroll ((err, values) => { if (! err) { // Делай что хочешь. } });

  4. Используйте правильный метод проверки для полей

Удачи!

...