2014-03-12 103 views
1

使用D7表單API,我需要創建一個層次集合的過濾器,每個過濾器都具有先前過濾器的依賴關係。當在其中一個過濾器上進行選擇時,該行下的所有過濾器將根據鏈上的選擇自動更新。看起來不錯,但還有一點點。Drupal 7表單API - 自定義自動填充過濾器

舉一個例子,假設我有一個數據庫,其中包含我想要顯示的+ 75k產品記錄。

  • 過濾器1 - 布蘭德(10K可能的選擇)
  • 過濾器2 - 產品(20K可能的選擇)
  • 過濾器3 - 名稱(75K可能的選擇)

很顯然,我不能在每個select-multi中顯示所有選項,因此以下是我設想的工作方式:

  1. 頁面加載,所有過濾器都爲空
  2. 每個過濾器上方都有一個小文本輸入。鍵入該字段自動完成,但結果被轉儲到select-multi輸入。
  3. 用戶從剛剛填充的列表中選擇一個選項。
  4. 所有過濾器都會自動填充,並通過鏈上的選擇進行細化。

我一直在尋找D7形式的API,我找不到任何提及這種功能。我知道#ajax和#state回調,但文本輸入自動完成在鏈中填充select-multi和triggering事件有點模糊。

如果有幫助,我已經使用jQuery構建了這個完整的功能。我現在的目標是使用適當的表單API將其移植到Drupal。

回答

0

創建一個論壇功能可以說my_module_filters_form比使用hook_menu每一個變化是在HTML表單提出做一個AJAX調用該回調,並替換爲您的HTML輸出時間

function my_module_menu() { 
    $items['my_module/ccallback' = array(
    // missing a menu item type (forgot the syntax) 
    'callback function' => 'drupal_get_form', 
    'callbsck arguments' => array('my_module_filters_form'), 
    'access callback' => TRUE 
); 
} 

添加菜單回調。

1

我知道它已經很長時間了,但仍然會爲了其他人尋找解決方案而分享。您將必須根據需要實現您自己的每種自動完成功能。需要注意的是使用前一個過濾器的值設置的autocomplete_path。休息應該是自我解釋。

// hook_menu would look something like this 
function hook_menu() { 
    $menu = array(); 
    $menu['hierarchical_filter'] = array(
    'title' => 'Autocomplete Ajax Cascading Form', 
    'page callback' => 'drupal_get_form', 
    'page arguments' => array('hierarchical_filter_form'), 
    'access callback' => TRUE, 
); 
    $menu['country_list'] = array(
    'title' => 'Country List autocomplete', 
    'page callback' => 'country_list_autocomplete', 
    'access callback' => TRUE, 
    'type' => MENU_CALLBACK, 
); 
    $menu['state_list'] = array(
    'title' => 'State List autocomplete', 
    'page callback' => 'state_list_autocomplete', 
    'access callback' => TRUE, 
    'type' => MENU_CALLBACK, 
); 
    $menu['city_list'] = array(
    'title' => 'City List autocomplete', 
    'page callback' => 'city_list_autocomplete', 
    'access callback' => TRUE, 
    'type' => MENU_CALLBACK, 
); 
    return $menu; 
} 
function country_list_autocomplete($string='') { 
    $values = array('United States' => 'United States', 'South Africa' => 'South Africa', 'Russian Federation' => 'Russian Federation', 'Singapore' => 'Singapore', 'China' => 'China'); 
    $matches = array_filter($values, function($item) use($string) { 
    if(stripos($item, $string) !== FALSE) return TRUE; 
    return FALSE; 
    }); 
    drupal_json_output($matches); 
} 
function state_list_autocomplete($country_code, $state='') { 
    $values = array('South Africa' => array('Mpumalanga' => 'Mpumalanga', 'Gauteng' => 'Gauteng', 'Limpopo' => 'Limpopo', 'Northern Cape' => 'Northern Cape'), 
    'United States' => array('Alabama'=>'Alabama', 'Arizona'=>'Arizona')); 
    $matches = array_filter($values[$country_code], function($item) use($state) { 
    if(stripos($item, $state) !== FALSE) return TRUE; 
    return FALSE; 
    }); 
    drupal_json_output($matches); 
} 
function city_list_autocomplete($state, $city='') { 
    $values = array('northern cape' => array('Barkly West' => 'Barkly West', 'Campbell' => 'Campbell', 'Delportshoop' => 'Delportshoop'), 
    'Alabama' => array('Butler'=>'Butler', 'Calera'=>'Calera', 'Helena'=>'Helena')); 
    $matches = array_filter($values[$state], function($item) use($city) { 
    if(stripos($item, $city) !== FALSE) return TRUE; 
    return FALSE; 
    }); 
    drupal_json_output($matches); 
} 
function hierarchical_filter_form($form, &$form_state) { 
    $form = array(); 
    $form['country_list'] = array(
    '#type' => 'textfield', 
    '#title' => 'Choose Country', 
    '#autocomplete_path' => 'country_list', 
    '#ajax' => array(
     'callback' => 'country_callback', 
     'wrapper' => 'states_wrapper', 
    ), 
); 
    $form['state_list'] = array(
    '#type' => 'textfield', 
    '#title' => 'Choose State', 
    '#prefix' => '<div id="states_wrapper">', 
    '#suffix' => '</div>', 
); 
    if(isset($form_state['values']['country_list'])) { 
    $form['state_list']['#autocomplete_path'] = 'state_list/'.$form_state['values']['country_list']; 
    $form['state_list']['#ajax'] = array(
     'callback' => 'state_callback', 
     'wrapper' => 'city_wrapper', 
    ); 
    } 
    $form['city_list'] = array(
    '#type' => 'textfield', 
    '#title' => 'Choose City', 
    '#prefix' => '<div id="city_wrapper">', 
    '#suffix' => '</div>', 
); 
    if(isset($form_state['values']['state_list'])) { 
    $form['city_list']['#autocomplete_path'] = 'city_list/'.$form_state['values']['state_list']; 
    } 
    return $form; 
} 
function country_callback($form, &$form_state) { 
    $commands = array(); 
    // On changing country, make sure state and city fields are reset 
    $form['state_list']['#value'] = ''; 
    $form['city_list']['#value'] = ''; 
    $commands[] = ajax_command_replace('#states_wrapper', drupal_render($form['state_list'])); 
    $commands[] = ajax_command_replace('#city_wrapper', drupal_render($form['city_list'])); 
    return array('#type' => 'ajax', '#commands' => $commands); 
} 
function state_callback($form, &$form_state) { 
    // On changing state, make sure city field is reset 
    $form['city_list']['#value'] = ''; 
    return $form['city_list']; 
} 

希望這對別人有幫助。