2015-12-22 55 views
8

我正在一个动态的在线表单网站上工作。在主窗体中,我有多个可以动态添加和删除的子窗体。等待所有的AJAX呼叫比显示对话框

<div class='subform'> 
    //form fields 
    <input ...> 
    ... 
    <button class='subform_submit'> 
</div> 

对于每个子窗体,我绑定这样子窗体上的提交按钮AJAX调用:

$('#main').on('click', '.subform_submit', function(){ 
    // Get this subform's user input 
    ... 
    $.ajax({ 
     url: .., 
     type: .., 
     data: /* this subform's data */ 
    }); 
}); 

因此,在该页面中,我可能取决于用户的选择0至10子窗体。 我在页面底部也有一个主要提交按钮,可以将这些子表单和主窗体的数据一起提交。

$('#main').on('click', '#submit', function(e){ 
    $('.subform_submit').click(); // Submit each subform 
    bootbox.confirm({ }); 
}) 

一旦主点击提交按钮,我想显示加载图片,然后显示一个对话框,(我用bootbox.confirm()这里),直到所有的Ajax调用已经完成。 此对话框告诉用户包括子表单在内的整个表单已提交。 但问题是每个AJAX调用可能需要2秒才能完成,我不知道可能的调用可能有待完成。我怎么能写这个主提交按钮,这样它会:

  1. 立即显示加载图像,并
  2. 隐藏加载图像,并显示对话框中的所有Ajax调用完成后?
+0

感谢@Lewis最佳的解决方案! – monknom

回答

2

你想使用.done()为了指定应该等到AJAX异步函数完成的代码。

$.ajax({ 
    url:.., 
    type: .., 
    data: /* this subform's data*/ }) 
    .done(function() { 
     //Put code here 
    }); 
1

您试过.ajaxStop() event handler

$(document).ajaxStop(function() { 
    // place code to be executed on completion of last outstanding ajax call here 
}); 

此外,检查this answer

4

跟踪的多少分的形式存在;

$subFormsCount = $('.subform').length; 

跟踪有多少表单已提交;

$submittedForms = 0; 

每次完成表单提交,加个$ submittedForms;

$.ajax({ 
    .. 
    .. 
    done: function(){ 
    $submittedForms++; 
    } 
}) 

创建一个全局计时器以查看提交的表单数是否与子表单的总数相匹配。如果为true,则隐藏对话框;

setInterval(function(){ 
    if($submittedForms == $subFormsCount){ 
    $('.dialog').show(); 
    } 
}, 50ms) 

编辑

你可以跳过全局定时器(因为这将可能是几毫秒出) - 在您的ajax.done而不是检查;

$.ajax({ 
    .. 
    .. 
    done: function(){ 
    $submittedForms++; 

    if($submittedForms == $subFormsCount){ 
    $('.dialog').show(); 
    } 
    } 
}) 
+0

哪里应该放对话框代码?如果在ajax.done中检查,那么如果有0个子表单,我仍然希望看到对话框? – monknom

+0

@monknom我不确定你在问什么。我以为你想在子表单提交时显示图像,只有在完成后才显示对话框? – Lewis

+0

对不起,我的英语不好,图像是提交子表单。但对话框我想告诉人们整个表单已经提交了不仅子表格 – monknom

0

我假设你有9个子窗体和1个主窗体。 8个子窗体的代码将相同。

我在这里使用async:false:意味着下一个ajax将不会被调用,直到第一个未完成。

示例代码格式:

var id = 5; 
$.ajax({ 
    url: , 
    type: 'POST', 
    data: {'id':id}, 
    dataType: 'JSON', 
    async: false, 
    error : function(xhr, textStatus, errorThrown) { 
     alert('An error occurred!'); 
    }, 
    success : function(response){ 

    } 
}); 

在你的最后一个子窗体只需设置变量是第九子窗体。

success : function(response){ 
     var counter = true; 
    } 

if(counter){ 
    /* Code to show dialog.*/ 
} 
0

您可以使用$.when等待每个请求完成。像这样的东西应该让你接近。你基本上想要将所有的ajax请求存储在一个数组中,并将其作为参数传递给when

$('#main').on('click', '.subform_submit', function() { 

    var formRequests = $('.subform').map(function() { 
    var $form = $(this); 
    return $.ajax({ 
     url: '', 
     data: $form.serialzeArray() 
    }); 
    }).get(); 

    $.when.apply(undefined, formRequests).done(function() { 
    console.log('All done!'); 
    }); 

}); 

这里去一个非常类似的小演示中,我只是做了:https://jsfiddle.net/g9a06y4t/