by Jeff EatonNovember 22, 2006

Drupal 5: Making forms that display their own results

Drupal's Form API offers advanced features for validation, processing, and (in version 5) multi-part forms that span several pages. Sometimes, though, you need to do something simple: write a form that does nothing but display some formatted information based on the data that was submitted.

Here's a short snippet of code that demonstrates how Drupal 5's new #multistep flag (used for complex, multi-page forms) can also simplify the little problems.

function multistep_example_form($form_values = NULL) {
  $form = array();
  // Setting #multistep to true activates some special form
  // handling code for Drupal. First, the FormAPI makes sure
  // that the results of the form's submission are passed back
  // into the builder function when the page loads for the second
  // time. That gives it a chance to build a different version of
  // the form (with additional options, for example). It also
  // does magickal voodoo that keeps validation working properly
  // in those complex multi-page forms. For now, we won't
  // worry about that.
  $form['#multistep'] = TRUE;
  // Setting #redirect to false means that Drupal *won't* attempt
  // to reload a clean copy of the form (by redirecting to the
  // current page, and reloading) when it's submitted. In a multistep
  // form, we want to keep the data around so it can be displayed,
  // or passed on to a subsequent step.
  $form['#redirect'] = FALSE;
  // Remember: in a #multistep form, Drupal makes sure that the
  // $form_values array is passed into this builder function once
  // you submit the form. That gives us a chance to display different
  // form fields based on what was previously submitted.
  if ($form_values === NULL) {
    // We're entering the form for the first time. Display the form!
    $form['text'] = array(
      '#type' => 'textfield',
      '#title' => t('Text field'),
      '#required' => TRUE,
    $form['more_text'] = array(
      '#type' => 'textarea',
      '#title' => t('A bigger text field'),
    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Submit'),
  else {
    // $form_values is populated, which means we're coming in a second
    // time. Let's display the results instead of the original form fields.
    $form['results'] = array(
      '#type' => 'item',
      '#title' => t('The results of your form submission'),
      '#value' => _multistep_example_format_values($form_values),
  return $form;
function _multistep_example_format_values($form_values = array()) {
  $header = array(t('Key'), t('Value'));
  $rows = array();
  foreach ($form_values as $key => $value) {
    $row = array();
    $row[] = $key;
    $row[] = check_plain($value);
    $rows[] = $row;
  return theme('table', $header, $rows);

That's all there is to it! Obviously, most modules will need to do some more complex formatting than that when they display their results. But the skeleton is there, and should serve you well.