5

Vì vậy, tôi có một cái nhìn với cơ cấu như sau (đây không phải là mã thực tế, nhưng một bản tóm tắt):MVC Client-Side Validation cho EditorFor trong foreach

@using (Html.BeginForm("Action", "Controller", FormMethod.Post)) 
{ 
    @Html.ValidationSummary("", new { @class = "text-danger" }) 
    <table> 
    <thead> 
     <tr> 
     <th>Column1</th> 
     <th>Column2</th> 
     </tr> 
    </thead> 
    <tbody id="myTableBody"> 
     @for (int i = 0; i < Model.Components.Count; i++) 
     { 
     @Html.EditorFor(m => m.MyCollection[i]) 
     } 
    </tbody> 
    <tfoot> 
     <tr> 
     <td> 
      <button id="btnAddRow" type="button">MyButton</button> 
     </td> 
     </tr> 
    </tfoot> 
    </table> 

    <input type="button" id="btnSubmit" /> 
} 

@section scripts { 
    @Scripts.Render("~/Scripts/MyJs.js") 
} 

Các EditorFor được render đánh dấu rằng đại diện cho các hàng được liên kết với các thuộc tính trong MyCollection. Dưới đây là một đoạn mẫu về cách template editor trông:

@model MyProject.Models.MyCollectionClass 
 

 
<tr> 
 
    <td> 
 
    @Html.TextBoxFor(m => m.Name) 
 
    </td> 
 
    <td> 
 
    @Html.DropDownListFor(m => m.Type, Model.AvailableTypes) 
 
    </td> 
 
</tr>

Về cơ bản, vấn đề của tôi là xác nhận client-side sẽ không kích hoạt cho các yếu tố bên trong của mẫu biên tập như mong muốn . Ai đó có thể chỉ cho tôi đi đúng hướng, nơi tôi có thể đi sai với điều này.

Ngoài ra, xin lưu ý rằng những điều sau được đặt trong web.config của tôi.

<appSettings> 
    <add key="ClientValidationEnabled" value="true" /> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 
</appSettings> 

và MyCollectionClass có đúng [Require] chú thích về thuộc tính sẽ được thi hành. Một điều cần lưu ý là kiểm tra

if(ModelState.IsValid) 
{ 
} 

Trả về false, như mong đợi, nếu các trường bắt buộc không đúng. Vấn đề ở đây là tôi muốn xác thực phía máy khách và không phải phía máy chủ. Một trong những trang khác của tôi đang thực hiện xác nhận hợp lệ jQuery, nhưng không chứa tất cả các lồng nhau mà kịch bản này làm và do đó nó hoạt động chính xác.

Xin cảm ơn trước.

+0

Bạn có thêm tập lệnh xác thực không phô trương không? Tôi có thể xem các tập lệnh được bao gồm trong trang của bạn không? – Giu

+3

Xóa vòng lặp 'for' - nó chỉ cần là' @ Html.EditorFor (m => m.MyCollection) '- phương thức' EditorFor() 'chấp nhận' IEnumerable 'và đủ thông minh để hiển thị đúng html cho mỗi mục trong bộ sưu tập. Nhưng mã của bạn không có ý nghĩa vì vòng lặp 'for' là thuộc tính' Thành phần' không phải là thuộc tính 'MyCollection' (là một lỗi đánh máy?) –

+3

Trong mọi trường hợp, bạn nên bao gồm' @ Html.ValidationMessageFor() 'cho mỗi thuộc tính trong 'EditorTemplate' rất rõ ràng đối với người dùng mà hàng có lỗi (và tóm tắt sau đó phải là' @ Html.ValidationSummary (true, "", new {@class = "text-danger"}) ') –

Trả lời

1

Từ những gì tôi đã học MVC Không thực sự cung cấp tính năng xác thực phía khách hàng 'ngoài hộp'. có các tùy chọn của bên thứ ba nhưng tôi thích làm việc của riêng tôi vì vậy tôi đã ném toàn bộ nội dung trong JavaScript. Để ghép các vấn đề với EditorFor, không cho phép thêm các thuộc tính html như các phương thức trợ giúp khác.

Fix My cho điều này là khá phức tạp nhưng tôi cảm thấy toàn diện, tôi hy vọng bạn tìm thấy nó là hữu ích như tôi có

Đầu tiên quá tải các HtmlHelper EditorFor trong Net

public static HtmlString EditBlockFor<T, TValue>(this HtmlHelper<T> helper, Expression<System.Func<T, TValue>> prop, bool required) 
    { 
     string Block = ""; 
     Block += "<div class='UKWctl UKWEditBox' " + 
      "data-oldvalue='" + helper.ValueFor(prop) + "' " + 
      "data-required='" + required.ToString() + ">"; 
     Block += helper.EditorFor(prop); 
     Block += "</div>"; 

     return new HtmlString(Block); 
    } 

thêm editBlockfor mới trong chế độ xem dao cạo (giống như bạn) nhưng thay đổi phương thức Biểu mẫu Bắt đầu để thêm Tên và id vào phần tử biểu mẫu để bạn có thể xác định nó sau

