Index: forms_api.html
===================================================================
RCS file: /cvs/drupal-contrib/contributions/docs/developer/topics/forms_api.html,v
retrieving revision 1.9
diff -u -p -r1.9 forms_api.html
--- forms_api.html	28 Apr 2006 03:08:02 -0000	1.9
+++ forms_api.html	21 Feb 2007 02:40:29 -0000
@@ -49,7 +49,7 @@
 <p>Let's take a look at a working piece of code using the API:</p>
 <div class="codeblock">
 			<p><code><font color="#000000"> <font color="#0000BB">&lt;?php<br />
-              </font><font color="#007700">function </font><font color="#0000BB">test_page</font><font color="#007700">() {<br />
+              </font><font color="#007700">function </font><font color="#0000BB">test_form</font><font color="#007700">() {<br />
 &nbsp;&nbsp;</font><font color="#FF8000">// Access log settings:<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$options </font><font color="#007700">= array(</font><font color="#DD0000">'1' </font><font color="#007700">=&gt; </font><font color="#0000BB">t</font><font color="#007700">(</font><font color="#DD0000">'Enabled'</font><font color="#007700">), </font><font color="#DD0000">'0' </font><font color="#007700">=&gt; </font><font color="#0000BB">t</font><font color="#007700">(</font><font color="#DD0000">'Disabled'</font><font color="#007700">));<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'access'</font><font color="#007700">] = array(</font><font color="#DD0000"><br />
@@ -101,19 +101,26 @@
 &nbsp;&nbsp;);<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'hidden'</font><font color="#007700">] = array(</font><font color="#DD0000">'#type' </font><font color="#007700">=&gt; </font><font color="#DD0000">'value'</font><font color="#007700">, </font><font color="#DD0000">'#value' </font><font color="#007700">=&gt; </font><font color="#DD0000">'is_it_here'</font><font color="#007700">);<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'submit'</font><font color="#007700">] = array(</font><font color="#DD0000">'#type' </font><font color="#007700">=&gt; </font><font color="#DD0000">'submit'</font><font color="#007700">, </font><font color="#DD0000">'#value' </font><font color="#007700">=&gt; </font><font color="#0000BB">t</font><font color="#007700">(</font><font color="#DD0000">'Save'</font><font color="#007700">));<br />
-&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">= </font><font color="#0000BB">drupal_get_form</font><font color="#007700">(</font><font color="#DD0000">'test_page'</font><font color="#007700">, </font><font color="#0000BB">$form</font><font color="#007700">);<br />
-&nbsp;&nbsp;return </font><font color="#0000BB">$output</font><font color="#007700">;<br />
+&nbsp;&nbsp;return </font><font color="#0000BB">$form</font><font color="#007700">;<br />
+      }<br />
+<br />
+<font color="#007700">function </font><font color="#0000BB">test_page</font><font color="#007700">() {<br />
+&nbsp;&nbsp;return </font><font color="#0000BB">drupal_get_form</font><font color="#007700">(</font><font color="#DD0000">'test_form'</font><font color="#007700">)</font><font color="#007700">;<br />
       }<br />
-						    
+
 </font><font color="#0000BB">?&gt;</font> </font></code></p>
 </div>
-<p>This example demonstrates how form elements can be built in a hierarchical fashion by expanding and layering the form array.</p>
+<p>This example demonstrates how form elements can be built in a hierarchical fashion by expanding and layering the form array.  There are two functions involved - the function that builds the form, and another that displays the form using <code>drupal_get_form()</code>.</p>
 <p>Notice that the first layer is made up of two form groups, 'access', and 'details', and that inside each of these groups, one layer down, are some individual form elements. Order of construction is important here, as the form building code will default to the constructed order of the <code>$form</code> array when it builds the form (this can be overridden, and will be discussed later in the custom theming section). </p>
 <p>For form groups, the <code>&#039;#type&#039;</code> parameter is set to <code>&#039;fieldset&#039;</code>, and notice how the <code>&#039;details&#039;</code> form group is made into a collapsed form group with the addition of a few attributes.</p>
-<p>Once all groups/elements have been built into the master <code>$form</code> array, it's passed to <code>drupal_get_form</code>. <code>drupal_get_form</code> takes three args: the first is a string representing the name of the form itself (called the form ID, which is usually just the name of the function), the second is the form array to render, and the third is an optional callback argument (which will be discussed later). </p>
-<p>The <code>drupal_get_form</code> function is the &quot;key&quot; function in the Forms API. It does the following:</p>
+<p>All groups/elements are been built into the master <code>$form</code> array by the builder function.</p>
+<p>The <code>drupal_get_form</code> function is the &quot;key&quot; function in the Forms API. Note that in its basic usage, it takes just one argument, a string which
+is both the form ID and also the name of the function that builds the <code>$form</code> array. <code>drupal_get_form</code> can take optional additional arguments, which will be simply passed on to the <code>$form</code> builder function.</p>
+
+
+<code>drupal_get_form</code> does the following:</p>
 <ul>
