7

Is it possible to put multiple forms on a single page?

I am trying to make a coupon offer page. I wanted to have two forms for two different offers on each side of a page. Each form has a text field for the coupon code and its own submit button. The first form works okay; however the second form's hidden values seem to be overridden by the first form's.

I'm using hook_alter to alter the second form to make it different, but it still has the same form_id as the first. Is this what's causing my problems, or do I need to look/think somewhere else?

The two forms have the same values for "form_id" and "form_token," but different values for "form_build_id."

2 Answers 2

8

If you want to add the same form multiple times, you need to implement hook_forms(). See node_forms() for an example.

This allows to use different form_id's, which all point to the same form builder function. For example, you can use yourmodule_some_form_$i and then use hook_forms() to point these to yourmodule_some_form.

See http://www.mohitsharma.net/content/how-show-same-form-multiple-time-page for an example

5
  • 1
    The OP is talking of using two forms on the same page; using hook_forms() doesn't automatically solve this. If you simple use the same form twice on the same page, you still have the problem of having the same form field repeated twice.
    – avpaderno
    Commented Jul 1, 2011 at 11:24
  • Not sure if I follow you. Not sure about 6.x right now, but at leat Drupal 7 makes sure that that there are no duplicate id's, so there shouldn't be a problem when having the same form fields multiple times on the same page?
    – Berdir
    Commented Jul 1, 2011 at 12:31
  • hook_forms() is not used to have two forms with the same form fields in the same page; it is used to allow to have a single form builder for different form IDs.
    – avpaderno
    Commented Jul 1, 2011 at 12:46
  • You can use hook_forms() for exactly this. See for example mohitsharma.net/content/how-show-same-form-multiple-time-page
    – Berdir
    Commented Jul 1, 2011 at 13:21
  • The example given in that article is not practical; the form doesn't even have a submission button, and for such form I would not use hook_forms(). The OP is then altering one of the two forms.
    – avpaderno
    Commented Jul 1, 2011 at 13:45
-1

You can have more than one form in the same page; see what done by node_admin_content(), which uses the following code:

function node_admin_content($form_state) {
  if (isset($form_state['values']['operation']) && $form_state['values']['operation'] == 'delete') {
    return node_multiple_delete_confirm($form_state, array_filter($form_state['values']['nodes']));
  }
  $form = node_filter_form();

  $form['#theme'] = 'node_filter_form';
  $form['admin']  = node_admin_nodes();

  return $form;
}

Leaving out the first IF-statement, the function is adding two different forms that have their own submission handlers.

The problem is with the form fields that are repeated twice. The following array structure would create problems when the form array is flattened, as there would be two "coupon" fields.

$form['first form']['coupon'] = array(
  '#type' => 'textfield', 
  '#title' => t('Coupon'), 
  '#default_value' => variable_get('mymodule_coupon'), 
  '#size' => 60, 
  '#maxlength' => 128, 
  '#required' => TRUE,
);

$form['second form']['coupon'] = array(
  '#type' => 'textfield', 
  '#title' => t('Coupon'), 
  '#default_value' => variable_get('mymodule_coupon'), 
  '#size' => 60, 
  '#maxlength' => 128, 
  '#required' => TRUE,
);

Without to see the code being used, I could think that using a page callback that calls drupal_get_form() is probably the easier way, in your case.

$output = drupal_get_form("form identifier") . drupal_get_form("form identifier");

I tried using the following code in Drupal 6.

module_load_include('inc', 'path', 'path.admin');
$output = drupal_get_form('path_admin_form') . drupal_get_form('path_admin_form');

The content of $output for the two form was the following one (I removed the output for the single form fields).

<form action="/dr61/devel/php"  accept-charset="UTF-8" method="post" id="path-admin-form-1">
<div><div class="form-item" id="edit-language-1-wrapper">

<input type="submit" name="op" id="edit-submit" value="Create new alias"  class="form-submit" />
<input type="hidden" name="form_build_id" id="form-4eb9304baac34f292901ca23d925ff03" value="form-4eb9304baac34f292901ca23d925ff03"  />
<input type="hidden" name="form_token" id="edit-path-admin-form-form-token" value="cd429a06b84e381eb82ef04cd5033eeb"  />
<input type="hidden" name="form_id" id="edit-path-admin-form" value="path_admin_form"  />
<form action="/dr61/devel/php"  accept-charset="UTF-8" method="post" id="path-admin-form-1">
<div><div class="form-item" id="edit-language-1-wrapper">

<input type="submit" name="op" id="edit-submit-1" value="Create new alias"  class="form-submit" />
<input type="hidden" name="form_build_id" id="form-fb363c7ca6d88f71d98e86f8a69b0379" value="form-fb363c7ca6d88f71d98e86f8a69b0379"  />
<input type="hidden" name="form_token" id="edit-path-admin-form-form-token-1" value="cd429a06b84e381eb82ef04cd5033eeb"  />
<input type="hidden" name="form_id" id="edit-path-admin-form-1" value="path_admin_form"  />

There is not a conflict between the HTML ID assigned to the same form field, and the value for "form_build_id" (or "form_token") is different in the two forms.

The implementation of hook_form_alter() used to alter the form should be able to understand in which case to alter the form, or both the forms would show the same fields.

From the point of view of the user experience, I am not sure that showing two different forms with their own submission buttons is the best way to do what you are trying to achieve.
I would think that using a form that shows different fields basing on the values set for other fields would be better. For example, the form could have a selector for the type of the coupon, and would shown different form fields basing on the coupon type selected.

1
  • It's not that simple when you want to re-use the same form.
    – Berdir
    Commented Jul 1, 2011 at 10:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.