38

Tôi đang xác thực biểu mẫu bằng các tính năng xác thực không phô trương mới trong ASP.NET MVC 3.Làm thế nào để thêm một chức năng 'submitHandler' khi sử dụng jQuery Unobtrusive Validation?

Vì vậy, không có mã nào tôi đã viết để thiết lập jQuery xác thực để bắt đầu xác thực biểu mẫu của tôi. Tất cả được thực hiện bằng cách tải thư viện jQuery.validate.unobtrusive.js.

Thật không may, tôi cần phải nhấn mạnh trong 'bạn có chắc không?' hộp thông báo khi biểu mẫu hợp lệ nhưng trước khi gửi. Với jQuery xác nhận bạn sẽ thêm tùy chọn handleSubmit khi khởi tạo như vậy:

$("#my_form").validate({ 
    rules: { 
    field1: "required", 
    field1: {email: true }, 
    field2: "required" 
    }, 
    submitHandler: function(form) { 
    if(confirm('Are you sure?')) { 
     form.submit(); 
    } 
    } 
}); 

Nhưng bạn không cần khởi tạo khi sử dụng thư viện không phô trương.

Bất kỳ ý tưởng nào/cách tôi có thể thêm trình xử lý gửi trong trường hợp đó?

Thx

+0

bất kỳ ai: có tài liệu chính thức nào về điều này từ MS không? –

+0

lưu ý: 'handleSubmit()' chỉ được gọi nếu tất cả các giá trị biểu mẫu xác thực. Nó không được gọi nếu bạn có bất kỳ lỗi nào. Nó hoàn hảo để yêu cầu xác nhận như bạn (vì bạn biết mọi thứ hợp lệ) nhưng nếu bạn muốn xử lý đặc biệt khi có lỗi bạn phải sử dụng 'invalidHandler' - xem câu trả lời của DGreen –

+0

Thay vì đợi cho đến khi nó được khởi tạo, bạn cũng có thể gọi ['jQuery.validator.setDefaults'] (https://jqueryvalidation.org/jQuery.validator.setDefaults/) trực tiếp và bất kỳ intializations biểu mẫu tiếp theo nào sẽ sử dụng các cài đặt đó. Chỉ cần chắc chắn rằng nó chạy trước khi DOM được nạp và jQuery Validator sẽ tự động khởi tạo các biểu mẫu. – KyleMit

Trả lời

62

Thư viện không phô trương sẽ đính kèm các validator trên mọi hình thức, vì vậy bạn phải thay thế submitHandler theo cách này:

$("form").data("validator").settings.submitHandler = function (form) { alert('submit'); form.submit(); }; 
+2

Cảm ơn @petrhaus - câu trả lời đơn giản tốt đẹp mà cũng đã làm tăng sự hiểu biết của tôi về jQuery. – WooWaaBob

+4

Đối với các biểu mẫu được nạp động (ví dụ: hộp thoại), trước tiên bạn phải gọi $ .validator.unobtrusive.parse ($ ('form')) hoặc $ ('form'). Dữ liệu sẽ trả về không xác định. – parliament

+0

Bực bội một phần về điều này là tôi đã bị mắc kẹt cố gắng tìm ra những gì đã xảy ra sai vì nếu người nộp đơn được đặt trong các thẻ

59

Tôi thấy câu hỏi này trong khi tìm kiếm một cách để thiết lập invalidHandler , trái ngược với submitHandler. Thật thú vị, bạn không thể đặt invalidHandler theo cách tương tự khi sử dụng tính năng xác thực không phô trương.

Chức năng không được kích hoạt khi một hình thức không hợp lệ được phát hiện:

$("form").data("validator").settings.invalidHandler = function (form, validator) { 
    alert('invalid!'); 
}; 

Cách tiếp cận này hoạt động:

$("form").bind("invalid-form.validate", function() { 
    alert('invalid!'); 
}); 

Nó có vẻ là do cách mà jquery.validate.unobtrusive .js tập lệnh khởi tạo Xác thực plugin và cách plugin yêu cầu trình xử lý.

+0

Lưu ý: cách tiếp cận 'liên kết' ở đây theo nghĩa đen là chính xác cách hàm jquery.validate init thực hiện –

+0

giúp, ai có thể giúp giải thích? nó có vẻ không phải là một cách 'chính thức', làm thế nào nếu tôi muốn định nghĩa submitHandler? – Elaine

+0

Tôi đã thử tất cả các điều trên để xử lý 'invalidHandler' nảy ra một' cảnh báo', nhưng nó không bật lên. Và '$ ('form'). Data ('validator')' trả về 'undefined'. – Shimmy

10

Tôi thích tiêm một event handler, vì vậy nó có thể được liên kết với ... :)

//somewhere in your global scripts 
$("form").data("validator").settings.submitHandler = function (form) { 
    var ret = $(form).trigger('before-submit'); 
    if (ret !== false) form.submit(); 
};

Bằng cách này, tôi có thể liên kết với nó bất cứ nơi nào cần thiết ...

//in your view script(s) 
$("form").bind("before-submit", function() { 
    return confirm("Are you sure?"); 
});
33

Những phát hiện sau đây có thể quan tâm đến hiểu sự khác biệt giữa:

submitHandler: Được gọi là khi biểu mẫu được xác nhận thành công - ngay trước khi postback máy chủ
invalidHandler: Được gọi là nếu xác nhận thất bại và không có bài đăng nào trở lại

