Answers:
您可以使用Ajax完成此任务。Drupal 7现在具有良好的Ajax支持。在第一个选择列表(城市)上,您需要添加Ajax信息。然后,可以基于第一个选择列表中的信息填充第二个选择列表。您甚至还可以隐藏第二个选择列表,直到第一个选择列表中的一个选项被选中为止,我将稍作解释。首先,设置基本形式:
$form['city'] = array(
'#type' => 'select',
'#title' => t('City'),
'#options' => $options,
'#ajax' => array(
'event' => 'change',
'wrapper' => 'squadron-wrapper',
'callback' => 'mymodule_ajax_callback',
'method' => 'replace',
),
);
$form['squadron_wrapper'] = array('#prefix' => '<div class="squadron-wrapper">', '#suffix' => '</div>');
$form['squadron_wrapper']['squadron'] = array(
'#type' => 'select',
'#title' => t('Squadron'),
'#options' => $squadron_options,
);
这只是元素的基本设置。现在,您需要一种方法来确定中队应该使用的选项。首先,您需要在“ city”选择列表中标识您的Ajax回调。在大多数情况下,您可以只返回包装ajax元素的元素,在这种情况下为$ form。
function mymodule_ajax_callback($form, $form_state) {
return $form;
}
现在,当“城市”选择列表更改时,它将重建表单的中队包装器部分。您的“城市”值现在将在$ form_state ['values']中。因此,在重建表单时,我们需要基于“ city”的值确定为选择列表提供哪些选项。
// Get the value of the 'city' field.
$city = isset($form_state['values']['city']) ? $form_state['values']['city'] : 'default';
switch ($city) {
case 'default':
// Set default options.
break;
case 'losangeles':
// Set up $squadron_options for los angeles.
break;
}
// If you want to hide the squadron select list until a city is
// selected then you can do another conditional.
if ($city !== 'default') {
$form['squadron_wrapper']['squadron'] = array(
'#type' => 'select',
'#title' => t('Squadron'),
'#options' => $squadron_options,
);
}
非常感谢上面的jordojuice。在他的帮助下,我设法找到了解决方案。我还参考了http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-submission中的示例。我最终使用下面的代码在自定义模块中工作。由于某种原因,我无法在$ form_state值中找到任何值,但能够在$ form中找到它们。最终,当我进行测试时,我收到一条错误消息,表明Drupal在下拉菜单中检测到非法选择。我通过在form.inc中注释掉第1290行来解决这个问题:
form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));
我使用的最终代码是:
<?php
function sappers_squadron_form_work_history_node_form_alter(&$form, &$form_state) {
//echo '<pre>';
//print_r ($form);
//echo '</pre>';
$squadron_options = array();
if(isset($form['field_wkhist_city']['und']['#default_value'][0])) {
$city = $form['field_wkhist_city']['und']['#default_value'][0];
}
else {
$city = 0;
}
$squadron_options = sappers_squadron_squadrons($city);
$form['field_wkhist_city']['und']['#ajax'] = array(
'event' => 'change',
'wrapper' => 'squadron-wrapper',
'callback' => 'sappers_squadron_ajax_callback',
'method' => 'replace',
);
$form['field_squadron']['und']['#prefix'] = '<div id="squadron-wrapper">';
$form['field_squadron']['und']['#suffix'] = '</div>';
$form['field_squadron']['und']['#options'] = $squadron_options;
}
function sappers_squadron_ajax_callback($form, $form_state) {
$city = $form['field_wkhist_city']['und']['#value'];
$form['field_squadron']['und']['#options'] = sappers_squadron_squadrons($city);
return $form['field_squadron'];
}
function sappers_squadron_squadrons($city) {
$nodes = array();
$select = db_query("SELECT node.title AS node_title, node.nid AS nid FROM {node} node INNER JOIN {taxonomy_index} taxonomy_index ON node.nid = taxonomy_index.nid WHERE (( (node.status = '1') AND (node.type IN ('squadron')) AND (taxonomy_index.tid = $city) )) ORDER BY node_title ASC");
$nodes[]="";
foreach ($select as $node) {
$nodes[$node->nid] = $node->node_title;
}
return $nodes;
}
?>
根本原因为“已检测到非法选择。请与站点管理员联系。” 是添加了0的空字符串$nodes[]="";
对于field_squadron字段无效。
请参阅高级PHP编程和开发,但请记住,D7中不推荐使用DANGEROUS_SKIP_CHECK和validated标志。
在删除该行之后,错误消失了。