Steps to reproduce:

1) Change the #weights of elements on a built-in Drupal form to reorder form elements. The registration form is a good choice.
2) Submit the form with errors in every validated field.
3) Notice that the order the validation messages appear in does not match the order of the fields on the form.

I've prepared a patch that solves this issue by sorting child elements before doing any validating in _form_validate(). Patch is built against Drupal 5.1.

CommentFileSizeAuthor
#79 177124-79.patch4.28 KBLuke.Leber
#78 177124-78.patch4.35 KBLuke.Leber
#72 form_validation-177124-72.patch790 byteshgoto
#67 interdiff-177124-59-67.txt638 byteswturrell
#67 form_validation-177124-67.patch3.7 KBwturrell
#59 interdiff-177124-55-59.txt577 byteshgoto
#59 form_validation-177124-59.patch3.74 KBhgoto
#59 form_validation-177124-59-test_only.patch2.69 KBhgoto
#55 form_validation-177124-55.patch3.74 KBhgoto
#55 form_validation-177124-55-test_only.patch2.7 KBhgoto
#52 validate_in_order-177124-52.patch838 byteshgoto
#49 validate_in_order-177124-49.patch397 bytespreksha
#47 form_validation-177124-47.patch1.04 KBAjitS
#47 interdiff.txt839 bytesAjitS
#45 form_validation-177124-45.patch1.04 KBtim.plunkett
#41 form_validation-177124-41.patch170.72 KBNitesh Sethia
#39 form_validation-177124-39.patch170.56 KBNitesh Sethia
#30 177124-sort-before-element-validation.patch858 byteslyricnz
#16 validate_in_order-177124-16.patch517 bytesmrfelton
#16 D7-validate_in_order-177124-16-do-not-test.patch497 bytesmrfelton
#14 D7-validate_in_order-177124-14-do-not-test.patch705 bytesroblav
#13 validate_in_order-177124-13.patch725 bytesroblav
#10 validate_in_order-177124-5.patch669 bytesroblav
#4 validate_in_order-177124-4.patch903 byteseffulgentsia
validate_in_order_51.patch567 bytesADLongwell
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ADLongwell’s picture

Version: 5.1 » 5.2

Correction.. previous attachment was actually built against Drupal 5.2. I forgot that I had upgraded this installation.

killes@www.drop.org’s picture

Version: 5.2 » 5.x-dev
Status: Needs review » Reviewed & tested by the community

Patch works and still applies.

drumm’s picture

Version: 5.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Needs work

This does not completely solve the issue. The errors are displayed in the order form_set_error() is called. This is controlled by the hook invocation order and what order the validate hooks look at the fields. This patch does of course solve the issue for empty required fields and any modules which walk through the fields in form order.

I would like to see this sort of change be written for the development version and then backported. The code in Drupal 6 looks like it has the same behavior as 5.

effulgentsia’s picture

Title: Form Validation Messages Appear in Incorrect Order » Form validation messages appear in incorrect order, should form_builder() return a sorted $form?
Status: Needs work » Needs review
FileSize
903 bytes

If this is to be fixed at all for D7, I think this patch is the way to do it. As per #3, it's not a 100% solution, but it probably gets us most of the way there, and remaining edge cases would need a deeper FAPI refactoring (D8 material). But to be honest, I think even this patch should be bumped to D8. Leaving the version alone for now, so that others can make that call.

sun’s picture

Issue tags: +Needs tests

Well, why not. Just moves sorting from drupal_render() to form_builder(), so nothing lost.

With a proof that we're fixing a bug here, RTBC.

sun’s picture

#4: validate_in_order-177124-4.patch queued for re-testing.

zubikit’s picture

Issue tags: -Needs tests

#4: validate_in_order-177124-4.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +Needs tests

The last submitted patch, validate_in_order-177124-4.patch, failed testing.

roblav’s picture

Version: 7.x-dev » 7.12
Status: Needs work » Needs review
FileSize
669 bytes

Using the patch in #4 I've created an updated patch for Drupal 7 using version 7.12.

Status: Needs review » Needs work

The last submitted patch, validate_in_order-177124-5.patch, failed testing.

sun’s picture

Version: 7.12 » 8.x-dev
Issue tags: +Needs backport to D7

