Drupal: How to Render Results of Form on Same Page as Form
Asked Answered
M

5

7

How would I print the results of a form submission on the same page as the form itself?

Relevant hook_menu:

    $items['admin/content/ncbi_subsites/paths'] = array(
        'title' => 'Paths',
        'description' => 'Paths for a particular subsite',
        'page callback' => 'ncbi_subsites_show_path_page',
        'access arguments' => array( 'administer site configuration' ),
        'type' => MENU_LOCAL_TASK,
    );

page callback:

function ncbi_subsites_show_path_page() {
  $f = drupal_get_form('_ncbi_subsites_show_paths_form');
  return $f;
}

Form building function:

   function _ncbi_subsites_show_paths_form() {
      // bunch of code here

      $form['subsite'] = array(
        '#title' => t('Subsites'),
        '#type' => 'select',
        '#description' => 'Choose a subsite to get its paths',
        '#default_value' => 'Choose a subsite',
        '#options'=> $tmp,
      );

      $form['showthem'] = array(
        '#type' => 'submit',
        '#value' => 'Show paths',
        '#submit' => array( 'ncbi_subsites_show_paths_submit'),    
      );

      return $form;
    }

Submit function (skipped validate function for brevity)

function ncbi_subsites_show_paths_submit( &$form, &$form_state ) {
  //dpm ( $form_state );
  $subsite_name = $form_state['values']['subsite'];
  $subsite = new Subsite( $subsite_name ); //y own class that I use internally in this module
  $paths = $subsite->normalized_paths;

  // build list
  $list = theme_item_list( $paths );
}

If I print that $list variable, it is exactly what I want, but I am not sure how to get it into the page with the original form page built from 'ncbi_subsites_show_path_page'. Any help is much appreciated!

Methylene answered 28/4, 2010 at 21:36 Comment(1)
robshouse.net/blog-post/…Isidora
C
7

The key information in the link Nikit posted is $form_state['rebuild']. Here's some info from Drupal 7 documentation that I believe applies the same for Drupal 6...

$form_state['rebuild']: Normally, after the entire form processing is completed and submit handlers ran, a form is considered to be done and drupal_redirect_form() will redirect the user to a new page using a GET request (so a browser refresh does not re-submit the form). However, if 'rebuild' has been set to TRUE, then a new copy of the form is immediately built and sent to the browser; instead of a redirect. This is used for multi-step forms, such as wizards and confirmation forms. Also, if a form validation handler has set 'rebuild' to TRUE and a validation error occurred, then the form is rebuilt prior to being returned, enabling form elements to be altered, as appropriate to the particular validation error.

Callisto answered 29/4, 2010 at 2:36 Comment(4)
Got it working, thanks to this tip. However,the only way I could "pass" data from the submit function to the function that renders the form is by setting global variables in the submit function, then rebuilding the form, and checking if those varaibles are set. Is there another way to do this? I don't like global variables.Methylene
Also in the example from that link, you can see $form_state['storage'] being used. I believe ['storage'] is a dedicated place where you can safely store data between validations, submits etc.Callisto
The problem is that I don't have access to $form_state from the page handler function. I'd like to store something in the storage array of $form_state, but I need that value in the page handler, not the form building function...Methylene
Drupal will pass in the $form_state variable to your form building function if you put it in the function definition -- it will never be passed to the page callback, as that is outside of form API's scope. Inside your form builder function you can switch based on the contents of form state and add extra elements of type 'markup' containing the results you want to display.Spanish
J
1

This is a full working example of a page and a list on the same page

<?php


/*
* Implements hook_mennu()
*/
function test_menu() {
  $items['test'] = array(
    'title'             => t('Test'),
    'page callback'     => 'test_search_page',
    'access callback'   => True,
  );

  return $items;
}


function test_search_page(){
    $form = drupal_get_form('test_search_form');

    return $form;
}