@using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { name = "MyDataForm", id = "MyDataForm" })) 

Sau đó, khi Người dùng Nhấp chuột vào Lưu, Chạy phương pháp xác nhận từ hoạt Javascript

function validate(container) { 

    var valid = true; 
    //use jquery to iterate your overloaded editors controls fist and clear any old validation 
    $(container).find(".UKWctl").each(function (index) { clearValidation($(this)); }); 
    //then itterate Specific validation requirements 
    $(container).find(".UKWctl[data-required='True']").each(function (index) { 
     var editobj = getUKWEdit(this); 
     if (editobj.val() == "") { 
      valid = false; 
      //use this Method to actually add the errors to the element 
      AddValidationError(editobj, 'This field, is required'); 
      //now add the Handlers to the element to show or hide the valdation popup 
      $(editobj).on('mouseenter', function (evt) { showvalidationContext(editobj, evt); }); 
      $(editobj).on('mouseout', function() { hidevalidationContext(); }); 
      //finally add a new class to the element so that extra styling can be added to indicate an issue 
     $(editobj).addClass('valerror'); 
    } 
    }); 
    //return the result so the methods can be used as a bool 
    return valid; 
} 

Thêm Validation Phương pháp

function AddValidationError(element, error) { 
    //first check to see if we have a validation attribute using jQuery 
    var errorList = $(element).attr('data-validationerror'); 
    //If not Create a new Array() 
    if (!errorList || errorList.length < 1) { 
     errorList = new Array(); 
    } else { 
     //if we have, parse the Data from Json 
     var tmpobj = jQuery.parseJSON(errorList); 
     //use jquery.Map to convert it to an Array() 
     errorList = $.map(tmpobj, function (el) { return el; }); 
    } 
    if ($.inArray(error, errorList) < 0) { 
     // no point in add the same Error twice (just in case) 
     errorList.push(error); 
    } 
    //then stringyfy the data backl to JSON and add it to a Data attribute  on your element using jQuery 
    $(element).attr('data-validationerror', JSON.stringify(errorList)); 
} 

Cuối cùng Hiển thị và ẩn các lỗi thực tế, Để tạo điều kiện này một cách dễ dàng tôi trượt trong một phần tử div ít đến _Bố trí.html

<div id="ValidataionErrors" title="" style="display:none"> 
     <h3 class="error">Validation Error</h3> 
     <p>This item contatins a validation Error and Preventing Saving</p> 
     <p class="validationp"></p> 
    </div> 

Hiện

var tipdelay; 
function showvalidationContext(sender, evt) 
{ 
    //return if for what ever reason the validationError is missing 
    if ($(sender).attr('data-validationerror') == "") return; 
    //Parse the Error to an Object 
    var jsonErrors = jQuery.parseJSON($(sender).attr('data-validationerror')); 
    var errorString = ''; 
//itterate the Errors from the List and build an 'ErrorString' 
    for (var i = 0; i <= jsonErrors.length; i++) 
    { 
     if (jsonErrors[i]) { 
      //if we already have some data slip in a line break 
      if (errorString.length > 0) { errorString += '<br>'; } 
      errorString += jsonErrors[i]; 
     } 
    } 
//we don't want to trigger the tip immediatly so delay it for just a moment 
    tipdelay = setTimeout(function() { 
     //find the p tag tip if the tip element 
     var validationError = $('#ValidataionErrors').find('.validationp'); 
     //then set the html to the ErrorString 
     $(validationError).html(errorString); 
     //finally actually show the tip using jQuery, you can use the  evt to find the mouse position 
     $('#ValidataionErrors').css('top', evt.clientY); 
     $('#ValidataionErrors').css('left', evt.clientX); 
     //make sure that the tip appears over everything 
     $('#ValidataionErrors').css('z-index', '1000'); 
     $('#ValidataionErrors').show(); 
    }, 500); 
}  

Hide (nó dễ dàng hơn để che giấu)

function hidevalidationContext() { 
    //clear out the tipdelay 
    clearTimeout(tipdelay); 
    //use jquery to hide the popup 
    $('#ValidataionErrors').css('top', '-1000000px'); 
    $('#ValidataionErrors').css('left', '-1000000px'); 
    $('#ValidataionErrors').css('z-index', '-1000'); 
    $('#ValidataionErrors').hide(); 
} 

để sử dụng bạn có thể thử một số điều như

function save() 
{ 
    if (validate($("#MyDataForm"))) 
    { 
     $("#MyDataForm").submit(); 
    } 
    else { 
     //all the leg has been done this stage so perhaps do nothing 
    } 
} 

đây là Css My để xác thực Popup

#ValidataionErrors { 
    display: block; 
    height: auto; 
    width: 300px; 
    background-color: white; 
    border: 1px solid black; 
    position: absolute; 
    text-align: center; 
    font-size: 10px; 
} 

#ValidataionErrors h3 { border: 2px solid red; } 
.valerror { box-shadow: 0 0 2px 1px red; } 
Các vấn đề liên quan