Needs to be fixed in HEAD first.

roblav’s picture

Status: Needs work » Needs review
FileSize
725 bytes

Here's the updated patch for 8.x-dev based on comment #4

roblav’s picture

Here's the D7.x-dev patch, renamed as suggested in http://drupal.org/node/332678

mrfelton’s picture

Status: Needs review » Needs work

Hmm. Interestingly, this patch actually messes up the weighting of field_groups, which always display right at the bottom of a node/add form, below the vertical tabs and form actions with this patch applied (D7).

mrfelton’s picture

Status: Needs work » Needs review
FileSize
497 bytes
517 bytes

Here is a slightly different version of the patch, which does the validation in order, but doesn't mess with the form so much aside from that.

sun’s picture

Title: Form validation messages appear in incorrect order, should form_builder() return a sorted $form? » Form validation messages appear in incorrect order

Aah, that makes much more sense! :)

Now we should take over the inline comment from #13 to explain why we're enforcing elements to be ordered there.

Also, we still need a test.

mrfelton’s picture

Status: Needs review » Needs work

There is still a problem with this. Once you submit a form, if it has validation errors, then when that form is rebuilt and rerendered, a lof of the fields show up under the submit/action buttons - similar to my post in #15 but now only after a validation failure.

Bartezz’s picture

I know I should just click the follow button but am so happy this issue is being worked on. Always bugged me that the error messages were out of order but never succeeded in fixing this. It's a big usabillity issue IMO so kuddos to all of you!

Cheers

mrfelton’s picture

Status: Needs work » Needs review

I just tested this patch on a clean Drupal 8 and Drupal 7 installation, and it actually seems to work properly. The problem I'm experiencing only seems to happen when the field_group module is used, which makes me think the issue is with field_group and no with this patch. Setting back to needs review so that others can test and confirm.

mrfelton’s picture

I have confirmed that the problem with the fields reordering on submit, is indeed a problem with field_group. I have a patch that solves the field_group issue, a feature module to test with, and a screenshot that shows the problem at #1657306: Field group form elements are placed at the wrong location within the form array structure..

lyricnz’s picture

Status: Needs review » Needs work

Works for me, but sun suggests we need a comment and a test. Marked #1843520: Field Validation Order is Wrong a duplicate of this.

GoddamnNoise’s picture

I've just tried the patch, but there is a problem with it. Try this:

- Make a fresh install of Drupal 7.17 (or Drupal 7.x-dev).
- Apply the patch.
- Edit the "Basic Page" content type, go to the "Manage fields" tab and make the "Body" field required. Then, reorder the fields making the "Body" field the field with the lowest weight and the "Title" field the field with the highest weight.
- Then, try to create a new "Basic Page" node. Leave all the fields blank and click on the "Save" button.
- You'll see that the validation errors are shown in the wrong order. In addition, the fields on the node creation form are now rendered in the wrong order too!.

lyricnz’s picture

You're right! What a strange bug. This works OK if you call element_children() on a copy of $elements, but that's pretty inefficient. Still digging.

GoddamnNoise’s picture

Yeah, it's really weird. I don't know the code very well, so I won't be able to help very much. I've looking for a chance to retrieve the fields from the database in the right order, but that's not easy, because the weight of each field is stored in the 'data' column, which is a BLOB column.

lyricnz’s picture

No no, definitely don't want to go to the DB, all the data needed is in $form/$elements around the place. I'm just poking around to understand how the field stuff moves "title" to the correct place, quite late in the game I think. I can't look at it now, will look again after dayjob work.

lyricnz’s picture

Interesting. I think this issue is related specifically to the Title field, because it's still not quite like the other ones - it gets a weight of -5 from the node_content_form() regardless of it's weight from the UI. I'm still trying to figure out where the weight from the field gets applied (not an expert).

lyricnz’s picture

OK, the reason this doesn't work quite right for "title" is that the weight of non-fields are only fixed up in _field_extra_fields_pre_render() called during drupal_render(). At the time we're validating the form, this hasn't been done yet.

Besides the fact that the weight isn't set yet, I *think* the reason that sorting $elements in _form_validate() breaks the field ordering is that $elements['#sorted'] is set to true as a side-effect, which means that when attempting to sort *after* pre_render has changed the weights, it thinks the $elements are already sorted, so doesn't re-sort.

