2015-12-22 54 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/