function test_search_form($form, &$form_state){
  $header = array(t('id'), t('name'), t('firstname'));
  $rows = Null;
  $form['name'] = array(
    '#type'             => 'textfield',
    '#title'            => t('Name'),
    '#required'         => True,
    '#default_value'    => isset($_GET['name']) ? $_GET['name'] : Null
  );

  $form['submit'] = array(
    '#type'           => 'submit',
    '#value'          => t('submit'),
  );



  if (isset($_GET['name'])){
    $rows = get_data();
  }
  $form['table'] = array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $rows,
    '#empty' => t('Aucun résultat.')
  );
  $form['pager'] = array('#markup' => theme('pager'));

  /*
  if (isset($form_state['table'])) {
    $form['table']  = $form_state['table'];
  }
  $form['pager'] = array('#markup' => theme('pager'));
  */
  return $form;
}

function test_search_form_submit($form, &$form_state){
   $form_state['redirect'] = array(
    // $path
    'test',
    // $options
    array('query' => array('name' => $form_state['values']['name'])),
    // $http_response_code
    302,
  );
}

//$header = array(t('id'), t('name'), t('firstname'));

function get_data(){
    $data =  array(
        0   => array(
            'id' => '0',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        1   => array(
            'id' => '1',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        2   => array(
            'id' => '2',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        3   => array(
            'id' => '3',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        4   => array(
            'id' => '4',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        5   => array(
            'id' => '5',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        6   => array(
            'id' => '6',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        7   => array(
            'id' => '7',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        8   => array(
            'id' => '8',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        9   => array(
            'id' => '9',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        10   => array(
            'id' => '10',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        ),
        11   => array(
            'id' => '11',
            'name'  => 'pokpokpok',
            'firstname' => 'pokpokpok',
        )
    );
    $paging = pager_array_splice($data, 2);

    return $paging;
}
/*
    $header = array(t('id'), t('name'), t('firstname'));

    $form_state['table'] = array(
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $paging,
      '#empty' => t('Aucun r?sultat.')
    );

    $form_state['rebuild'] = True;*/


function pager_array_splice($data, $limit = 9, $element = 0) {
  global $pager_page_array, $pager_total, $pager_total_items;
  $page = isset($_GET['page']) ? $_GET['page'] : '';

  // Convert comma-separated $page to an array, used by other functions.
  $pager_page_array = explode(',', $page);

  // We calculate the total of pages as ceil(items / limit).
  $pager_total_items[$element] = count($data);
  $pager_total[$element] = ceil($pager_total_items[$element] / $limit);
  $pager_page_array[$element] = max(0, min((int)$pager_page_array[$element], ((int)$pager_total[$element]) - 1));
  return array_slice($data, $pager_page_array[$element] * $limit, $limit, TRUE);
}
Jaenicke answered 25/2, 2015 at 10:10 Comment(0)
C
0

Drupal6 node.module and dblog.module do this for admin/content/node and admin/reports/dblog by providing a page callback which includes the rendered form in its output.

modules/dblog/dblog.admin.inc
dblog_overview()

modules/node/node.admin.inc
node_admin_nodes()

In form submit, updated filter settings are stored in $_SESSION.

In the page callback it renders the results based on the filter settings stored in $_SESSION.

$_SESSION is just another global here (albeit a persistent one).

Chery answered 29/12, 2010 at 21:47 Comment(0)
E
0

For Drupal7 I find that if you use $form_state['rebuild'], then the form variables can be best accessed from the PHP super-global variable $_POST (or $_REQUEST). However, if you use $form_state['redirect'], the solution with $_SESSION is better (instead of using $_GET or $_REQUEST).

I find this issue quite tricky even for experts. Maybe Drupal has some more easy and intuitive way that we don't know.

Estabrook answered 27/10, 2011 at 7:6 Comment(1)
Although how do I display these values on my page?Lemaceon
A
0

For Drupal 8, if you have a form implementing FormBase I found I needed to set the form to be rebuilt to allow using the form state during render of the form after a successful form submission:

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $form_state->setRebuild(TRUE);
  }

By default, the form will submit and process the form, then redirect, then build the form again and at that point you don't have the form state (unless you've passed the form state as part of a query parameter in the redirect).

Addendum answered 3/6, 2020 at 10:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.