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

Allow something other than the field "name" property to be the default when showing error messages. #9954

Open
1 task done
evantrimboli opened this issue Apr 7, 2018 · 12 comments

Comments

@evantrimboli
Copy link

evantrimboli commented Apr 7, 2018

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

What problem does this feature solve?

By default, when an error message is displayed is uses "%s is required", where %s is the name of the field. The field name isn't necessarily something to present to the user. For example, my field name might be parentId, but to the user I want to display Parent. In essence, across the entirety of my app I want to use the label as opposed to the name to display errors.

What does the proposed API look like?

I had a browse around the source, it seems as though fullField is an attempt to allow this, however it doesn't appear to work correctly. See: https://codesandbox.io/s/v06vq5zlx0 which attempts to use fullField.

A potential API would be something like:

rules: [{
  required: true,
  errorProp: 'Parent'
}]
@dengfuping
Copy link
Contributor

@evantrimboli It's unnecessary to supply such a feature. You could customize your error message using message property.

@evantrimboli
Copy link
Author

evantrimboli commented Apr 8, 2018

Of course I could customize the label, but that's not the point. It doesn't scale for an app of any large size. There is no ability to have a convention based naming system.

For example, all the field names in my app are lower case. This means whenever an error is displayed, it will show as name is required. It would make more sense for it to read Name is required.

Now say I have 10 fields in a form. For each of those required field, I need to manually set the message because I want the required message to use Name and not name. This requires a bunch of repetition where it could be easily solved using a transform function.

Also consider I have a field with a min and max value length rule. That means I need to duplicate the text for both rules:

min: '%s must be at least %s characters',
max: '%s cannot be longer than %s characters',

Only because I want the label to be Product Price instead of product_price.

The framework should not just assume that the underlying programmatic name for a field should be something displayed to the user. Why do field labels exist? For this exact reason. The name for the error message should correspond with the label by default, because the label is shown to the user, not the name.

There should a way, either globally or potentially per rule some way to automatically transform the the field name before it is sent to the formatter.

The other thing you didn't address is that it seems to already have an attempt to support this using fullField, but it's not documented and doesn't seem to work correctly. If it were intended to solely use the name property, why does it pass fullField to the validator in the first place?

I'd suggest you reconsider this,, your answer doesn't seem particularly deeply considered.

@SyuTingSong
Copy link

@evantrimboli Similar problem I hit. However, the fullField in rules is not the label or display name or such things, fullField is the full pathname for depp object validating. I create a feature request issue to the underlying lib async-validator project for a new localField for message displaying localization field name.

@evantrimboli
Copy link
Author

Great, thanks for your post! It would be nice to be able to:
a) Specify a particular value for a field (basically the label) to also be used for the error
b) Have some kind of transform function that could be applied across your app, for example:

const transform = s => s.split('_').map(capitalizeFn).join(' ')

@rohit-gohri
Copy link

Any way to do this now? I'd like to use the label property for validator error messages

@csandanov
Copy link

csandanov commented Jan 31, 2020

I was also surprised to find out it that names are used instead of labels in error messages. I believe it should be label by default because a label is what a user sees, not name property. Especially this is a problem when you have multiple fields and you have to make them unique, e.g. name-${id}.

I tried to customize it via:

const validateMessages = {
  required: "'${label}' is required!",
};

but it doesn't recognize the label property for some reason.

@rohit-gohri
Copy link

I tried to customize it via:

const validateMessages = {
  required: "'${label}' is required!",
};

but it doesn't recognize the label property for some reason.

The message is made by the rule validator and not the form so it doesn't have access to label.

If you send the label in the rule, like : {required: true, label: 'Email ID'} it will show properly but I don't think that is officially supported.

@csandanov
Copy link

@rohit-gohri yes, that works, although I'm using typescript and gives a warning that label is not assignable to Rule[]

@devuxer
Copy link

devuxer commented Apr 5, 2020

@rohit-gohri & @csandanov,

@rohit-gohri 's suggestion is actually pretty promising! Perhaps it could just be made official and added to the documentation.

I was even able to get it to work with TypeScript with these three steps:

  1. Copy the default validation messages from the source.
  2. Replace ${name} with ${label}.
  3. Add this simple utility function:
    // add label property to each rule
    export function getRules(label: string, ...rules: Rule[]): Array<Rule & { label: string }> {
        return rules.map(x => ({ ...x, label }));
    }

Usage for required + len:

<Form.Item name="zipCode" noStyle rules={getRules("Zip Code", { required: true, len: 5 })}>
    <Input placeholder="Zip Code" />
</Form.Item>

Usage for required + pattern w/ custom message:

<Form.Item
    name="legalName"
    label="Legal Name"
    extra="Full, official name {e.g., Robert Smith)"
    rules={getRules(
        "Legal Name",
        { required: true },
        {
            pattern: /^ *[A-Za-z-',.]+( +[A-Za-z-',.]+)+$ */,
            message: `'Legal Name' must have at least two words and only these symbols: - ' , . `
        }
    )}
>
    <Input />
</Form.Item>

@rohit-gohri
Copy link

rohit-gohri commented Apr 5, 2020

@devuxer I don't think you even need to do that now, label support was added in the 4.1 release : #21835
Just need to do the first 2 steps you mentioned.
Though the rules hack is still useful if you want to use it for some other custom prop.

@devuxer
Copy link

devuxer commented Apr 5, 2020

@rohit-gohri,

Ahh, I didn't realize. Thanks for letting me know 👍

@yoyo837
Copy link
Contributor

yoyo837 commented Mar 13, 2021

Can this be closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants