Ответ 1
Хорошо, я понимаю. Очевидно, вы должны вернуть массив в свою функцию обратного вызова ajax, а не только текстовое сообщение...
Что-то вроде этого:
return array("#markup" => "<div id='wrapper'></div>");
Я создал форму в Drupal 7 и хочу использовать AJAX. Я добавил это в массив кнопок отправки:
"#ajax" => array(
"callback" => "my_callback",
"wrapper" => "details-container",
"effect" => "fade"
)
Это работает, но вся функция проверки игнорируется. Как я могу проверить форму до того, как вызывается my_callback()
? И как я могу отображать состояние или сообщения об ошибках в форме AJAX?
Хорошо, я понимаю. Очевидно, вы должны вернуть массив в свою функцию обратного вызова ajax, а не только текстовое сообщение...
Что-то вроде этого:
return array("#markup" => "<div id='wrapper'></div>");
Этот вопрос и ответ помогли мне найти правильное решение, но это не совсем ясно. Позвольте сделать это так.
Что нужно знать:
#ajax['wrapper']
#markup
, а из-за того, что он включает div с установленным идентификатором обертки.Вот код, который работал у меня, основываясь на том, что Marius добавил в комментарий выше:
function dr_search_test_form($form, &$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, &$fstate) {
return "<div id='test-ajax'>Wrapper Div</div>";
}
function dr_search_test_form_validate($form, &$fstate) {
form_set_error("name", "Some error to display.");
}
Я нашел отличное решение этой проблемы.
Кредит идет на этот блог парня:
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, &$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;
}
Ничто из этого не работает для меня. Форма submit Функция ajax по-прежнему просто вызывает функцию обратного вызова, минуя проверку, отправку и также делая ее так, что кнопка не может быть нажата несколько раз. Сообщения проверки не отображаются. Я буквально скопировал и вставил код Джошуа Стюардсона, и он не работал.
Тот факт, что этот случай использования настолько жесткий и недокументированный, очень расстраивает. Для меня это похоже на самые основные запросы на API формы AJAX. Хорошо, сделайте, чтобы выпустить мое разочарование, на решение.
Вот что я сделал, чтобы заставить это работать. Он чувствует себя взломанным и отсталым. Он также будет разбит, если на одной странице есть несколько экземпляров формы, но это было лучшее, что я мог сделать. Если кто-то может пролить свет на это ПОЖАЛУЙСТА, сделайте это!
В принципе, вы должны заменить всю форму на себя внутри своего обратного вызова и вручную добавлять любые заданные сообщения в объект формы. Сделайте это, объявив обертку как идентификатор вашей формы (она сломается, если на одной странице будет несколько экземпляров вашей формы, поскольку идентификатор будет обновлен).
function productsearchbar_savesearch_form($form, &$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, &$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, &$form_state) {
if ($form_state['values']['name'] == '') {
form_set_error('', t('Name field is empty!'));
}
}
function productsearchbar_savesearch_form_submit($form, &$form_state) {
drupal_set_message(t('Your form has been saved.'));
}
Я искал много часов, чтобы сделать это правильно. К сожалению, большинство из этих решений по-прежнему полагаются на проверку на стороне сервера 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 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'
)
);
Теперь проверка активируется, как только нажата кнопка отправки, и проверка на стороне сервера происходит только после ее действительного!
//вы можете использовать проверку формы 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;
});