form_set_errors() flags ALL instances of a form on a page

nterbogt - February 15, 2007 - 00:40
Project:Drupal
Version:5.x-dev
Component:forms system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:needs work
Description

Form errors are set at the field level in form_set_error() and the array is checked for errors for each individual fields when rendering a form. The problem arises when two forms, which exist on the same page, have the same field names. The forms API marks the fields in both forms as errors.

An example of where multiple forms appear with the same fields is the editview module, where node forms exist repeatedly down the page.

The patch I've included moves the static array out of the form_set_error function, into a private function which allows you to set the arrays contents. I've also created a function which allows you to reset the form array, so it can be called between rendering two forms. This is not an ideal solution, as form errors should really be tied to the form_id so that if the same field exists in a number of forms on the same page, it doesn't mark all of them as an error on a page rebuild.

AttachmentSize
form_2.patch1.89 KB

#1

eaton - February 21, 2007 - 04:49
Status:active» needs review

This looks very promising. I've run it through its paces on number of different forms and seen no ill effects; it also makes certain very impressive hacks like the "editview" module possible.

Long term we want to solve it in a 'proper' way; for now, simply fixing the bug may do. Thoughts? Anyone?

#2

Mojah - May 16, 2007 - 03:37

+1 on this

If for no other reason than the making the editview.module work.

Also confirming that I've tested this patch and have not discovered any errors so far.

#3

eaton - May 16, 2007 - 11:48
Title:Repeating errors» form_set_errors() flags ALL instances of a form on a page
Version:5.1» 6.x-dev

This can probably be integrated withthe new $view_state work that's been done in the FormAPI 3 patch for Drupal 6. If form errors are carried around in the $form_state variable rather than a general array, they can be restricted to just the form that's being rendered.

#4

Dries - May 16, 2007 - 12:16

I don't think the proposed patch solves this problem the right way. I agree that we want to fix this, but we'll want to fix it properly. The solution might be to follow Eaton's advice, or to pass a $form_id into form_set_error(), form_has_errors() and friends.

#5

eaton - May 16, 2007 - 12:37

The latter approach is something chx and I considered for the FAPI3 patch but decided against because of the already-large list of features that were going in. I'd love to see that happen; we already made a similar change to form_set_value(). I don't have time to tackle it myself but I'd be happy to give some guidance to anyone willing to take on the patch.

#6

ray007 - May 17, 2007 - 13:55

subscribing

#7

goose2000 - May 31, 2007 - 15:07
Version:6.x-dev» 5.1
Category:bug report» support request

Hi, I'm trying out the Editview, we need this module or something quite the same. How do I apply this patch? Copy & paste on forms.inc ?
A little scary pasting into the core...

#8

nterbogt - June 1, 2007 - 00:17

There is a page here which details how to apply the patch
http://drupal.org/patch/apply

In linux it's as simple as going to the base installation directory of drupal (the one that has the sites directory in it) and running 'patch -p0 < form_2.patch'
I haven't done this on Windows, but I'm sure that the page above can tell you how to do it in that case.

If you're feeling cautious about patching core, which you have every right to be, I suggest reading patches before applying them.
This patch only effects the file '/includes/form.inc', so you could make a backup of this file and roll back if you're unhappy with the outcome.

Happy patching!

#9

nterbogt - June 1, 2007 - 00:22
Version:5.1» 6.x-dev
Category:support request» bug report

Changing the status back to being a bug against 6.x.

I'd still love to see a resolution on this... but I don't think I have the background knowledge of the forms API to be able to do it myself.
I do like the idea of storing the errors in the $form_state variable, but again, not entirely sure what I'd be doing if I were to try and implement it.

I'd be happy to take a look into it if someone can provide me with some direction.

#10

eaton - June 1, 2007 - 02:38

In a nutshell, we currently call form_set_error($name-of-form-element, $error-message). That stores things in a global variable that is shared across all forms. (whoops!) At its simplest, form_set_error and form_get_errors should be keyed by form id THEN form element. Ideally, though, we would instead build up elements in $form_state['errors']. We'd only display them to the screen when the form is rendered, and things like drupal_execute would be able to check the errors collection after execution to find any problems.

#11

pisco23 - June 25, 2007 - 21:26

This may not be the place for this newbie question but.... I don't have shell access on my shared host, and I don't have any linux box at home (shame on me), so how can I use the patch? Is it possible to manually merge the two files? If not, does "patching" involve any modifications to any files other than form.inc? If its just a modification of this file, could someone provide me with a 'patched' form.inc (or am I being too naive?)

Thanks for any help with this

#12

Zach Harkey - June 26, 2007 - 04:35

+1

This bug is really blocking a lot of cool administrative innovation here.

It's a bug, not a feature. While it may not be the perfect long-term fix, is there any argument that it is better than the current behavior?

#13

StuartDH - September 17, 2007 - 13:45

Tried this on 5.2 but it doesn't patch. Is there an equicvalent for 5.2 as I can't get edit view module to work and it looks as though it's the same problem as with 5.1

#14

fysa - September 28, 2007 - 14:53

Also interested in a 5.x patch/snippet.

#15

mkalkbrenner - November 26, 2007 - 11:39

To require a form_id in addition to a form element is a good approach. But it doesn't solve all problems. The second thing is that you need a possibility to reset the error state of a form. For example if you run a script that calls drupal_execute multiple times on the same form_id (like we create nodes from an data file).
This patch solves the second issue. But due to the fact that a reset of the error array must be called from others it should not be private (function _form_set_error_array should not start with an underscore).

#16

nterbogt - November 28, 2007 - 04:00

You can do this with a form_reset_errors(); anyway though.
Just a thought.

#17

mkalkbrenner - November 28, 2007 - 12:02

You're right. I didn't recognize this function. Sorry.

But if you decide to extend the patch and handle form_ids, form_reset_errors() should have a signature like form_reset_errors($form_id).

#18

Darren Oh - November 28, 2007 - 20:59
Version:6.x-dev» 5.x-dev
Status:needs review» reviewed & tested by the community

Bug fixes should not be put off to the next version when there is a patch available for the current version. Since there have been many changes since Drupal 5, a separate issue should be created for Drupal 6, or the status of this issue should be made “to be ported” after the patch has been applied to Drupal 5.

Applying this patch to Drupal 5 will not affect future versions. From what I can see, it’s ready to be committed. The re-roll below offsets the patch by four lines but does not change any code.

AttachmentSize
form.inc-119208.patch 2.07 KB

#19

drumm - December 17, 2007 - 02:24
Status:reviewed & tested by the community» needs work

As implemented, this is an API change and should not go into Drupal 5.x. As far as I can tell, this does not actually fix the problem, just provides a new API to reset the form error array.

It is usually best to fix bug in the current development version first. More people will look at 6.x bugs since that is the development focus at the moment. This is an exception since 5.x and 6.x Form API are a bit different.

#20

sinasalek - January 12, 2008 - 16:29

An updated version of patch for Drupal 5.6

AttachmentSize
form.inc5-6.patch 1.65 KB

#21

mkalkbrenner - January 15, 2008 - 17:06

I discovered an additional issue. drupal_validate_form() behaves like form_set_error() and caches the form_ids of all forms that have been validated. So every form will only be validated once!

I extended the latest patch in this thread to solve the problem the same way like for form_set_error(). Now it's hopefully possible to really process the same form multiple times in one script.

I also added a function named form_reset_all() to reset errors and validation cache at once.

AttachmentSize
form.inc5-6.patch 2.72 KB

#22

canadrian@elect... - March 11, 2008 - 17:17

Anyone know if this works on 5.7?

#23

mkalkbrenner - March 11, 2008 - 23:56

We currently run drupal 5.7 with form.inc5-6.patch applied.

#24

aexl_konzepto.net - April 27, 2008 - 11:37

+10 :-)
subscribing.

#25

asak - September 5, 2008 - 20:26

Is this still necassery for Editview ? will this work on Drupal 5.10 ?

#26

maria_zk - September 10, 2008 - 01:30

subscribe

#27

1.kenthomas - November 25, 2008 - 05:01

@25: Patch appears to work for 5.10, cannot tell if it is necessary for edit-view (don't see a difference).

#28

Darren Oh - March 18, 2009 - 13:58

This is only necessary for Editview when JavaScript is disabled in the browser.

 
 

Drupal is a registered trademark of Dries Buytaert.