Здравствуйте.
имеется форма состоящая из повторяющихся блоков.
ПОльзователь может добавлять новые блоки (реализовано через AHAH) и удалять существующие.
Для удаление , в каждом блоке предусмотрена кнопка Remove, все кнопки привязаны к одному AHAH хендлеру.
<?php
...
$items['remove_js'] = array(
'page callback' => 'remove_ahah',
'access arguments' => array('access ahah form'),
'type' => MENU_CALLBACK,
);
...
$form['items']['remove'] = array(
'#type' => 'submit',
'#value' => 'Remove',
'#ahah' => array(
'path' => 'remove_js',
'wrapper' => 'item-wrapper',
'method' => 'replace',
'effect' => 'fade')
);
?>
Как понять от какой кнопки был вызван хендлер? Может можно использовать как-то 'page arguments' у $items['remove_js']
Комментарии
> Может можно использовать как-то 'page arguments' у $items['remove_js']
Да. Вот простой вариант:
<?php
$items['remove_js/%'] = array(
'page callback' => 'remove_ahah',
'page arguments' => array(1),
'access arguments' => array('access ahah form'),
'type' => MENU_CALLBACK,
);
... $form['items']['block1']['remove'] = array(
'#type' => 'submit',
'#value' => 'Remove',
'#ahah' => array(
'path' => 'remove_js/1',
'wrapper' => 'item-wrapper',
'method' => 'replace',
'effect' => 'fade')
); $form['items']['block2']['remove'] = array(
'#type' => 'submit',
'#value' => 'Remove',
'#ahah' => array(
'path' => 'remove_js/2',
'wrapper' => 'item-wrapper',
'method' => 'replace',
'effect' => 'fade')
);
?>
UPD
Функция-обработчик примет вид:
<?phpfunction remove_js($block_id) {
if (!$block_id || empty($_POST['form_build_id'])) {
// error
...
}
/* загрузка кэшированной формы; удаление нужного блока; сохранение формы обратно в кэш. */
...
}?>
Чтобы понять как нужно реализовывать работу с кэшем форм, посмотрите реализацию AHAH в модуле Poll, а также ahah helper.
спасибо, действительно все просто
Выдрано из статьи на drupal.org (Adding dynamic form elements using AHAH).
Если быть кратким, то когда происходит запрос ahah, то сабмитится вся форма, но при этом не отрабатывают валидаторы/сабмиттеры и т.д. Соответственно для этого нужно сделать это вручную, прописав в обработчик ahah что-то вроде этого:
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form['#redirect'] = FALSE;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
$qt_form = $form['qt_wrapper']['tabs'];
unset($qt_form['#prefix'], $qt_form['#suffix']); // Prevent duplicate wrappers.
$javascript = drupal_add_js(NULL, NULL, 'header');
drupal_json(array(
'status' => TRUE,
'data' => theme('status_messages') . drupal_render($qt_form),
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
));
}
,где последние строки отвечают за "откусывание" нужных секций для добавления.
Использовав это вы можете реализовать все стандартно с помощью form->submit->form, и кроме того, формы на стороне пользователя и в кеше будут совпадать, что тоже немаловажно.
Если требуется модифицировать javascript страницы после AHAH-запрсов - посмотрите как это реализовано в модуле CCK filefield(и вообще там все красиво реализовано).
Полезный модуль, в нем есть решение следующей проблемы - у кнопок добавленных через AHAH не работает AHAH и они просто делают submit страницы
<?php
// Add the AHAH settings needed for our new buttons.
// Loop through the JS settings and find the settings needed for our buttons.
$javascript = drupal_add_js(NULL, NULL);
$filefield_ahah_settings = array();
if (isset($javascript['setting'])) {
foreach ($javascript['setting'] as $settings) {
if (isset($settings['ahah'])) {
foreach ($settings['ahah'] as $id => $ahah_settings) {
if (strpos($id, 'filefield-upload') || strpos($id, 'filefield-remove')) {
$filefield_ahah_settings[$id] = $ahah_settings;
}
}
}
}
}
if (!empty($filefield_ahah_settings)) {
$output .= '<script type="text/javascript">jQuery.extend(Drupal.settings.ahah, '. drupal_to_js($filefield_ahah_settings) .');</script>';
}
?>