Drupal 5: How to process multiple instances of the same form on the same page

Posted by: 
Dominique De Cooman

Given a page with multiple instances of the same form (which use the same form id), your form submit() function may not receive the anticipated set of form values for the form the user has submitted. The values you get may not be from the form attached to the submit button the user clicked, but values from a different form with different values which is using the same form id.

Example: Below is the situation i found myself in. Given three functions, the form() function to create the form data, the submit() function to process the form values from the user when they click submit in their browser, and a view() function which renders two instances of the same form on one page.

/**
 * The form creation function to create the form data needed
 * by drupal_get_form() to render a form.  The name of our
 * function is normally what we will use as our form id to
 * reference the form.
 */
function mymodule_thing_form($thing) {
 
    # create form and add widgets to
    # edit our thing
    $form = array();
    $form['thing']['name']  = ...;    
    $form['thing']['title'] = ...;
    ...
    return $form;
}
 
/**
 * Form submission function which Drupal looks for by
 * using the form id and adding _submit() to the end.
 * This is the function where our values will go when 
 * the user clicks the form submit button in their
 * browser.
 */
function mymodule_thing_form_submit($form_id, $form_values) {
 
    # save/update values in $form_values
    ...
}
 
/**
 * For whatever reason, we want to show two thing edit 
 * forms on the same page, a separate form instance 
 * for each to edit $thing1 and $thing2.
 * 
 * Drupal's drupal_get_form() will call our mymodule_thing_form()
 * function above to get the form data to render the form.
 */
function mymodule_view($thing1, $thing2) {
    $output  = drupal_get_form("mymodule_thing_form", $thing1);
    $output .= drupal_get_form("mymodule_thing_form", $thing2);
    return $output;
}

The problem is that when the user clicks for example, on the submit button representing values for thing2 because that’s what they want to update, the submit() function may actually receive values for thing1 instead ! I’m not sure if this is a browser issue, or some value caching issue in the Drupal form API, but the result is not what you would expect initially. The HTML that Drupal renders will contain two

<form>

HTML elements for thing1 and thing2 using
<form id="mymodule_thing_form">

as the id. The only way around this is to use different form ids.

But how do we do this ? It’s the drupal_get_form() function handles all this for us and creates the form ids from the function name we gave it. We would have to create two separate functions with different names returning the same form data structure just to get this to work. We would also have to duplicate our submit() functions too because they would now be called

mymodule_thing_form1_submit()

and
mymodule_thing_form2_submit()

in order for Drupal to get the form values to us. Only two duplicate functions… not a big deal ! But what if you wanted to display 10 of the same form, or 20 on the same page… or you just don’t know because the number fluctuates based on the content of the site. How do you go about using different form ids for the same form ?

This guy explains how to do it.

http://www.gtrlabs.org/blog/dayre/drupal_5_how_to_process_multiple_insta...

Add new comment