FormState::setErrorByName does not set multiple errors on the same element

Created on 14 October 2016, over 8 years ago
Updated 10 October 2023, over 1 year ago

Problem/Motivation

This is a follow-up from the alexpott's comment #2767125-22: EntityFormDisplay::validateFormValues sets form state errors by empty name string instead using the provided form element β†’ .

The problem with FormState::setErrorByName is that it will bet only one error per element and ignore all following calls with the same name.
What currently would happen is that if there are 3 errors for an element only the first one will be shown to the user, after the users clears the first problem and submits again now the second error will be shown ...
This would be the case e.g. when having entity level validation and having to set multiple errors on a whole nested entity form. This would happen in EntityFormDisplay::validateFormValues where all the entity level validation errors are set on the given form element.

Proposed resolution

FormState::setErrorByName should support multiple errors per name, but changing how the function sets errors and what FormState::getErrors returns will be an API break, so a non invasive solution is needed.

Remaining tasks

Find a proper solution.

User interface changes

See all the errors at once for a given element instead of having to resubmit the form to see the next error after the first one is fixed.

API changes

none at moment.

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
FormΒ  β†’

Last updated 26 minutes ago

Created by

πŸ‡©πŸ‡ͺGermany hchonov πŸ‡ͺπŸ‡ΊπŸ‡©πŸ‡ͺπŸ‡§πŸ‡¬

Live updates comments and jobs are added and updated live.
  • Needs subsystem maintainer review

    It is used to alert the maintainer(s) of a particular core subsystem that an issue significantly impacts their subsystem, and their signoff is needed (see the governance policy draft for more information). Also, if you use this tag, make sure the issue component is set to the correct subsystem. If an issue significantly impacts more than one subsystem, use needs framework manager review instead.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @smustgrave: Pinging here, as this issue for example blocks contrib issues like πŸ› Use of $form_state->setErrorByName() within email_registration_user_login_validate prevents other core errors Needs work . Also see #39

    To me, it looks like a misconception in multiplicity here, what can we do for "Needs subsystem maintainer review" as of #37?

  • πŸ‡©πŸ‡ͺGermany Grevil

    I know this is probably far-fetched and might need too much refactoring, but in some cases it would be super helpful if each element error could have their own ID. This way, it would be possible to override specific element errors by ID.

    I just came to this idea, while taking a look at πŸ› Use of $form_state->setErrorByName() within email_registration_user_login_validate prevents other core errors Needs work . Basically what we want there is to only overwrite the error message that gets thrown, when using incorrect credentials (password / username) and leave all other errors thrown (e.g. the "Too many failed login attempts" error message). An optional "$eid" parameter would be enough:

      /**
       * @param string $name
       *   The name of the form element. If the #parents property of your form
       *   element is array('foo', 'bar', 'baz') then you may set an error on 'foo'
       *   or 'foo][bar][baz'. Setting an error on 'foo' sets an error for every
       *   element where the #parents array starts with 'foo'.
       * @param string $eid
       *   (optional) The error id to use for your error
       * @param string $message
       *   (optional) The error message to present to the user.
       *
       * @return $this
       */
      public function setErrorByName($name, $eid, $message = '');
    

    The only problem is, that core would need to adjust all its "setErrorByName()" calls. Otherwise, this wouldn't have any real benefit.

    What are everybody's thoughts on this? Would you agree with this feature request? Should I create a follow up issue for that?

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    Agree with additional benefits from #42!
    That shouldn't be a blocker and might be a follow-up, but it has been a good idea to allow a key for such, to allow altering!

    Like other areas do better or worse since Drupal 7, e.g. https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_... ($key) or #attached in Drupal 8+! It's a lovely and helpful general concept.

    Good point @Grevil!

    Let's hear what the maintainers think.

Production build 0.71.5 2024