Как предотвратить отправку формы до завершения нескольких вызовов ajax? JQuery - PullRequest
9 голосов
/ 18 февраля 2010

Исходя из повторного вопроса p , где я спрашивал об отключении кнопки отправки до тех пор, пока все вызовы ajax не закончатся ...

Похоже, что людям все еще удается отправить форму даже с отключенной кнопкой и предупреждающим знаком. Я предполагаю, что это может быть от нажатия «ввод» в текстовом вводе.

Как мне отключить всю форму, а не только кнопку отправки?

Код на данный момент:

// if we're waiting for any ajax to complete we need to disable the submit
$(document).ajaxStart(function() {
  $(".ajaxbutton").attr("disabled", "disabled");
  // if it's taken longer than 250ms display waiting message
  timer = setTimeout(function() {
    $('#processingAlert').html(' ...please wait one moment');
    $('#processingAlert').show();
  }, 250);
})
$(document).ajaxComplete(function() {
  $(".ajaxbutton").removeAttr("disabled");
    $('#processingAlert').hide();
    // cancel showing the message when the ajax call completes.
clearTimeout(timer);
});

Еще одна вещь, которую я должен упомянуть и которая может вызывать проблему, заключается в том, что одновременно происходит несколько вызовов ajax, например, один div получает скрытые входные данные, а другой div в другом месте на странице, например, показывает общую цену. 1012 *

Может ли тот факт, что некоторые вызовы ajax завершаются, быстро свести на нет отключающий эффект ajaxStart? Например, ajax call1 и ajax call2 оба запускают ajaxStart - call1 завершается очень быстро, будет ли он снова активировать форму, пока мы ожидаем завершения call2?

Есть ли лучший способ сделать это, где мы могли бы просто проверить, завершены ли ВСЕ вызовы ajax?

Ответы [ 5 ]

2 голосов
/ 18 февраля 2010

Вы можете добавить обработчик события для отправки события формы. Обработчик событий может проверить, является ли отправка разрешенной, и прервать, если нет. Вот несколько документов: http://api.jquery.com/submit/

Обратите внимание, что если javascript на странице вызывает .click () для одной из кнопок отправки формы, форма будет отправлена ​​без вызова вашего обработчика .submit (). Это странная проблема jQuery (http://groups.google.com/group/jquery-en/browse_thread/thread/1317bfd4e3a8b233?pli=1), которая, как мне кажется, люди jQuery не считают ошибкой. Могут быть и другие подобные случаи, надеюсь, нет.

Если вы используете ASP.NET, в зависимости от того, что находится в форме, ASP.NET может внедрить функцию «__doPostBack». Возможно, вам придется перехватить эту функцию, переопределив ее с помощью некоторого пользовательского кода, который вызывает оригинал.

1 голос
/ 18 февраля 2010

Вы можете просто установить объект JS с несколькими свойствами для каждого вызова ajax.Пример:

var requiredCalls = {call1: false, call2: false, call3: false}

При отправке формы необходимо пройти через каждое свойство, чтобы проверить его на true.Если они ложны, не отправляйте форму.

По завершении каждого вызова ajax установите для его свойства (call1, call2 и т. Д.) Значение true.

Это можно сделать одним способом, независимо отлучший способ, я не знаю.

0 голосов
/ 27 февраля 2010

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

Я не знаю, совпадение ли это, но все люди, которым удалось отправитьон использовал Safari на Mac.

Вот метод, который я использую, было бы замечательно, если бы кто-то мог заметить изъян в логике.

Используя предложение Винсента:

// set this to zero before any ajax calls are made  
var ajaxcallcounter = 0;

затем, когда я выполняю ajax-вызов, например:

    // UPDATE SHIPPING BOXES
    var data = 'pickup=1';
    ajaxcallcounter++;
    $.ajax({
    type: "POST",
    url: "incViewbasketShippingBoxes.php", 
    data: data,
    success: function(response) {
        $('#shippingBoxes').html(response);
            ajaxcallcounter--;
    }
    });

Это работает нормально, у меня также есть хороший небольшой скрипт для обратной связи с пользователем - кнопка неактивна, ожидая возвращения ajaxcounters иесли это занимает больше 250 мс, отображается анимация.Как только все вызовы ajax завершены, счетчик возвращается к нулю, и кнопка отображается как обычно:

// when ajaxStart is triggered, keep an eye on the ajaxcallcounter
$(document).ajaxStart(function() {
  $(".ajaxbutton").attr("disabled", "disabled");
  $('#processingAlert').html(' ...calculating');
  $('#processingAlert').show();

  // if it's taken longer than 250ms (say) display waiting message
  timer = setTimeout(function() {
    $('#processingAlert').html(' ...calculating <img src="../gfx-site/ajax-loader.gif">');
  }, 250);
});
// when ajaxComplete is triggered, keep an eye on the ajaxcallcounter
$(document).ajaxComplete(function() {
    if (ajaxcallcounter == 0) {
        $(".ajaxbutton").removeAttr("disabled");
        $('#processingAlert').hide();
        // cancel showing the message when the ajax call completes.
    clearTimeout(timer);
    }
});

Наконец, мы приходим к функции, которая должна предотвратить отправку, но неКажется, не работает:

// can we submit yet?
  $('#checkoutform').submit(function() {
    if (ajaxcallcounter == 0) {
      return true;
    }
    return false;
  });

Кто-нибудь может заметить, что я здесь сделал неправильно?

Спасибо!

0 голосов
/ 18 февраля 2010

Полагаю, у вас есть такой код:

var form = $(...);
form.bind ('submit', function (...) {
  $.ajax (
    ...,
    complete: function (...) {
      // do something
    }
  );
}

Вы можете сделать это:

var form = $(...);
form.bind ('submit', function (...) {
  if ($ (this).data ('inprogress') === null) {
    $ (this).data ('inprogress', 1);
    // disable submit button
    $.ajax (
      ...,
      complete: function (...) {
        // do something
        $ (this).data ('inprogress', null)
        // enable submit button
      }
    );
  } else {
    // display notification / warning
  }
}
0 голосов
/ 18 февраля 2010

Как насчет создания глобальной переменной:

  var i = 0;

и каждый вызов AJAX увеличивает эту переменную в начале вызова и уменьшает ее при завершении.

При отправке формы проверьте, превышает ли эта переменная значение 0, и запретите отправку.

  function submitForm(){
      return i == 0;
  }

<form onsubmit="submitForm()"....>

</form>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...