#jquery #ajax #drupal-7 #drupal-forms
#jquery #ajax #drupal-7 #drupal-forms
Вопрос:
Я создал форму в Drupal 7 и хочу использовать AJAX. Я добавил это в массив кнопок отправки:
"#ajax" => array(
"callback" => "my_callback",
"wrapper" => "details-container",
"effect" => "fade"
)
Это работает, но вся функция проверки игнорируется. Как я могу проверить форму перед my_callback()
вызовом? И как я могу отобразить сообщения о состоянии или ошибках в форме AJAX?
Комментарии:
1. Вы уверены, что проверка игнорируется? Я делал это десятки раз, и проверка никогда не игнорировалась (если я специально не сказал Drupal игнорировать их использование
#limit_validation_errors
). Также сообщения об ошибках автоматически загружаются вwrapper
элемент по умолчанию, поэтому, как только вы исправите первый бит, он должен просто встать на свое место. Не могли бы вы опубликовать еще немного своего кода?2. @Clive Я только что создал другую тестовую форму, те же результаты. Вот форма: функция dr_search_test_form($form, amp;$fstate) { $form[«wrapper»] = array( «#markup» => «<div id=’test-ajax’></div>» ); $form[«name»] = array(«#type» => «textfield», «#required» => true, «#title» => «Name» ); $form[«submit»] = массив ( «#type» => «submit», «#value» => «Отправить», «#ajax» => array( «обратный вызов» => «dr_search_test_form_callback», «оболочка» => «тест-ajax», «эффект» => «fade» ) ); возвращает $form; }
3. функция dr_search_test_form_callback($form, amp;$fstate) { возвращает «sadsadas»; } функция dr_search_test_form_validate($form, amp;$fstate) { form_set_error(«имя», «Отображается некоторая ошибка».); }
4. Я просто вижу текст из функции обратного вызова «sadsadas», но проверка не выполняется….
Ответ №1:
Этот вопрос и ответ помогли мне найти правильное решение, но оно не совсем предельно ясно. Давайте сделаем это так.
О чем нужно знать:
- Сообщения об ошибках проверки будут помещены внутри всего, что указано в качестве
#ajax['wrapper']
- Обратите пристальное внимание на то, где в документации Drupal Forms API для оболочки ajax говорится, что «заменяется весь элемент с этим идентификатором, а не только содержимое элемента».
- Поскольку этот элемент заменен, вам лучше предоставить его снова. Вот почему ответ Мариуса Илие работает — не из-за массива и
#markup
, а скорее потому, что он включает div с установленным идентификатором оболочки.
Вот код, который работал для меня, основываясь на том, что Мариус написал в комментарии выше:
function dr_search_test_form($form, amp;$fstate) {
$form["wrapper"] = array("#markup" => "<div id='test-ajax'></div>");
$form["name"] = array(
"#type" => "textfield",
"#required" => true,
"#title" => "Name"
);
$form["submit"] = array(
"#type" => "submit",
"#value" => t("Send"),
"#ajax" => array(
"callback" => "dr_search_test_form_callback",
"wrapper" => "test-ajax",
"effect" => "fade",
),
);
return $form;
}
function dr_search_test_form_callback($form, amp;$fstate) {
return "<div id='test-ajax'>Wrapper Div</div>";
}
function dr_search_test_form_validate($form, amp;$fstate) {
form_set_error("name", "Some error to display.");
}
Комментарии:
1. 1 за то, что поделился своим опытом после закрытия вопроса; это настоящие вопросы и ответы сообщества.
2. Работает нормально. Как очистить значения формы после отправки?
Ответ №2:
Я нашел отличное решение этой проблемы.
Заслуга принадлежит блогу этого парня:
http://saw.tl/validate-form-ajax-submit-callback
Решение, которое он предлагает, заключается в следующем:
// when creating or altering the form..
{
$form['#prefix'] = '<div id="formwrapper">';
$form['#suffix'] = '</div>';
// the submit button
$form['save']['#ajax'] = array(
'callback' => 'mymodule_form_ajax_submit',
'wrapper' => 'formwrapper',
'method' => 'replace',
'effect' => 'fade',
);
// ...
}
function mymodule_from_ajax_submit($form, amp;$form_state) {
// validate the form
drupal_validate_form('mymodule_form_id', $form, $form_state);
// if there are errors, return the form to display the error messages
if (form_get_errors()) {
$form_state['rebuild'] = TRUE;
return $form;
}
// process the form
mymodule_form_id_submit($form, $form_state);
$output = array(
'#markup' => 'Form submitted.'
);
// return the confirmation message
return $output;
}
Комментарии:
1. $form[‘#prefix’] и $form[‘#suffix’] не работают в моем перехватчике _form_alter.
2. @AlxVallejo Это должно применяться к любому элементу формы, включая саму форму. Проверьте ссылку на API формы
Ответ №3:
У меня ничего из этого не работает. Ajax-функция отправки формы по-прежнему просто вызывает функцию обратного вызова напрямую, минуя проверку, отправку, а также делая так, чтобы кнопку нельзя было нажимать несколько раз. Сообщения о проверке НЕ отображаются. Я буквально скопировал и вставил код Джошуа Стюардсона, и это не сработало.
Тот факт, что этот вариант использования настолько сложный и недокументированный, очень расстраивает. Мне кажется, что это самый простой из запросов к API AJAX form. Хорошо, я выплеснул свое разочарование на решение.
Вот что я в итоге сделал, чтобы заставить это работать. Это кажется хакерским и отсталым. Он также сломается, если на одной странице будет несколько экземпляров формы, но это было лучшее, что я мог сделать. Если кто-нибудь может пролить свет на это, ПОЖАЛУЙСТА, сделайте!
По сути, вам нужно заменить всю форму самой собой внутри вашего обратного вызова и вручную добавить любые установленные сообщения к объекту формы. Сделайте это, объявив оболочку идентификатором вашей формы (она сломается, если на одной странице будет несколько экземпляров вашей формы, потому что идентификатор будет обновлен).
function productsearchbar_savesearch_form($form, amp;$form_state) {
$form["wrapper"] = array("#markup" => "<div class='inline-messages'></div>");
$form["name"] = array(
"#type" => "textfield",
"#required" => true,
"#title" => "Name"
);
$form["submit"] = array(
"#type" => "submit",
"#value" => "Send",
"#ajax" => array(
"callback" => "productsearchbar_savesearch_form_callback",
"wrapper" => "productsearchbar-savesearch-form",
"effect" => "fade"
)
);
return $form;
}
function productsearchbar_savesearch_form_callback($form, amp;$form_state) {
$messages = theme('status_messages');
if($messages){
$form["wrapper"] = array("#markup" => "<div class='inline-messages'>$messages</div>");
}
return $form;
}
function productsearchbar_savesearch_form_validate($form, amp;$form_state) {
if ($form_state['values']['name'] == '') {
form_set_error('', t('Name field is empty!'));
}
}
function productsearchbar_savesearch_form_submit($form, amp;$form_state) {
drupal_set_message(t('Your form has been saved.'));
}
Комментарии:
1. Я испытываю обратное, запускается обратный вызов Ajax, а затем вызывается функция отправки формы, и сообщение в обработчике отправки возвращается с ответом Ajax, в котором говорится, что оно было сохранено. Это не то, чего я хочу. Поскольку это запускает пакетную операцию. Это Drupal 7, если это имеет значение.
Ответ №4:
Хорошо, я понял это. По-видимому, вы должны возвращать массив в вашей функции обратного вызова ajax, а не просто текстовое сообщение…
Что-то вроде этого:
return array("#markup" => "<div id='wrapper'></div>");
Ответ №5:
Я много часов искал способ сделать это правильно. К сожалению, большинство этих решений по-прежнему полагаются на проверку на стороне сервера Drupal, чтобы определить, следует ли помещать в оболочку результаты ajax или сообщения об ошибках на стороне клиента. Полагаться на результат сервера медленнее, чем проверка на стороне клиента, которая должна быть практически мгновенной. Кроме того, замена формы … формой … с сообщениями об ошибках слишком запутана для моих предпочтений.
Используйте методы проверки jquery для запуска события ajax с помощью триггера javascript:
// Prevent form submission when there are client-side errors, trigger ajax event when it is valid
(function ($) {
Drupal.behaviors.submitForm = {
attach: function (context) {
var $form = $("form#validated_form", context);
var $submitButton = $('input[type="submit"]', $form);
$form
.once('submitForm')
.off('submit')
.on('submit', function(e){
// Prevent normal form submission
e.preventDefault();
var $form = $(this);
// The trigger value should match what you have in your $form['submit'] array's ajax array
//if the form is valid, trigger the ajax event
if($form.valid()) {
$submitButton.trigger('submit_form');
}
});
}
};
})(jQuery);
Ссылайтесь на триггер javascript как на ваше событие ajax, которое прослушивается:
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#ajax' => array(
'event' => 'submit_form',
'callback' => 'callback_function_for_when_form_is_valid',
'wrapper' => 'validated_form'
)
);
Теперь проверка запускается сразу после нажатия кнопки отправки, а проверка на стороне сервера выполняется только после ее подтверждения!
Ответ №6:
// вы можете использовать проверку формы jquery
jQuery('#button-id').mousedown(function() {
var textval = $("#get-text-val").val();
if (textval == '') {
$("#apend-error-msg").append('<div id="add-text-error" class="add-text-error">error msg</div>');
return false;
}
else {
return true;
}
return false;
});
Комментарии:
1. Выход за пределы Drupal для проверки может быть проблематичным, если вы хотите проверить больше, чем длину строки.