-  <li>Starts the entire form-building process</li>
+  <li>Starts the entire form-building process by getting the  <code>$form</code> from the builder function</li>
   <li>Translates the <code>$form['name']</code> items into actual form elements</li>
   <li>Performs any validation and &quot;clean-up&quot; that needs to be done, and calls custom validation functions if declared</li>
   <li>Submits the form if a submit function is declared, and the form has been submitted</li>
@@ -153,15 +160,15 @@
     <p>example:</p>
     <p>For our above form, we could create a custom theming function as follows:</p>
     <div class="codeblock"><code><font color="#000000"> <font color="#0000BB">&lt;?php<br />
-      </font><font color="#007700">function </font><font color="#0000BB">theme_test_page</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">) {<br />
+      </font><font color="#007700">function </font><font color="#0000BB">theme_test_form</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">) {<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">= </font><font color="#DD0000">''</font><font color="#007700">;<br />
-&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">form_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'name'</font><font color="#007700">]);<br />
+&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">drupal_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'name'</font><font color="#007700">]);<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#DD0000">'&lt;div class=&quot;foo&quot;&gt;'</font><font color="#007700">;<br />
-&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">form_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'access'</font><font color="#007700">]);<br />
+&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">drupal_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'access'</font><font color="#007700">]);<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#DD0000">'&lt;div class=&quot;bar&quot;&gt;'</font><font color="#007700">;<br />
-&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">form_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'details'</font><font color="#007700">]);<br />
+&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">drupal_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">[</font><font color="#DD0000">'details'</font><font color="#007700">]);<br />
 &nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#DD0000">'&lt;/div&gt;&lt;/div&gt;'</font><font color="#007700">;<br />
-&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">form_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">);<br />
+&nbsp;&nbsp;</font><font color="#0000BB">$output </font><font color="#007700">.= </font><font color="#0000BB">drupal_render</font><font color="#007700">(</font><font color="#0000BB">$form</font><font color="#007700">);<br />
 &nbsp;&nbsp;return </font><font color="#0000BB">$output</font><font color="#007700">;<br />
       }<br />
     </font><font color="#0000BB">?&gt;</font> </font> </code></div>
@@ -169,10 +176,10 @@
     <ol>
       <li>The theme function has one argument, which is the form array that it will theme</li>
       <li>You build and return an output string just as you would do in a regular theming function</li>