So... a combination of issues:
- form needs to be pre_rendered to get the right weights?? (this might be bad)
- _field_extra_fields_pre_render() should unset #sorted if #weight is modified

GoddamnNoise’s picture

That has a lot of sense. Nice job!.

lyricnz’s picture

Status: Needs work » Needs review
FileSize
858 bytes

I don't think we should call pre_render from validate - that's just too evil. So, we can't really fix this completely. We can get pretty close by sorting a *copy* of $elements (a copy so we don't modify $elements, which causes another bug later).

GoddamnNoise’s picture

Hi again, lyricnz,

I've just tested the patch. Doing the same as in #23, the order of the field validation errors are still wrong, but the order of the fields after validation is the right one in the node create/edit form.

Going further with the test case explained in #23, adding another required field to the "Basic Page" content type and trying to create a new node of that content type leaving all the three (required) fields blank results in:

- The order of the fields after the validation is right in the node create/edit form.
- The order of the field validation errors shown is right except for the "Title" field, which is not really a regular field.

lyricnz’s picture

Yup, the patch in #30 should fix most of the ordering of field validation messages, and not break the form ordering. This probably still needs a test, but since the solution is incomplete, I'd like some buy-in from Real Core Coders before I spend the time on that. Plus a pointer on how to test it.

guschilds’s picture

I manually applied the patch from #30 to Drupal 7's form.inc because I was having the same issue. After a few quick tests it seems to have fixed the problem, but I'd love to know if there are any possible side effects that arise from more thorough testing by those closer to this code. Thanks!

Liam Morland’s picture

Liam Morland’s picture

I don't think the solution in #30 fixes all cases of this. For example, the Webform Validation module calls form_set_error() in an order that may not match the order of the form components and it does all of its validation at once, so its errors will be together, not sorted together with validation done by other parts of Drupal.

Right now, form_set_error() calls drupal_set_message() as part of its operation. What we need is for it to instead gather all the errors together. Then, once all errors have been set by all modules, sort the errors by the component to which they apply and then call drupal_set_message().

This may also play into the solution: #569094: Get rid of form_set_error().

kjholla’s picture

Subscribing...

Liam Morland’s picture

jhedstrom’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs reroll

Needs reroll and tests. This might not even be applicable to 8.x at this point.

Nitesh Sethia’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll +#drupalgoa2015
FileSize
170.56 KB

Rerolled the patch.

Status: Needs review » Needs work

The last submitted patch, 39: form_validation-177124-39.patch, failed testing.

Nitesh Sethia’s picture

Status: Needs work » Needs review
FileSize
170.72 KB

Rerolled the patch

Status: Needs review » Needs work

The last submitted patch, 41: form_validation-177124-41.patch, failed testing.

tim.plunkett’s picture

Issue tags: +Needs reroll

The last two patches look like they're reverting all of the changes to the form system. It's about 200x bigger than the last valid patch.

AjitS’s picture

I tried rerolling #30 and the size of the new patch was just about the same as on #39 or #41. And looks like it is adding back all the parts of code which was removed.

I wonder if this issue is still valid. The patch on #30, changes a loop inside the function _form_validate(), which is no longer present in the file, or any file in the core.

tim.plunkett’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
1.04 KB

Still needs tests, but here is the patch from #30 rerolled.

Xano’s picture

+++ b/core/lib/Drupal/Core/Form/FormValidator.php
@@ -214,8 +214,12 @@ protected function finalizeValidation(&$form, FormStateInterface &$form_state, $
+    $elements_copy = $elements;

Call this $elements_sorted for readability and this looks good to go :)

AjitS’s picture

Done.

Xano’s picture

This also needs tests, as mentioned in #45. My apologies for the confusion.

preksha’s picture

Here's the updated patch for 7.37 based on comment #16

preksha’s picture

Here's the updated patch for 7.37 based on comment #16

Status: Needs review » Needs work

The last submitted patch, 49: validate_in_order-177124-49.patch, failed testing.

hgoto’s picture

here's the patch for Drupal 7, 7.42. The only difference between the patch #30 and this is the line number.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

hgoto’s picture

Assigned: Unassigned » hgoto
hgoto’s picture

