【问题标题】:Drupal: How to Render Results of Form on Same Page as FormDrupal:如何在与表单相同的页面上呈现表单的结果
【发布时间】:2010-04-28 21:36:57
【问题描述】:

如何将表单提交的结果打印在与表单本身相同的页面上?

相关的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,
    );

页面回调:

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

表单构建功能:

   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;
    }

提交函数(为简洁起见跳过了验证函数)

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 );
}

如果我打印那个 $list 变量,这正是我想要的,但我不确定如何将它放入带有从“ncbi_subsites_show_path_page”构建的原始表单页面的页面中。非常感谢任何帮助!

【问题讨论】:

标签: php forms drupal drupal-6 drupal-fapi


【解决方案1】:

Nikit 发布的链接中的关键信息是 $form_state['rebuild']。以下是 Drupal 7 文档中的一些信息,我认为这些信息同样适用于 Drupal 6...

$form_state['rebuild']:通常,在整个 表格处理完成并且 提交处理程序运行,表单是 认为已经完成并且 drupal_redirect_form() 将重定向 用户使用 GET 访问新页面 请求(因此浏览器刷新不会 重新提交表格)。然而,如果 'rebuild' 已设置为 TRUE,然后 表格的新副本立即 构建并发送到浏览器;反而 的重定向。这用于 多步骤表单,例如向导和 确认表格。此外,如果一个表格 验证处理程序已设置“重建” 为 TRUE 和验证错误 发生,然后表格被重建 在被退回之前,启用表格 酌情更改的元素 到特定的验证错误。

【讨论】:

  • 得到它的工作,感谢这个提示。但是,我可以将数据从提交函数“传递”到呈现表单的函数的唯一方法是在提交函数中设置全局变量,然后重建表单,并检查是否设置了这些变量。还有另一种方法可以做到这一点吗?我不喜欢全局变量。
  • 在该链接的示例中,您可以看到正在使用 $form_state['storage']。我相信 ['storage'] 是一个专门的地方,您可以在其中安全地存储验证、提交等之间的数据。
  • 问题是我没有从页面处理函数访问 $form_state 的权限。我想在 $form_state 的存储数组中存储一些东西,但我需要页面处理程序中的值,而不是表单构建函数...
  • 如果你把 $form_state 变量放在函数定义中,Drupal 会将它传递给你的表单构建函数——它永远不会传递给页面回调,因为 that超出了表单 API 的范围。在表单构建器函数中,您可以根据表单状态的内容进行切换,并添加包含您要显示的结果的“标记”类型的额外元素。
【解决方案2】:

这是同一页面上的页面和列表的完整工作示例

<?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);
}

【讨论】:

    【解决方案3】:

    Drupal6 node.module 和 dblog.module 通过提供一个页面回调来为 admin/content/node 和 admin/reports/dblog 执行此操作,该回调在其输出中包含呈现的表单。

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

    在表单提交中,更新的过滤器设置存储在 $_SESSION 中。

    在页面回调中,它根据存储在 $_SESSION 中的过滤器设置呈现结果。

    $_SESSION 在这里只是另一个全局变量(尽管是一个持久变量)。

    【讨论】:

      【解决方案4】:

      对于 Drupal7,我发现如果你使用 $form_state['rebuild'],那么最好从 PHP 超级全局变量 $_POST(或 $_REQUEST)访问表单变量。但是,如果您使用$form_state['redirect'],则使用$_SESSION 的解决方案会更好(而不是使用$_GET$_REQUEST)。

      我发现这个问题即使对于专家来说也很棘手。也许 Drupal 有一些我们不知道的更简单直观的方法。

      【讨论】:

      • 虽然我如何在我的页面上显示这些值?
      【解决方案5】:

      对于 Drupal 8,如果您有一个实现 FormBase 的表单,我发现我需要设置要重建的表单,以允许在表单提交成功后在表单呈现期间使用表单状态:

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

      默认情况下,表单将提交并处理表单,然后重定向,然后再次构建表单,此时您没有表单状态(除非您已将表单状态作为查询参数的一部分传递在重定向中)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-18
        • 2014-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多