使用D7表单API,我需要创建一个分层的过滤器集,每个过滤器都具有前一个过滤器的依赖关系。当在其中一个过滤器上进行选择时,线下的所有过滤器将根据链上的选择自动更新。看起来很直接,但还有一点点。
举个例子,假设我有一个数据库,我想要显示+ 75k的产品记录。
显然我无法在每个select-multi中显示所有选项,所以这就是我设想它的工作方式:
我一直在看D7表单api,我找不到任何关于这种功能的提及。我知道有#ajax和#state回调,但文本输入自动完成填充链中的select-multi和触发事件有点模糊。
如果有帮助,我已经使用jQuery构建了这整个功能。我现在的目标是使用适当的表单API将其移植到Drupal中。
答案 0 :(得分: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'];
}
// 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'];
}
希望这会对某人有所帮助。
答案 1 :(得分:0)
创建论坛函数让我们说my_module_filters_form比使用hook_menu添加菜单回调
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
);
}
每次在HTML表单中进行更改时,都会对该回调执行ajax调用,并将HTML替换为您的输出。