Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Form item error, should be shown first time on blur, not on change #12542

Closed
1 task done
tylik1 opened this issue Oct 8, 2018 · 14 comments
Closed
1 task done

Form item error, should be shown first time on blur, not on change #12542

tylik1 opened this issue Oct 8, 2018 · 14 comments
Assignees
Labels
🐛 Bug Ant Design Team had proved that this is a bug.

Comments

@tylik1
Copy link

tylik1 commented Oct 8, 2018

  • I have searched the issues of this repository and believe that this is not a duplicate.

Version

3.10.0

Environment

Google Chrome latest version

Reproduction link

Edit on CodeSandbox

Steps to reproduce

type one letter in the field with 2 rules: "required" and "min"

What is expected?

Error should not show when user is editing input, for the first time

What is actually happening?

Error for "min" rule is shown when user edits form input


Expected behavior:
User starts editing form input;
Error is not shown;
User blurs input;
error is shown;
From then on, error is shown on onChange;

I also know there is a validateTrigger which can be set to "onBlur", but it's not the case, it should only work once.

Please visit the link where it works properly with Formik plugin.
https://codesandbox.io/s/lp904qlj1q

@zombieJ
Copy link
Member

zombieJ commented Oct 9, 2018

validateTrigger: "onBlur"

@ant-design-bot
Copy link
Contributor

Hello @tylik1, we use GitHub issues to trace bugs or discuss plans of Ant Design. So, please don't ask usage questions here. You can try to ask questions on Stack Overflow or Segment Fault, then apply tag antd and react to your question.

你好 @tylik1,Ant Design Issue 板块是用于 bug 反馈与需求讨论的地方。请勿询问如何使用的问题,你可以试着在 Stack Overflow 或者 Segment Fault 中提问(记得添加 antdreact 标签哦~)。

@tylik1
Copy link
Author

tylik1 commented Oct 9, 2018

It is not usage question, it is bad UI experience, and it would be good if additional option is added to show first error onBlur, not onChange.

validateTrigger onBlur is not the case. It will always validate on blur, but this behavior should happen only first time, as i've described above, and as it happens on example in Formik.

There is no way to make validateTrigger dynamically - e.g. change from 'onBlur' to 'onChange' with state.

@zombieJ zombieJ added 🐛 Bug Ant Design Team had proved that this is a bug. and removed Usage labels Oct 9, 2018
@zombieJ
Copy link
Member

zombieJ commented Oct 9, 2018

Tested. validateTrigger change not work. Reopen issue.

@lalitkapoor
Copy link

This is still an issue for me with antd version 3.20.7. Errors should not show when user is editing input, for the first time. While it's possible to address this issue by creating handlers for onChange and onBlur that will update the validateTrigger via state. I think it would be better if this was the default behavior. Another example of where this is very frustrating is if you have the following rules for an email field:

rules: [
  { type: "email", message: "The input is not a valid -mail" },
  { required: true, message: "Please include your email address" }
]

It would be much nicer, in my opinion, if the user doesn't see "This input is not a valid Email" while they are typing in their email for the first time.

@Enalmada
Copy link

Enalmada commented Nov 22, 2019

Following advice above, this is what I did to work around this issue. Start with onBlur state for email and switch to onChange when there is an error so the error goes away when error is fixed. Not saying it is perfect but it seems to be better than showing error when people start typing.

   const [emailValidateTrigger, setEmailValidateTrigger] = useState("onBlur");
   ...
 <FormItem label="Email">
            {form.getFieldDecorator("email", {
              validateTrigger: emailValidateTrigger,
              rules: [
                {
                  type: "email",
                  message: "The input is not valid E-mail!"
                },
                {
                  required: true,
                  message: "Please input your E-mail!"
                }
              ]
            })(
              <Input
                placeholder="Email"
                type="email"
                onChange={() => {
                  if (form.getFieldError("email")) {
                    setEmailValidateTrigger("onChange");
                  } else {
                    setEmailValidateTrigger("onBlur");
                  }
                }}
              />
            )}
          </FormItem>

@dimasusername
Copy link

@Enalmada thanks for this!

I shortened it in my code like so:

const { getFieldError } = form; as we might use it for several fields

and then:

onChange={() =>
  setEmailValidateTrigger(getFieldError('email') ? 'onChange' : 'onBlur')
}

@samfed
Copy link

samfed commented Apr 7, 2020

@Enalmada @dimasusername Thanks for the idea.
I have shortened it more like this, where there is no need to use onChange handler.