As far as I understood, the left task for this D8 issue is only adding a test. I added a test which extends KernelTestBase to the patch #47. I expect that this test-only patch fails and another patch with working code and test works.

I'd like someone to review this. Thank you.

hgoto’s picture

Assigned: hgoto » Unassigned

The last submitted patch, 55: form_validation-177124-55-test_only.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 55: form_validation-177124-55.patch, failed testing.

hgoto’s picture

The test class name was wrong in the patch #55. I fixed it and try the test again. I'd like someone to review this.

The last submitted patch, 59: form_validation-177124-59-test_only.patch, failed testing.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

quotesBro’s picture

OMG, the bug was reported in 2007, and still not fixed.
#52 worked for me (Drupal 7.50)

wturrell’s picture

Status: Needs review » Reviewed & tested by the community

This is over nine years old so it would be good to make some progress with it…

- Able to reproduce original problem (8.2.x)
- Fixed by patch #59
- Have rerun testbot (8.2.x) and it passes
- No UI changes
- Seems in scope
- Not seeing any coding standard errors
- Code itself OK to me (it just sorts the element array by weight first before validating it)
- Code is commented
- Tests: I've not used Simpletest myself yet – test looks logical but is line 53 there for a reason or is it just orphaned?

$user_input = $form_state->getUserInput();

The last submitted patch, 52: validate_in_order-177124-52.patch, failed testing.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

cilefen’s picture

Status: Reviewed & tested by the community » Needs work

Agreed: what is the purpose of $user_input = $form_state->getUserInput()? Let's get that sorted and get this in!

wturrell’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
3.7 KB
638 bytes

Done.

xjm’s picture

Version: 8.3.x-dev » 8.4.x-dev
Issue tags: +DrupalCampNJ2017

Thanks @wturrell! In general, you should not mark your own patches RTBC, but in this case it is just a very small change that we approved in #66, so adding my +1 for the RTBC. Good writeup of the review in #63 also.

@cilefen and I went back and forth about whether to commit this issue to 8.4.x only or to backport it. We did come up with some obscure scenarios where fixing this bug and correcting the behavior might change something for some code somewhere (since the fix is in the form subsystem itself), so committing to 8.4.x. only for now on account of the alpha phase.

@Nitesh Sethia, I removed credit for the issue for you since your patches were unfortunately not correct and disrupted the flow of the issue. For your next core issue, I'd look carefully at https://www.drupal.org/contributor-tasks/reroll so we can include your work in the issue! Thanks for contributing.

Similarly for @preksha, your patch update did not take into account the recent comments on the issue. To receive issue credit in the future, you can build off the latest comments on the issue and provide an interdiff: https://www.drupal.org/documentation/git/interdiff

Saving issue credit.

  • xjm committed cd05ee4 on 8.4.x
    Issue #177124 by hgoto, roblav, mrfelton, AjitS, wturrell, lyricnz,...
xjm’s picture

Status: Reviewed & tested by the community » Patch (to be ported)

I believe the Drupal 7 maintainers want us to mark issues PTBP until the separate D7 followup issue can be created and referenced on this issue. Once that's done, we mark this issue to fixed in 8.4.x. again. Thanks everyone!

hgoto’s picture

Thank you, @Mikhail K. @wturrell @cilefen @xjm!

Following the comment #70, I opened a new issue for D7 backport.

#2850273: [D7] Form validation messages appear in incorrect order

Can we move this issue to Fixed?

hgoto’s picture

Status: Patch (to be ported) » Needs review
FileSize
790 bytes

This is a small point. The method name of the test case introduced in #55 is testLimitValidationErrors(). I used this name mistakenly and it's not proper for the content of the test. If possible, I'd like this to be adjusted.

Here is a trial patch. This patch expects that the previous patch was already applied.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Luke.Leber’s picture

I'm including a test case that should show that conditionally required fields are sometimes out of order. (Drupal 8.8)

Please let me know if this should be a separate issue. Thanks.

Luke.Leber’s picture

FileSize
4.28 KB

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

pameeela’s picture

@Luke.Leber, thanks for the patch - definitely a new issue would be good for this.

I also think this issue should be marked 'Fixed', since it was committed to 8 and there is a separate task for D7, perhaps with a follow up for the small change in #72.

pameeela’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.