@ Giải pháp của DGreen chắc chắn có vẻ là cách tốt nhất để tiêm xử lý đặc biệt nếu xác thực biểu mẫu không thành công và bạn cần phải làm điều gì đó chẳng hạn như hiển thị một bản tóm tắt xác nhận sổ pop-up (invalidHandler)

$("form").bind("invalid-form.validate", function() { 
    alert('invalid!'); 
}); 

giải pháp @PeteHaus là cách tốt nhất để làm điều gì đó nếu bạn muốn ngăn chặn postback của một hình thức xác nhận thành công (submitHandler)

$("form").data("validator").settings.submitHandler = function (form) { 
                alert('submit'); form.submit(); }; 

Tuy nhiên tôi đã hơi lo lắng về những gì hành vi của tôi đã được trọng (hoặc không trọng) bằng cách gắn vào các phương pháp .validate như thế này - và tại sao tôi phải làm mỗi cách khác nhau. Vì vậy, tôi đã kiểm tra nguồn. Tôi đặc biệt khuyên bất kỳ ai muốn hiểu quy trình này cũng làm như vậy nữa - hãy đặt trong một số câu lệnh 'cảnh báo' hoặc 'trình gỡ rối' và nó khá dễ dàng để theo dõi *

Dù sao nó chỉ ra rằng jquery.validate.unobtrusive xử lý khởi tạo jquery.validate plugin nó làm như vậy trong phương thức parseElement() bằng cách truy xuất các tùy chọn được tạo bởi phương thức validationInfo().

ValidationInfo() trả về các tùy chọn như thế này:

options: { // options structure passed to jQuery Validate's validate() method 
      errorClass: "input-validation-error", 
      errorElement: "span", 
      errorPlacement: $.proxy(onError, form), 
      invalidHandler: $.proxy(onErrors, form), 
      messages: {}, 
      rules: {}, 
      success: $.proxy(onSuccess, form) 
      }, 

Phương pháp onErrors() trong jquery.validate.unobtrusive có trách nhiệm tự động tạo ra các bảng tóm tắt xác nhận cho MVC. Nếu bạn không tạo bảng tóm tắt xác thực (với @Html.ValidationSummary() phải được chứa trong cơ thể MẪU) thì phương pháp này hoàn toàn trơ và không làm gì cả nên bạn không cần phải lo lắng.

function onErrors(event, validator) { // 'this' is the form elementz 
    var container = $(this).find("[data-valmsg-summary=true]"), 
     list = container.find("ul"); 

    if (list && list.length && validator.errorList.length) { 
     list.empty(); 
     container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 

     $.each(validator.errorList, function() { 
      $("<li />").html(this.message).appendTo(list); 
     }); 
    } 
} 

Nếu bạn thực sự muốn bạn có thể unbind handler jquery.validate.unobtrusive như thế này - nhưng tôi sẽ không làm phiền bản thân mình

$("form").unbind("invalid-form.validate"); // unbind default MS handler 

Nếu bạn đang tự hỏi tại sao các công trình này

$("form").data("validator").settings.submitHandler = ... 

và điều này không hoạt động

$("form").data("validator").settings.invalidHandler = ... 

bởi vì submitHandler được gọi là bên trong jquery.validate khi xác thực được thực hiện. Vì vậy nó không quan trọng vào thời điểm nó được thiết lập.

validator.settings.submitHandler.call(validator, validator.currentForm); 

nhưng invalidHandler là ràng buộc để một sự kiện trong init() như thế này vì vậy nếu bạn đặt nó trong mã của riêng bạn đó là quá muộn

if (this.settings.invalidHandler) 
    $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); 

Một bước nhỏ qua mã làm cho rất nhiều sự hiểu biết đôi khi! Hy vọng điều này sẽ giúp

* Đảm bảo bạn không bật tính năng làm tối thiểu các nhóm.

+4

Giải thích chi tiết của Simon đặc biệt so với câu trả lời mơ hồ của tôi :) – DGreen

+3

@DGreen Câu trả lời của tôi có xu hướng tỷ lệ thuận với số lượng đau và thời gian mà vấn đề đã gây ra cho tôi - nhưng không có câu trả lời của bạn sẽ lâu hơn rất nhiều 'd figured it out! –

+0

Tôi đã thử tất cả các điều trên để xử lý 'invalidHandler' nảy ra một' cảnh báo', nhưng nó không bật lên. Và '$ ('form'). Data ('validator')' trả về 'undefined'. – Shimmy

1

Tôi dựa trên câu trả lời gốc này, điều này không có tác dụng đối với tôi. Tôi đoán mọi thứ đã thay đổi trong jQuery.

Như thường lệ, lấy mã này và thêm kiểm tra lỗi dồi dào: D Tôi sử dụng mã tương tự để ngăn các đệ trình kép trên biểu mẫu của chúng tôi và nó hoạt động tốt trong IE8 + (như mvc4 và jquery 1.8.x).

$("#myFormId").confirmAfterValidation(); 

// placed outside of a $(function(){ scope 
jQuery.fn.confirmAfterValidation = function() { 
    // do error checking first. should be null if no handler already 
    $(this).data('validator').settings.submitHandler = confirmValidForm; 
}; 

function confirmValidForm(form) { 
    var validator = $(this); 
    var f = $(form); 
    if (confirm("really really submit?")) { 
     // unbind so our handler doesn't get called again, and submit 
     f.unbind('submit').submit(); 
    } 
     // return value is _ignored_ by jquery.validate, so we have to set 
     // the flag on the validator itself, but it should cancel the submit 
     // anyway if we have a submitHandler 
     validator.cancelSubmit = true; 
    } 
} 
Các vấn đề liên quan