2011-03-01 53 views
11

Drupal 7動態選擇列表的最佳做法是什麼?Drupal 7:Drupal 7動態選擇列表的最佳實踐

a)創建通過用戶界面虛擬選項場及hook_form_FORM_ID_alter

B)通過與hook_form

自定義模塊從頭開始創建一個動態的選擇列表重寫選項或

c)不同的方法?

感謝

+0

我更新我的回答有一個例子Drupal 7 – wildpeaks 2011-03-02 10:20:17

回答

21

你可以使用表格API的#ajax(它曾經被稱爲Drupal6 #ahah)來做到這一點。

這裏是爲Drupal 7(基於Examples for Developers),其示出了兩個下拉菜單,其中所述第一下拉修改的第二下拉選項列表的示例:

文件的源mymodule.module

<?php 

/** 
* Implementation of hook_menu(). 
* Registers a form-based page that you can access at "http://localhost/mypage" 
*/ 
function mymodule_menu(){ 
    return array(
     'mypage' => array(
      'title' => 'A page to test ajax', 
      'page callback' => 'drupal_get_form', 
      'page arguments' => array('mymodule_page'), 
      'access arguments' => array('access content'), 
     ) 
    ); 
} 



/** 
* A form with a dropdown whose options are dependent on a 
* choice made in a previous dropdown. 
* 
* On changing the first dropdown, the options in the second are updated. 
*/ 
function mymodule_page($form, &$form_state) { 
    // Get the list of options to populate the first dropdown. 
    $options_first = mymodule_first_dropdown_options(); 

    // If we have a value for the first dropdown from $form_state['values'] we use 
    // this both as the default value for the first dropdown and also as a 
    // parameter to pass to the function that retrieves the options for the 
    // second dropdown. 
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first); 

    $form['dropdown_first'] = array(
     '#type' => 'select', 
     '#title' => 'First Dropdown', 
     '#options' => $options_first, 
     '#default_value' => $value_dropdown_first, 

     // Bind an ajax callback to the change event (which is the default for the 
     // select form type) of the first dropdown. It will replace the second 
     // dropdown when rebuilt 
     '#ajax' => array(
      // When 'event' occurs, Drupal will perform an ajax request in the 
      // background. Usually the default value is sufficient (eg. change for 
      // select elements), but valid values include any jQuery event, 
      // most notably 'mousedown', 'blur', and 'submit'. 
      'event' => 'change', 
      'callback' => 'mymodule_ajax_callback', 
      'wrapper' => 'dropdown_second_replace', 
     ), 
    ); 
    $form['dropdown_second'] = array(
     '#type' => 'select', 
     '#title' => 'Second Dropdown', 
     // The entire enclosing div created here gets replaced when dropdown_first 
     // is changed. 
     '#prefix' => '<div id="dropdown_second_replace">', 
     '#suffix' => '</div>', 
     // when the form is rebuilt during ajax processing, the $value_dropdown_first variable 
     // will now have the new value and so the options will change 
     '#options' => mymodule_second_dropdown_options($value_dropdown_first), 
     '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '', 
    ); 
    return $form; 
} 

/** 
* Selects just the second dropdown to be returned for re-rendering 
* 
* Since the controlling logic for populating the form is in the form builder 
* function, all we do here is select the element and return it to be updated. 
* 
* @return renderable array (the second dropdown) 
*/ 
function mymodule_ajax_callback($form, $form_state) { 
    return $form['dropdown_second']; 
} 


/** 
* Helper function to populate the first dropdown. This would normally be 
* pulling data from the database. 
* 
* @return array of options 
*/ 
function mymodule_first_dropdown_options() { 
    return array(
     'colors' => 'Names of colors', 
     'cities' => 'Names of cities', 
     'animals' => 'Names of animals', 
    ); 
} 


/** 
* Helper function to populate the second dropdown. This would normally be 
* pulling data from the database. 
* 
* @param key. This will determine which set of options is returned. 
* 
* @return array of options 
*/ 
function mymodule_second_dropdown_options($key = '') { 
    $options = array(
     'colors' => array(
      'red' => 'Red', 
      'green' => 'Green', 
      'blue' => 'Blue' 
     ), 
     'cities' => array(
      'paris' => 'Paris, France', 
      'tokyo' => 'Tokyo, Japan', 
      'newyork' => 'New York, US' 
     ), 
     'animals' => array(
      'dog' => 'Dog', 
      'cat' => 'Cat', 
      'bird' => 'Bird' 
     ), 
    ); 
    if (isset($options[$key])) { 
     return $options[$key]; 
    } 
    else { 
     return array(); 
    } 
} 
+0

我已經使用上面的代碼。但我無法獲得選定的值。一旦我改變dropdown_one,dropdown_second不會顯示。我在你的代碼中做了一個改變。我使用了hook_form_form_id_alter鉤子而不是hook_page()。我提出了一個問題。你能檢查並幫我解決這個問題嗎? http://stackoverflow.com/questions/23496574/drupal-dynamic-select-list-not-reterving-values-in-subcategory-field – Ananth 2014-05-06 14:10:13

0

從wildpeaks答案回調應該是:

function mymodule_ajax_callback($form, $form_state) { 
    return render($form['dropdown_second']); 
}