Суть задачи.
Перехватываю по hook_fork_alter() форму редактирования ноды. Для определенных ролей добавляю на нее дополнительную кнопку, при нажатии на которую необходимо сохранять содержание формы, не обращая внимания на то, что некоторые обязательные поля могут быть пустыми. Такая себе опция промежуточного "быстрого" сохранения.
Добавил свой хук валидации к форме, в котором перехватываю событи валидации формы при нажатии кнопки. Вызов функции валидации происходит, в нем для обязательного поля устанавливаю статус #required = FALSE, но валидация все равно гавкает, что поле обязательное, и форму соответственно не сабмитит.
В чем может быть проблема?
Комментарии
Наверно #required = FALSE нужно выставлять в hook_fork_alter().
код?
Выдержка из кода:
<?php function mymodule_form_alter(&$form, &$form_state, $form_id) {
...
$form['prsave'] = array('#weight' => '-3',
'#id' => 'timeout',
'#type' => 'button',
'#value' => 'Проміжне зберігання',
);
$form['#validate'][] = 'mymodule_form_validate';
$form['actions']['submit']['#submit'][] = 'mymodule_form_submit';
}
function
mymodule_form_validate($form, &$form_state) {switch ($form_state['clicked_button']['#id']) {
case $form['prsave']['#id']:
$form ['field_ram_capacity_relation']['uk']['#required'] = FALSE;
break;
}
} ?>
Так вот и трабл то в том, что если убрать обязательность в hook_form_alter(), то она (обязательность) уберется вообще. А нужно, чтобы она убиралась только для "быстрого" сохранения, а для полноценного сабмита по стандартной кнопке "Сохранить" оставалась.
проверяйте нажатую кнопку в $form_state
С проверкой значений нажатой кнопки в $form_state через hook_form_alter() тоже проблема. Согласно схеме обработки форм в Drupal 7, вызов hook_form_alter() происходит, если форма не прокэширована в текущей сессии. Если форма к кэше есть, то она отдается, миную вызов hook_form_alter().
Для проверки поставил в hook_form_alter() проверку на нажатие какой-либо из кнопок, даже не целевой:
if (isset($form_state['clicked_button']['#id'])) {
$form ['field_ram_capacity_relation']['uk']['#required'] = FALSE;
}
соответственно, ноль реакции, поскольку форма на вилидацию пошла из кэша.
кэш форм это выдумки. dsm($form_state) что выдаст?
dsm($form_state) прописан в hook_form_alter()
При первой загрузке формы dsm($form_state) начально значение $form_state, в котором форма не просабмичена:
submitted (Boolean) FALSE
executed (Boolean) FALSE
$form_state['clicked_button'] не проинициализировано.
При нажатии на кнопку сабмита формы dsm($form_state) вообще не отображается.
Пока нашел следующий выход из ситуации:
по hook_form_alter() смотрю поля, и для тех, которые обязательны к заполнению изменяю #element_validate на кастомный обработчик валидации. В этом обработике в зависимости от нажатой кнопки буду:
-разблокировать поле, с дальнейшей выдачей на сохранение;
-отдавать на стандартную валидацию вызовом соответствующей функции с подальшей выдачей на сохранение или возвратом в форму если поле не заполнено. Предварительно работает, но пока тестировал только на одном поле, имя которого захардкодил в модуле. Сейчас пишу универсальный обработчик, который будет автоматически просматривать поля и подменять их валидаторы.
Два аналогичных поля, разница только в виджетах. Для обоих переопределена функция валидации. Одно через валидацию проходит, второе нет. Танцы с бубном вокруг валидатора...
Тут можно было пойти путем от обратного. Все поля по умолчанию ['#required'] = FALSE;
в my_custom_form_validate(&$form, &$form_state) {} делаем следующее
<?php
function my_custom_form_validate(&$form, &$form_state) {
// Validate the postal code is entered when Ireland is not selected.
if ($form_state['values']['country'] != 'ireland' && empty(trim($form_state['values']['postal']))) {
form_set_error('postal', t('The Postal code is required.'));
}
}
?>
нашел здесь http://drupal.org/node/739742