在多个ajax调用完成之前,如何阻止表单提交? jQuery的

时间:2010-02-18 16:46:15

标签: jquery ajax validation forms

从p revious question开始,我询问是否禁用了提交按钮,直到所有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调用,EG一个div接收隐藏的输入,另一个div在页面的其他地方显示例如价格总和。 / p>

一些ajax调用快速完成的事实是否会否定ajaxStart的禁用效果? EG ajax call1和ajax call2都触发了ajaxStart - call1很快完成,它会在我们等待call2完成时重新启用表单吗?

有没有一种更好的方法可以简单地测试所有ajax调用是否已完成?

5 个答案:

答案 0 :(得分:2)

您可以为表单的submit事件添加事件处理程序。事件处理程序可以检查提交是否允许,如果没有则中止。以下是一些文档: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 :(得分:1)

您可以为每个ajax调用设置一个具有多个属性的JS对象。例如:

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

在表单提交循环中,通过每个属性检查是否为true。如果有任何错误,请不要提交表格。

当每个ajax调用完成时,将其属性(call1,call2等)设置为true。

这是你能做到的一种方式,不管它是最好的方式,我不知道。

答案 2 :(得分:0)

如何创建全局变量:

  var i = 0;

并且每个AJAX调用在调用开始时递增此变量,并在完成时递减它。

在提交表单时,检查此变量是否大于0并阻止提交。

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

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

</form>

答案 3 :(得分:0)

我猜你有这样的代码:

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

答案 4 :(得分:0)

我几乎已经解决了这个问题但是人们似乎仍然可以在回调结束之前提交表单。

我不知道这是不是巧合,但所有设法提交它的人都在Mac上使用Safari。

这是我正在使用的方法,如果有人能发现逻辑上的缺陷,那将会很棒。

使用文森特的建议:

// 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返回时显示为灰色,如果需要超过250ms,则也会显示动画。完成所有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;
  });

有人能发现我在这里做错了吗?

谢谢!