2010-02-18 76 views
8

Tiếp theo từ ap revious question nơi tôi được hỏi về việc vô hiệu hóa một nút gửi đến khi tất cả các cuộc gọi ajax đã hoàn thành việc quay trở lại ...Làm cách nào để ngăn chặn việc gửi biểu mẫu cho đến khi nhiều cuộc gọi ajax kết thúc? jquery

Dường như mọi người vẫn đang quản lý để gửi biểu mẫu ngay cả với các nút bị vô hiệu và một dấu hiệu cảnh báo . Tôi đoán nó có thể là từ nhấn 'enter' trong một đầu vào văn bản.

Tôi làm cách nào để vô hiệu hóa toàn bộ biểu mẫu chứ không phải chỉ là nút gửi?

Mã này cho đến nay là:

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

Một điều khác mà tôi nên đề cập đến mà có thể gây ra một vấn đề là có rất nhiều ajax gọi xảy ra cùng một lúc, EG một div nhận đầu vào ẩn và div khác ở đâu đó trên trang hiển thị tổng giá.

Thực tế là một số cuộc gọi ajax đang hoàn thành nhanh chóng phủ nhận hiệu ứng vô hiệu hóa của ajaxStart? EG ajax call1 và ajax call2 đều kích hoạt ajaxStart - call1 kết thúc thực sự nhanh chóng, nó sẽ kích hoạt lại biểu mẫu trong khi chúng ta đang đợi call2 hoàn thành?

Có cách nào tốt hơn để làm điều này, nơi chúng tôi có thể chỉ đơn giản là kiểm tra nếu tất cả các cuộc gọi ajax đã hoàn thành?

Trả lời

2

Bạn có thể thêm trình xử lý sự kiện cho sự kiện gửi biểu mẫu. Trình xử lý sự kiện có thể kiểm tra xem việc gửi có được phép hay không và hủy bỏ nếu không. Dưới đây là một số tài liệu: http://api.jquery.com/submit/

Lưu ý rằng nếu javascript trên trang gọi .click() trên một trong các nút gửi biểu mẫu, biểu mẫu sẽ được gửi mà không cần gọi trình xử lý .submit() của bạn. Đây là một vấn đề jQuery lạ (http://groups.google.com/group/jquery-en/browse_thread/thread/1317bfd4e3a8b233?pli=1) mà tôi đoán các folks jQuery không xem xét một lỗi. Có thể có những trường hợp như thế này, tôi hy vọng là không.

Nếu bạn đang sử dụng ASP.NET, tùy thuộc vào những gì trên biểu mẫu, ASP.NET có thể tiêm hàm "__doPostBack". Bạn có thể cần phải móc hàm đó thay vì xác định lại nó bằng một số mã tùy chỉnh gọi là bản gốc.

+0

Điều này nghe theo dòng bên phải, từ hướng dẫn: $ ("biểu mẫu"). Submit (function() { if ($ ("input: first"). Val() == "correct") Văn bản { $ ("span"). ("Đã xác thực ..."). Hiển thị(); trả về true; } $ ("span"). Văn bản ("Không hợp lệ!"). Hiển thị(). fadeOut (1000); trả về false; }); Vì vậy, nếu tôi kiểm tra xem tất cả các cuộc gọi ajax đã hoàn thành, tôi có thể trả về true. Tôi đang sử dụng PHP nên không thể sử dụng các chức năng ASP. – Ashley

+0

PS Bất cứ ai cũng có thể cho tôi biết làm thế nào để chèn mã định dạng vào một bình luận, tôi luôn luôn có vẻ để có được tất cả mọi thứ squished vào một dòng – Ashley

+0

Tôi không nghĩ rằng bạn có thể định dạng mã trong ý kiến. Tôi sẽ tiếp tục và mở rộng câu hỏi của bạn với các nhận xét bổ sung. –

0

Làm thế nào về việc tạo một biến toàn cầu:

var i = 0; 

và gia cuộc gọi mỗi AJAX biến này vào lúc bắt đầu của cuộc gọi và decrements nó khi hoàn tất.

Khi gửi biểu mẫu, hãy kiểm tra xem biến này có lớn hơn 0 và không cho phép gửi.

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

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

</form> 
+0

Điều này nghe khá linh hoạt. Tại đó các điểm trong cuộc gọi ajax làm chúng ta tăng/giảm. Là tăng ngay sau khi $ .ajax ({ – Ashley

+0

Tôi sẽ tưởng tượng rằng bạn tăng vào lúc bắt đầu của hàm ajaxStart và giảm ở đầu hàm ajaxComplete –

+0

điều này có vẻ như một ý tưởng hay, nhưng khi tôi thử nó, tất cả 3 ajax Các cuộc gọi bắt đầu đồng thời và bộ đếm nhận được giá trị 1. Sau đó, khi chúng hoàn thành vào các thời điểm khác nhau, bộ đếm sẽ chuyển sang -2. – Ashley

1

Bạn chỉ có thể đặt đối tượng JS có nhiều thuộc tính cho mỗi cuộc gọi ajax. Ví dụ:

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

Trên biểu mẫu gửi vòng qua từng thuộc tính để kiểm tra xem có đúng không. Nếu có sai thì không nộp mẫu.

Khi mỗi cuộc gọi ajax hoàn tất đặt thuộc tính của nó (call1, call2, v.v.) thành true.

Thats một cách bạn có thể làm điều đó, cho dù đó là cách tốt nhất, tôi không biết.

+0

Điều này nghe có vẻ giống như một ý tưởng hay, tuy nhiên có một số cuộc gọi khác nhau có thể được thực hiện trên trang này, không phải tất cả chúng đều được kích hoạt bởi mỗi khách hàng.Tôi sẽ có một suy nghĩ – Ashley

+0

trong trường hợp đó, nếu tôi hiểu bạn một cách chính xác, bạn sẽ đặt giá trị mặc định của chúng thành true.Khi cuộc gọi ajax được kích hoạt, bạn sẽ đặt thuộc tính của nó trong requiredCalls thành false và oncomplete/onsuccess bạn sẽ đặt nó trở lại true. – Mark

0

Tôi đoán bạn có một số mã như thế này:

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

bạn có thể làm điều đó:

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

Tôi đã gần như giải quyết điều này, nhưng bằng cách nào đó mọi người dường như vẫn có thể gửi biểu mẫu trước khi các cuộc gọi lại kết thúc.

Tôi không biết nếu đó là trùng hợp ngẫu nhiên nhưng tất cả những người đã quản lý để gửi nó đã sử dụng Safari trên máy Mac.

Đây là phương pháp tôi đang sử dụng, sẽ tuyệt vời nếu bất cứ ai có thể phát hiện lỗ hổng trong logic.

Sử dụng gợi ý Vincent:

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

sau đó khi tôi làm một cuộc gọi ajax ví dụ:

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

này đang làm việc tốt, tôi cũng có một kịch bản ít tốt đẹp để đưa ra phản hồi người dùng - nút chuyển sang màu xám trong khi chờ đợi ajaxcounters trở lại và nếu nó mất nhiều hơn 250ms, một hoạt ảnh cũng được hiển thị. Một khi tất cả các cuộc gọi ajax đã hoàn thành, truy cập được trở về zero và nút được hiển thị như bình thường:

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

Cuối cùng, chúng ta đến với các chức năng mà nên ngăn chặn nộp, nhưng dường như không có tác dụng :

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

Ai có thể nhận ra những gì tôi đã làm sai ở đây?

Cảm ơn!

Các vấn đề liên quan