AJAX форма проверки и отправки

Я создал форму в Drupal 7 и хочу использовать AJAX. Я добавил Это в массив кнопок отправки:

"#ajax" => array(
  "callback" => "my_callback",
  "wrapper" => "details-container",
  "effect" => "fade"
)

это работает, но вся функция проверки игнорируется. Как я могу проверить форму до my_callback() называется? И как я могу отображать сообщения о состоянии или ошибках в форме AJAX?

6 ответов


этот вопрос и ответ помогли мне найти правильное решение, но это не совсем кристально ясно. Давайте сделаем так.

вещи очень знать:

  1. сообщения об ошибках проверки будут помещены внутри того, что указано как #ajax['wrapper']
  2. обратите пристальное внимание, где Drupal формирует документацию API для AJAX-оболочки говорит, что " весь элемент с этим идентификатором заменяется, а не только содержание элемента."
  3. поскольку этот элемент заменен, вам лучше предоставить его снова. это вот почему ответ Мариуса Илие работает-не из-за массива и #markup, но скорее потому, что он включает div с набором идентификаторов оболочки.

вот код, который работал для меня на основе того, что Мариус поставил в комментарии выше:

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;
}

ничего из этого не работает для меня. Функция ajax формы submit по-прежнему просто вызывает функцию обратного вызова напрямую, минуя проверку, отправку, а также делает ее так, что кнопку нельзя щелкнуть несколько раз. Сообщения проверки не отображаются. Я буквально скопировать и вставить код Джошуа Stewardson и он не работал.

тот факт, что этот случай использования настолько сложен и недокументирован, очень расстраивает. Для меня это кажется самым основным запросом для формы 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.'));
}

хорошо, я понял. По-видимому, вы должны вернуть массив в свою функцию обратного вызова ajax, а не только текстовое сообщение...

что-то вроде этого:

return array("#markup" => "<div id='wrapper'></div>");

Я искал много часов, чтобы сделать это правильно. К сожалению, большинство этих решений по-прежнему полагаются на проверку на стороне сервера 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'
    )
);

теперь проверка запускается, как только нажата кнопка отправки,и проверка на стороне сервера происходит только после ее проверки!


//вы можете использовать проверку формы 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;
 });