我正在尝试在我使用theme_table
/ theme('table',..)
生成的表格中包含Drupal表单元素。具体来说,我试图包含一个附有AHAH的提交按钮。
目前,我只是在每一行中包含一个对drupal_render
的调用,以呈现我动态生成的AHAH元素。按钮呈现正常,但没有连接AHAH。
所以,我的问题是:有没有办法将AHAH附加到只有drupal_render
的东西?
如果没有,我怎样才能将AJAX / AHAH调用附加到theme_table
生成的表中的元素?我需要允许用户对表中的数据行执行某些操作,但需要不刷新页面。
TIA,
本吉
答案 0 :(得分:1)
我相信AHAH仅适用于drupal_get_form()
。您必须自己编写AJAX(handbook page)。
也许您可以将drupal_get_form()
的返回值保存在变量中并将其传递给主题函数?
答案 1 :(得分:1)
我认为这是一个错误,但我创建了一个非常简单的通用解决方案:) Januz的解决方案对我不起作用,因为该表已经在表单中使用,并且它仅适用于非常具体的用例而不是通用解决方案。 您可以查看以下代码和我编写的函数作为示例 注意:您可能需要修改代码以满足您的需求
/**
* @param $form
* @param $form_state
* @param $form_id
*/
function mymodule_form_alter(&$form, &$form_state, $form_id) {
$test_button = array(
'test_button' => array(
'#type' => 'button',
'#value' => t('Add'),
'#name' => 'test_button',
'#id' => 'test_button',
'#weight' => 2,
'#ajax' => array(
'callback' => '_mymodule_ajax_callback',
)
)
);
$form['mytable'] = array(
'#weight' => 1,
'#theme' => 'table',
'#header' => array(
array("data" => "Item"),
),
'#rows' => array(
'data' => array(
array(
'data' => $test_button
),
)
),
);
// This is a work around, ajax elements do not work when used in drupal tables
mymodule_table_ajax_workaround($test_button, $form, $form_state);
}
/**
* Ajax enabled form elements do not work then used inside a drupal table and rendered via theme_table
* This is a workaround to address the issue
* @param $elements
* @param $form
* @param $form_state
*/
function mymodule_table_ajax_workaround($elements, &$form, &$form_state) {
foreach ($elements as $element_name => $element_info) {
drupal_add_js(array('ajax' => array(
$element_name => array(
'callback' => $element_info['#ajax']['callback'],
'event' => 'mousedown',
'keypress' => true,
'prevent' => 'click',
'url' => '/system/ajax',
'submit' => array(
'_triggering_element_name' => $element_name . '_fake',
'_triggering_element_value' => $element_info['#value'],
)
),
)), 'setting');
$form['form_ajax_workaround'][$element_name] = array(
'#name' => $element_name . '_fake',
'#input' => true,
'#value' => $element_info['#value'],
'#ajax' => array(
'callback' => $element_info['#ajax']['callback']
)
);
}
}
答案 2 :(得分:0)
您可以通过主题功能和表格生成来完成此操作。 AHAH会奏效。唯一的问题是当你有多个“桌子”时,事情开始变得毛茸茸。
答案 3 :(得分:0)
简短说明(如果我错了,请纠正我!):当Drupal的Form API保留在"#theme" => "table"
渲染数组中时,启用AJAX的表单元素看起来是不可见的。这可能是由于render()
使用element_children()
而未查看表格的#header
或#rows
元素。解决此问题的方法是向窗体中添加虚拟元素,这些元素对Form API可见,并将AJAX事件绑定到原始元素以触发虚拟元素。
我分享了新浪Salek对Drupal 7的强大解决方法,主要区别在于:
"#type" => "value"
表示虚拟按钮,而不是内部选项"#input" => TRUE
,构建表单时为每个启用AJAX的元素实现变通方法的示例:
/**
* My form.
*/
function MY_MODULE_my_form($form, &$form_state) {
// Define button. NB: An ID and name are required!
$my_button = array(
'#type' => 'button',
'#id' => 'test_button',
'#name' => 'test_button',
'#value' => t('Button label'),
'#ajax' => array('callback' => '_MY_MODULE_ajax_callback'),
);
// Call table AJAX workaround function on the button.
MY_MODULE_table_ajax_workaround($my_button, $form);
// Define table.
$form['my_table'] = array(
'#theme' => 'table',
'#header' => array(
array('data' => t('Column header')),
),
'#rows' => array(
'data' => array(
array('data' => $my_button),
)
),
);
return $form;
}
/**
* Workaround for AJAX enabled form elements that remain inside tables.
*
* Problem: AJAX enabled form elements appear invisible to Drupal's Form API
* when they remain inside a #theme => table render array. This is probably due
* to render() using element_children() which does not look into a table's
* #header or #rows elements.
*
* Workaround: Add dummy elements to the form which are visible to the Form API
* and bind AJAX events to the original elements to trigger the dummy elements.
*
* Based on:
* @link http://stackoverflow.com/questions/1981781
*
* Shared at:
* @link http://stackoverflow.com/a/31098784/328272
*
* Another workaround is the render elements using custom theme functions, but
* this seems slightly more complicated and rendered elements are no longer
* alterable.
* @link https://www.drupal.org/node/2101557#comment-7920151
*/
function MY_MODULE_table_ajax_workaround($element, &$form, $js_ajax_options = array()) {
// Add dummy element.
$form['table_ajax_workaround'][$element['#id']] = array(
'#type' => 'value',
'#name' => $element['#name'],
'#value' => $element['#value'],
'#ajax' => $element['#ajax'],
);
// Bind AJAX event to the original element, default properties are used. See
// Drupal.ajax in misc/ajax.js.
$js_setting['ajax'][$element['#id']] = drupal_array_merge_deep(array(
'event' => 'mousedown',
'keypress' => true, // Use lowercase booleans to support IE.
'prevent' => 'click',
'url' => base_path() . 'system/ajax',
'submit' => array(
'_triggering_element_name' => $element['#name'],
'_triggering_element_value' => $element['#value'],
),
), $js_ajax_options);
// Add JS setting.
drupal_add_js($js_setting, 'setting');
}