const { getFieldError } = form;

  getFieldDecorator("email", {
    validateTrigger: getFieldError('email') ? "onChange" : "onBlur",
    rules: [
      {
        required: true,
        message: "Please input your E-mail!",
      },
    ],
  })(<Input placeholder={localeData.email} />);
}

@engmsilva
Copy link

I tested the examples above and couldn't get them to work on Antd Form V4.

I solved the problem with the code below the three validateTrigger options "onBlur", "onChange" and "OnSubmit". I got a good behavior when necessary to do another type of validation in the field. Ieia is simply to clear the error field when "onBlur" and "onSubmit". Developers could think of something native when choosing these options for validateTrigger.

function onResetError(field) { if(getFieldError(field)){ setFields([ { name: field, errors: [], }, ]); } }

<Form.Item label='Confirmar Senha' name='new_password_confirm' dependencies={['new_password']} hasFeedback validateTrigger="onBlur" rules={[ { required: true, message: 'Confirm your password.', }, { min: 8, message: 'The password must be at least 8 characters long.' }, { validator: validadePassword, } ]} > <Input.Password size="large" prefix={<LockOutlined className="site-form-item-icon" />} disabled={stUpPassword} onChange={() => onResetError('new_password_confirm')} /> </Form.Item>

@ashkan-pm
Copy link
Contributor

ashkan-pm commented Jul 13, 2020

This is definitely the sought after behavior most of the times imo and getting it to work in v4 is really frustrating. Why not provide this sort of behavior out of the box? I'd be happy to do it.
Or maybe I'm missing something? As far as I can tell the only way to do this right now is to change validateTrigger with state.

@musacanminaz
Copy link

musacanminaz commented May 1, 2021

This is the easy solution I use check email field. In this why first time it use onBlur, after field checked validate type change to onChange.

...
const [emailValidateType, setEmailValidateType] = useState("onBlur");
...
<Form.Item name="email" validateTrigger={emailValidateType}
          rules={[
            {
              required: true,
              type: "email",
              message: t("email_error"),
              pattern: new RegExp(/^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/),
            },
          ]}
        >
          <Input
            prefix={<MailOutlined />}
            placeholder="Email Address"
            autoCapitalize="none"            
            onBlur={() => setEmailValidateType("onChange")}
          />
</Form.Item>

@vitorpedeo
Copy link

vitorpedeo commented Oct 6, 2021

Extending @musacanminaz answer, if you have more than one field that needs this type of behavior, you can build it like this.

First of all, define a state containing all field names that will have dynamic validation trigger. Start them with onBlur.

const [validationMode, setValidationMode] = useState({
  email: 'onBlur',
  acessToken: 'onBlur',
});

Next, create a funtion that will update validation trigger of a particular field.

const changeValidationMode = fieldName => {
  setValidationMode(prevState => ({ ...prevState, [fieldName]: 'onChange' }));
};

Now, use the function on onBlur handler of your fields.

<Input type="email" onBlur={() => changeValidationMode('email')} />

The only problem with this approach is when the form is submitted and the fields are invalid, the validation mode will not be updated to onChange. To fix this problem, just use onFinishFailed Form prop.

onFinishFailed={() => {
  const newValidationMode = Object.keys(validationMode).reduce(
    (obj, curr) => ({ ...obj, [curr]: 'onChange' }),
    {},
  );
  
  setValidationMode(newValidationMode);
}}

@mleister97
Copy link

Extending @musacanminaz answer, if you have more than one field that needs this type of behavior, you can build it like this.

First of all, define a state containing all field names that will have dynamic validation trigger. Start them with onBlur.

const [validationMode, setValidationMode] = useState({
  email: 'onBlur',
  acessToken: 'onBlur',
});

Next, create a funtion that will update validation trigger of a particular field.

const changeValidationMode = fieldName => {
  setValidationMode(prevState => ({ ...prevState, [fieldName]: 'onChange' }));
};

Now, use the function on onBlur handler of your fields.

<Input type="email" onBlur={() => changeValidationMode('email')} />

The only problem with this approach is when the form is submitted and the fields are invalid, the validation mode will not be updated to onChange. To fix this problem, just use onFinishFailed Form prop.

onFinishFailed={() => {
  const newValidationMode = Object.keys(validationMode).reduce(
    (obj, curr) => ({ ...obj, [curr]: 'onChange' }),
    {},
  );
  
  setValidationMode(newValidationMode);
}}

This should be the default without writing so much boilerplate

@mleister97
Copy link

Developed a custom hook solving exactly this issue. See here and leave an upvote guys! https://stackoverflow.com/a/75962381/12900361

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 Bug Ant Design Team had proved that this is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.