-      <li>Form elements are rendered using the <code>form_render</code> function</li>
-      <li>If you call <code>form_render</code> and pass it an array of elements (as in a fieldset), it will render all the elements in the passed array, in the order in which they were built in the form array.</li>
-      <li>While the default order of rendering for a form is the order in which it was built, you can override that in the theme function by calling <code>form_render</code> for any element in the place where you would like it to be rendered. In the above example, this was done with <code>$form[&#039;name&#039;]</code>.</li>
-      <li>The rendering code keeps track of which elements have been rendered, and will only allow them to be rendered once. Notice that <code>form_render</code> is called for the entire form array at the very end of the theming function, but it will only render the remaining unrendered element, which in this case is the submit button. calling <code>form_render($form)</code> is a common way to end a theming function, as it will then render any submit buttons and/or hidden fields that have been declared in the form in a single call.</li>
+      <li>Form elements are rendered using the <code>drupal_render</code> function</li>
+      <li>If you call <code>drupal_render</code> and pass it an array of elements (as in a fieldset), it will render all the elements in the passed array, in the order in which they were built in the form array.</li>
+      <li>While the default order of rendering for a form is the order in which it was built, you can override that in the theme function by calling <code>drupal_render</code> for any element in the place where you would like it to be rendered. In the above example, this was done with <code>$form[&#039;name&#039;]</code>.</li>
+      <li>The rendering code keeps track of which elements have been rendered, and will only allow them to be rendered once. Notice that <code>drupal_render</code> is called for the entire form array at the very end of the theming function, but it will only render the remaining unrendered element, which in this case is the submit button. calling <code>drupal_render($form)</code> is a common way to end a theming function, as it will then render any submit buttons and/or hidden fields that have been declared in the form in a single call.</li>
     </ol>
   </li>
 </ol>
@@ -181,7 +188,7 @@
 <p>The form API has general form validation which it performs on all submitted forms. If there is additional validation you wish to perform on a submitted form, you can create a validation function. the name of the validation function is the form ID with <em>_validate</em> appended to it. the function has two args: <code>$form_id</code> and <code>$form_values</code>. <code>$form_id</code> is the form ID of the passed form, and <code>$form_values</code> are the form values which you may perform validation on.</p>
 <p>Here's an example validation function for our example code:</p>
 <div class="codeblock"><code><font color="#000000"> <font color="#0000BB">&lt;?php<br />
-  </font><font color="#007700">function </font><font color="#0000BB">test_page_validate</font><font color="#007700">(</font><font color="#0000BB">$form_id</font><font color="#007700">, </font><font color="#0000BB">$form_values</font><font color="#007700">) {<br />
+  </font><font color="#007700">function </font><font color="#0000BB">test_form_validate</font><font color="#007700">(</font><font color="#0000BB">$form_id</font><font color="#007700">, </font><font color="#0000BB">$form_values</font><font color="#007700">) {<br />
 &nbsp;&nbsp;if (</font><font color="#0000BB">$form_values</font><font color="#007700">[</font><font color="#DD0000">'name'</font><font color="#007700">] == </font><font color="#DD0000">''</font><font color="#007700">) {<br />
 &nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#0000BB">form_set_error</font><font color="#007700">(</font><font color="#DD0000">''</font><font color="#007700">, </font><font color="#0000BB">t</font><font color="#007700">(</font><font color="#DD0000">'You must select a name for this group of settings.'</font><font color="#007700">));<br />
 &nbsp;&nbsp;}<br />
@@ -191,7 +198,7 @@
 <p>The preferred method of submitting forms with the API is through the use of a form submit function. This has the same naming convention and arguments as the validation function, except <em>_submit</em> is appended instead. Any forms which are submitted from a button of <code>type =&gt; &#039;submit&#039;</code> will be passed to their corresponding submit function if it is available. This method is more secure than grabbing <code>$_POST[&#039;edit&#039;]</code> and using a switch statement. </p>
 <p>example:</p>
 <div class="codeblock"><code><font color="#000000"> <font color="#0000BB">&lt;?php<br />
-  </font><font color="#007700">function </font><font color="#0000BB">test_page_submit</font><font color="#007700">(</font><font color="#0000BB">$form_id</font><font color="#007700">, </font><font color="#0000BB">$form_values</font><font color="#007700">) {<br />
+  </font><font color="#007700">function </font><font color="#0000BB">test_form_submit</font><font color="#007700">(</font><font color="#0000BB">$form_id</font><font color="#007700">, </font><font color="#0000BB">$form_values</font><font color="#007700">) {<br />
 &nbsp;&nbsp;</font><font color="#0000BB">db_query</font><font color="#007700">(</font><font color="#DD0000">&quot;INSERT INTO {table} (name, log, hidden) VALUES ('%s', %d, '%s')&quot;</font><font color="#007700">, </font><font color="#0000BB">$form_values</font><font color="#007700">[</font><font color="#DD0000">'name'</font><font color="#007700">], </font><font color="#0000BB">$form_values</font><font color="#007700">[</font><font color="#DD0000">'access'</font><font color="#007700">][</font><font color="#DD0000">'log'</font><font color="#007700">],&nbsp;&nbsp;</font><font color="#0000BB">$form_values</font><font color="#007700">[</font><font color="#DD0000">'hidden'</font><font color="#007700">]);<br />
 &nbsp;&nbsp;</font><font color="#0000BB">drupal_set_message</font><font color="#007700">(</font><font color="#0000BB">t</font><font color="#007700">(</font><font color="#DD0000">'Your form has been saved.'</font><font color="#007700">));<br />
 }<br/></font><font color="#0000BB">?&gt;</font> </font> </code></div>
@@ -211,11 +218,8 @@
   </li>
 </ol>
 
-<h2>Returning Forms</h2>
-<p>Generally speaking, you will return a form with the <code>drupal_get_form</code> function. </p>
-<p>In some cases, code may be written in such a way that form elements themselves (and not a fully themed form) need to be returned to a calling function. This is the case with many Drupal core hooks. in this case, simply return the constructed <code>$form</code> array, and let the calling code handle the form rendering.</p>
 <h2>Understanding the Flow</h2>
-<p>A difficult concept with Forms API compared to the previous Drupal method of doing things is that the <code><font color="#0000BB">drupal_get_form()</font></code> function handles both presenting and responding to the form. What this means is that the $form array you construct in your function will be built first when the form is presented, and again when the form is submitted. In the previous Drupal forms API, the check for 'submit' was done before calling any of the form_* functions, because those directly created the output.</p>
+<p>A difficult concept with Forms API compared to the previous (Drupal 4.6) method of doing things is that the <code><font color="#0000BB">drupal_get_form()</font></code> function handles both presenting and responding to the form. What this means is that the $form array you construct in your function will be built first when the form is presented, and again when the form is submitted. In the previous Drupal forms API, the check for 'submit' was done before calling any of the form_* functions, because those directly created the output.</p>
 <p>The practical upshot to this is that many developers immediately find themselves asking the question of <em>"where does my data get stored?"</em>. The answer is simply that it doesn't. You put your $form data together, perhaps loading your object from the database and filling in #default_values, the form builder then checks this against what was posted. What you gain from this, however, is that the FormsAPI can deal with your data securely. Faking a POST is much harder since it won't let values that weren't actually on the form come through to the $form_values in your submit function, and in your 'select' types, it will check to ensure that the value actually existed in the select and reject the form if it was not. 
 </body>
 </html>
