Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
We have a number of issues open to document $form_state, and it's probably better to consolidate them here.
These items at least should be documented:
- $form_state['cache'] and $form_state['no_cache'] (probably internal only) - from #689084: Document $form_state['cache']
- $form_state['redirect'] - from #579366: How many ways are there to redirect after form submission? and #623906: Fix FAPI Reference: $form['#redirect'] for Drupal 6
- $form_state['anything_that_does_not_conflict'] is persisted
- $form_state['storage'] is just one kind of $form_state['anything_that_does_not_conflict']
- $form_state['triggering_element'] replaces the deprecated $form_state['clicked_button']. It can be used to identify which element triggered a submission or AJAX pseudo-submission. Use $form_state['triggering_element']['#name'], for example, to identify a button.
- $form_state['rebuild'] = TRUE can be set in either submit or validate functions, and causes the form to rebuild instead of completing. This is typically used in multistep forms.
- $form_state['values'] has not really changed in D7: It's an array of values that were populated in the last form action (submission, validation, etc.). Its structure is altered by $form['#tree'].
- $form_state['input'] is the $_POST array, and for security reasons should never be used except by Form API internals
Comment | File | Size | Author |
---|---|---|---|
#26 | form-state-docs-follow-up-802746-26.patch | 2.13 KB | effulgentsia |
#23 | drupal.form_state_doc_802746_23.patch | 6.81 KB | rfay |
#20 | drupal.form_state_doc_802746_19.patch | 6.49 KB | rfay |
#16 | drupal.form_state_doc_802746_16.patch | 6.46 KB | rfay |
#13 | 802746-doccleaned.patch | 5.92 KB | jhodgdon |
Comments
Comment #1
jhodgdonI suggested to rfay on IRC that $form_state should be documented on
http://api.drupal.org/api/group/form_api/7
Which is a rather lame page anyway. It could use some expansion... such as documentation of what $form and $form_state are, and maybe a suggestion of what the key functions are, such as drupal_get_form() or something?
Comment #2
rfayIn addition, that section should explain
Comment #3
effulgentsia CreditAttribution: effulgentsia commentedsubscribe
Comment #4
rfayHere is a first cut at improving this. Opinions and improvements welcome.
The API-module-rendered section is at http://drupalexamples.info/node/3
Comment #5
mmccollow CreditAttribution: mmccollow commentedsubscribing
Comment #6
jhodgdonThis is a VAST improvement and is almost ready to be RTBC... A few things need changing (most minor):
a) Between "Its keys are:" and the beginning of the list of keys, there should not be a blank line.
b) There are some line wrapping problems, such as:
Some of the words on the 2nd line should be moved up.
c) English grammar/usage:
"... a URL which ..." => "a URL that"
d) I don't think I'd include information about deprecated parts of $form_state, and this has a redundant "element that caused submission" in it:
e) Shouldn't start this with "This is":
f) Persist is not a transitive verb, so nothing can "be persisted". Maybe use persistent?
g) Another "which" problem:
In this case, I think I would reword this to:
In addition, the @link form_example_tutorial.inc Form Example Tutorial @endlink provides many form examples from basic to multistep forms.
h) I think I would move the information about where to learn about $form to above the whole discussion about $form_state. And it shouldn't say "more" information about $form, because there is basically zero information about $form in this doc... Actually, maybe there should be a short paragraph just before the $form_state section, something like this:
The $form argument to form-related functions is a structured array containing the elements and properties of the form. For information on the array components and format, and more detailed explanations of the Form API workflow, see the @link http://api.drupal.org/api/file/developer/topics/forms_api_reference.html Forms API reference @endlink and the @link http://drupal.org/node/37775 Form API section of the handbook. @endlink
(I don't personally think that referring people to the quick start guide is useful -- and didn't that move out to the Handbook anyway?)
Comment #7
rfayHere's another round.
@jhodgdon: There was no reference to the tutorial/quickstart. Just to the form section of the handbook.
Comment #8
rfayNot sure how it got fixed so easily :-)
Comment #9
rfayThe statements about not touching $form_state['input'] are not correct... I ran into one use case the other day.
Comment #10
rfayMinor update to soften the statement about $form_state['input'].
Comment #12
jhodgdonThis is looking good! A few minor cleanup things, and I would mark it RTBC:
a) Pre-eminent means "superior" according to dictionary.com -- maybe we should just say primary? This is near the top.
b) When I tried the link to the form API reference, it worked, but redirected to another URL:
http://api.drupal.org/api/drupal/developer--topics--forms_api_reference....
So maybe we should put that URL in there? You never know if redirects are going to continue working forever.
c) I'm also not sure about the link to form_example_tutorial.inc -- I think it needs to be stand-alone rather than inside @link/@endlink in order to make a link to a non-URL. Did you test this with the API module? I'm not sure whether it would work this way or not. Could be fine...
d) "An associative array of values which were submitted to the form." which -> that, or omit the word entirely.
e) " their decisionmaking. " two words: decision making
f) See #817190: HTML formatting problems in forms API reference - found some formatting problems on the Form API reference while checking a link. Separate issue, just mentioning here...
g) "It is the element which caused submission," which -> that [note that the following line "which" is correct, though.]
h) "forces FAPI to turn on persistent storage for the $form."... I don't think the FAPI acronym was previously used/defined anywhere, so probably this should be written out as "forces the Form API to turn on...". Also, FAPI could also refer to field API, etc., so I would prefer to avoid using the acronym entirely.
i) "persistent, so are available in the validation, submission, and the form builder function (after first submission)."
I think I would either add 'the' before submission, or remove 'the' before form builder, for smoother flow.
Comment #13
jhodgdonHere's a new patch, with the doc cleanup described above.
Comment #14
rfayThanks, @jhodgdon.
@effulgentsia, could you RTBC this if you think it is?
Comment #15
effulgentsia CreditAttribution: effulgentsia commentedExcellent work and I like the initiative! This is some challenging stuff though (hence the need for this issue), so here's some feedback:
s/drupal_execute()/drupal_form_submit()/
No. drupal_get_form() takes $form_id plus extra args only. I'm not sure if the point of this paragraph is to explain the args of drupal_get_form(), or to explain the args of form builder and other form-related functions.
What exactly is this linking to? A file in the Examples module? How can that be conveyed in the @link structure?
- Can we make it clear here that forms should be prefixed by module name? For example, "mymodule_form" or "MODULE_form"? If we also want to make it clear that a module may implement multiple forms, then perhaps "MODULE_example_form".
- Can we change the submit button to have each property on its own line? I know sometimes we put short arrays on one line, but since this is being used as an example, let's stick to the canonical form.
- If you look at this patch in context, then the documentation in form.inc above where this patch starts instructs developers to use @ingroup and @see directives to link form builder, validation, and submission functions. Seems a shame to then not follow this in the first example. But, is it even possible to add mini-PHPDoc above each of these functions within the larger PHPDoc?
- Is it ok to introduce #ajax here like this without saying anything about it previously?
- Many of the $form_state keys are documented in the PHPDoc of drupal_build_form(), drupal_redirect_form(), and drupal_rebuild_form(). Do we want to mention that?
- "has enormous influence" is true, but do we want to get a little more precise here? In Drupal 6 we were pretty sloppy with what went into $form and what went into $form_state, but in Drupal 7, they're pretty clearly separated into $form (information about the form) and $form_state (information about the state of the form). Not sure yet how to explain that succinctly though, but understanding the distinction between the two would help developers tremendously. And if this is understood, then the statement "information about the state of the form influences its processing" seems too obvious to mention.
How about just linking to drupal_build_form() for this one, since that has an explanation for it?
I'm not sure how much of a convention this really is any more. For example, node editing forms persist information about the node being edited in $form_state['node']. I think the node form might be too complicated to use as an example here, but if we decide to, keep in mind that the details of $form_state['node'] are being changed in #735800: node form triggers form level submit functions on button level submits, without validation.
Not really internal (at least not yet). This is a tough key to explain though (see #689084: Document $form_state['cache']), and I don't like the explanation for it in drupal_build_form(). Here's a shot:
- 'cache': The typical form workflow involves two page requests. During the first page request, a form is built and returned for the user to fill in. Then the user fills the form in and submits it, triggering a second page request in which the form must be built and processed. By default, $form and $form_state are built from scratch during each of these page requests. In some special use-cases, it is necessary or desired to persist the $form and $form_state variables from the initial page request to the one that processes the submission. A form builder function can set 'cache' to TRUE to do this. One example where this is needed is to handle AJAX submissions, so ajax_process_form() sets this for all forms that include an element with a #ajax property. Note that the persistence of $form and $form_state across successive submissions of a multistep form happens automatically regardless of the value for 'cache'.
Not internal. How about this:
- 'input': The array of values as they were submitted by the user. These are raw and unvalidated, so should not be used without a thorough understanding of security implications. In almost all cases, code should use the data in the 'values' array exclusively. The most common use of this key is for multistep forms that need to clear some of the user input when setting 'rebuild'.
I don't think we need this. See my comments above for 'storage' and 'cache'.
Powered by Dreditor.
Comment #16
rfayThanks for the detailed review, effulgentsia - thanks especially for catching the mindless wandering about drupal_get_form().
Here's a patch that deals with most of those issues.
I think everything else is taken care of. Thanks for the excellent fixes.
Comment #17
jhodgdonTypo:
Other than that, I think it looks good.
Comment #18
jhodgdonOh. Also, as effulgentsia pointed out, $form_state doesn't get passed to form builder functions. So this seems to need revision:
One other thing mentioned in #15 that I don't think has been addressed:
Separate this array onto multiple lines, each property on one line, for readability.
Comment #19
jhodgdonScratch that first comment on #18.
Comment #20
rfayThanks, @jhodgdon. This should deal with those remaining two, and I caught another couple of questionable spellings.
Comment #21
jhodgdonLooks good!
Comment #22
Dries CreditAttribution: Dries commentedI think this looks great, but I have a couple of suggestions:
When I read 'interactive forms', I had to scratch my head. It became clear when reading 'programmatically'. Maybe instead of interactive, we should say 'forms presented and completed through a page'? Just a thought.
It seems valuable to mention that this is handy when you have multiple buttons on the form.
It would be good to say _why_ AJAX submission need to do this. Right now, the example doesn't really explain things.
These things aside, I want to re-iterate that this patch is a great improvement. :)
Comment #23
rfayThanks for the review, @Dries. I think this round addresses those three concerns.
Comment #24
jhodgdonI think Dries' comments have been addressed too...
Comment #25
Dries CreditAttribution: Dries commentedLooks great. Committed to CVS HEAD. Thanks.
Comment #26
effulgentsia CreditAttribution: effulgentsia commentedThanks! Minor follow-up.
Comment #27
rfayWhoops! Glad you caught the return $form; Additional information much appreciated as well.
Comment #28
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks.