2010-05-14 42 views
5

Tôi sử dụng jquery's .submit() để chặn sự kiện gửi của người dùng, tuy nhiên tôi đã tìm thấy sự cố.Sử dụng jquery để ngăn gửi lại biểu mẫu

Khi người dùng nhấp vào nút gửi, biểu mẫu được gửi bình thường, nhưng nếu người dùng cố tình nhấp nhanh nhiều lần, nó sẽ gửi nhiều lần, điều này sẽ gây ra dữ liệu trùng lặp trong cơ sở dữ liệu.

Giải pháp cho loại sự cố này là gì?

Cập nhật: Vâng, tôi thấy một số lời khuyên cho biết vô hiệu hóa nút gửi. Điều này sẽ ngăn chặn biểu mẫu được gửi nhiều lần, nhưng vấn đề là phần tử biểu mẫu trong trang của tôi không được làm mới, nếu tôi tắt nó, người dùng sẽ không thể gửi biểu mẫu đó nữa, vô hiệu hóa biểu mẫu trong 15 giây có thể hoạt động, nhưng điều này đúng cách để giải quyết vấn đề này?

+0

bạn đang sử dụng ajax để gửi biểu mẫu ... nguyên nhân vô hiệu hóa là tốt nếu không muốn nói ajax ... – Reigel

+0

Vâng, tôi đang sử dụng tải jquery của. khi người dùng gửi biểu mẫu, có tăng một hàng trong bảng. – Sawyer

+0

nhìn vào câu trả lời của tôi một lần nữa nếu nó giúp ... – Reigel

Trả lời

7

Vô hiệu hóa nút gửi thực sự là con đường để đi.

Tuy nhiên, trong nhiều trường hợp, logic bên máy chủ được thực hiện tùy thuộc vào sự hiện diện của cặp tên-giá trị của nút gửi được đề cập trong bản đồ tham số yêu cầu. Đặc biệt trong các khung công tác MVC dựa trên thành phần phía máy chủ như MS ASP.NET và Sun JSF, nhưng cũng ở dạng "đơn giản" có nhiều hơn một nút gửi. Cặp tên-giá trị của nút gửi nhấn là bắt buộc để xác định hành động được thực hiện. Vô hiệu hóa nút sẽ làm cho cặp giá trị tên của nó biến mất hoàn toàn trong bản đồ tham số yêu cầu và phía máy chủ có thể không thực hiện bất kỳ hành động nào hoặc thực hiện hành động sai.

Về cơ bản có 2 cách để đi xung quanh này:

  1. Sử dụng setTimeout() để vô hiệu hóa các nút sau một vài mili giây để cặp tên-giá trị của nó được gửi anyway. 50ms là một số tiền phải chăng.

    $("form").submit(function() { 
        var form = this; 
        setTimeout(function() { 
         $(':submit', form).attr('disabled', true); 
        }, 50); 
    }); 
    
  2. Sao chép cặp giá trị tên của nút gửi thực sự vào đầu vào ẩn của biểu mẫu. Điều này phức tạp hơn một chút vì thông tin này không có sẵn trong sự kiện submit của <form>. Bạn cần phải cho phép $(document) nắm bắt phần tử được nhấp cuối cùng.

    $("form").submit(function() { 
        $(':submit', this).attr('disabled', true); 
        $(this).append($('<input/>').attr({ 
         type: 'hidden', 
         name: $.lastClicked.name, 
         value: $.lastClicked.value 
        })); 
    }); 
    
    $(document).click(function(e) { 
        e = e || event; 
        $.lastClicked = e.target || e.srcElement; 
    }); 
    

Cập nhật: theo cập nhật của bạn:

Vâng, tôi thấy một số lời khuyên cho biết việc vô hiệu hóa nút gửi. Điều này sẽ ngăn không cho gửi nhiều lần, nhưng vấn đề là phần tử biểu mẫu trong trang của tôi không được làm mới, nếu tôi vô hiệu hóa nó, người dùng sẽ không thể gửi nó nữa, vô hiệu hóa nó trong 15 giây có thể hoạt động, nhưng đây có phải là đúng cách để giải quyết vấn đề này?

Vì vậy, bạn thực sự đang gửi yêu cầu ajaxical. Bạn chỉ có thể kích hoạt lại (các) nút trong trình xử lý gọi lại của hàm ajax của jQuery. Giả sử bạn đang sử dụng jQuery.post:

$("form").submit(function() { 
    // Disable buttons here whatever way you want. 

    var form = this; 
    $.post('some/url', function(data) { 
     // Re-enable buttons at end of the callback handler. 
     $(':submit', form).attr('disabled', false); 
    }); 
}); 
1

thử vô hiệu hoá nút gửi vào mẫu nộp ....

$("form").submit(function() { 
    $(':submit',this).attr('disabled','disabled'); 
    $('selector').load(url,function(){ 
     $(':submit',this).removeAttr('disabled'); 
    }) 
});​ 

quick demo

+0

Cảm ơn người đàn ông, hãy xem cập nhật của tôi! – Sawyer

+0

"url" là gì? Ngoài ra, đừng quên rằng nhấn Enter sẽ gửi biểu mẫu. – nickf

+0

@nickf - bạn có muốn hỏi tôi quá '$ ('selector')'? ... OP không cung cấp nhiều mã (chỉ là '.submit()') ... vì vậy tôi đã giả định. .. có nhấn enter cũng sẽ gửi nếu một hộp văn bản là trong tập trung và bạn nhấn enter ... nhưng sau đó một lần nữa, nó sẽ phụ thuộc vào mã OP ... – Reigel

0

Vấn đề thực sự nằm ở lớp cơ sở dữ liệu phải được thiết kế để ngăn trùng lặp. đây là giải pháp phổ biến nhưng hơi xấu xí:

Khi ban đầu bạn hiển thị một trang, bạn có thể tạo GUID. Nói, ID hoạt động. và đặt nó vào một quang cảnh. Khi bạn xử lý một sự kiện trên phía máy chủ chỉ cần chèn guid này trong một bảng, nói OngoingOperations nơi nó là một khóa chính. Việc chèn đầu tiên sẽ thành công, khác sẽ thất bại. Của cource, để được nhiều người dùng thân thiện, bạn chỉ có thể bỏ qua các hoạt động tiếp theo và trở về tình trạng của một trong những đầu tiên.

Bảng OngoingOperations có thể trông như sau:

CREATE TABLE OngoingOperations ( OperationID uniqueidentifier khóa chính, OperationDate datetime mặc định getdate(), OperationStatus nvarchar (max) );

OperationStatus - là thông báo trạng thái hoặc bất kỳ dữ liệu nào để trả lại cho khách hàng từ lần gửi tiếp theo. Ở đây bạn có thể sử dụng cờ (ok hoặc không) hoặc tin nhắn chi tiết - như bạn muốn.

bảng này yêu cầu thu thập các hồ sơ cũ, giả sử mỗi giờ bạn chỉ xóa các hoạt động đã hoàn tất từ ​​2 giờ trở lên trước đó.

Anton Burtsev

0

Hãy thử điều này:

$("form").submit(function() { 
    var form = this; 
    setTimeout(function() { 
     $(':submit', form).attr('disabled', true); 
    }, 50); 

    setTimeout(function() { 
     $(':submit', form).removeAttr('disabled'); 
    }, 1000); 
}); 
Các vấn đề liên quan