2016-05-23 41 views
0

我知道这种问题已经解决了很多次,但是我无法根据提供的解决方案获得我的固定。MVC - jQuery验证不适用于动态添加的元素

我正在构建一个简单的库应用程序。有一个功能可以添加一本书的副本,该书使用jQuery来调用控制器操作并返回部分视图,然后将动态添加到DOM中。

添加的最后一个动态元素是一个表单,其中包含创建副本的其他详细信息。当DropDownList#AuthorBooksDropDown)(也是动态添加的)值发生更改时,将触发ajax调用。

$('#authorBooksPlaceHolder').on('change', '#AuthorBooksDropDown', function() { 

    var bookId = $(this).val(); 

    $.get('/Books/AddCopy_RenderDetails/' + bookId, function (data) { 

     $('#bookDetailsPlaceHolder').html(data); 
     $('#bookDetailsPlaceHolder').slideDown(); 
    }); 

    $.validator.unobtrusive.parse('#addCopyForm'); 
}); 

的调用来调用AddCopy_RenderDetails行动基于本书id从数据库得到一个实体,并创建填充某些领域的新副本。

控制器动作:

public PartialViewResult AddCopy_RenderDetails(int id) 
     { 
      var book = db.LibraryBooks.Find(id); 

      var newCopy = new Book() 
      { 
       Author = book.Author, 
       Title = book.Title, 
       Publisher = book.Publisher, 
       CollectionId = book.CollectionId, 
       Collection = book.Collection 
      }; 

      return PartialView("_AddCopy_Details", newCopy); 
     } 

剩余需要被填充的字段中的视图显示。

@model CityLibrary.Models.Library.Book 

<div class="vertical-separator"></div> 

<hr /> 

@using (Ajax.BeginForm("AddCopy", "Books", new AjaxOptions 
{ 
    UpdateTargetId = "bookDetailsPlaceHolder" 
}, new { @id = "addCopyForm" })) 
{ 
    @Html.AntiForgeryToken() 

    @Html.HiddenFor(model => model.Author) 
    @Html.HiddenFor(model => model.Title) 
    @Html.HiddenFor(model => model.CollectionId) 
    @Html.HiddenFor(model => model.Collection.Name) 
    @Html.HiddenFor(model => model.Publisher) 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Collection.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Collection.Name, new { htmlAttributes = new { @class = "form-control", @disabled = "" } }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.ISBN, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.ISBN, new { htmlAttributes = new { @class = "form-control", } }) 
      @Html.ValidationMessageFor(model => model.ISBN, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Publisher, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Publisher, new { htmlAttributes = new { @class = "form-control", @disabled = "disabled" } }) 
      @Html.ValidationMessageFor(model => model.Publisher, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.YearPrinted, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.YearPrinted, new { htmlAttributes = new { @class = "form-control", @Value = "" } }) 
      @Html.ValidationMessageFor(model => model.YearPrinted, "", new { @class = "text-danger" }) 
     </div> 
    </div> 


    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Save" class="btn btn-success btn-block" /> 
     </div> 
    </div> 
} 

即使我有$.validator.unobtrusive.parse('#addCopyForm');时的形式呈现(在Chrome浏览器开发工具选中),确认仍然在服务器端在按压提交按钮作为POST操作被触发,每次发生调用。更不用说验证错误不会显示在下一个字段的TAB中。

验证属性是有形式的输入:

enter image description here

我也有一个检查输入ISBN是否已经在数据库的远程验证。很显然,这在客户端运行,在我的情况下根本没有。

谢谢你的时间和帮助。

编辑:

嗯,我已经添加了以下到视图的末尾:

<script> 
    $.validator.unobtrusive.parse('#addCopyForm'); 
</script> 

和它的作品。我不知道为什么在一个函数上触发它什么都不做。

+0

只是一个提醒这个和平,检查是否#authorBooksPlaceHolder已经存在的观点,而不是动态填充。 – Shashi

+0

谢谢你的回答。 '#authorBooksPlaceHolder'是一个静态div,最初使用'display:none'。 – Dandry

回答

1

Ajax是异步的,并且您的$.validator.unobtrusive.parse('#addCopyForm');代码行在HTML添加到DOM之前被调用。它移动到success回调

$.get('/Books/AddCopy_RenderDetails/' + bookId, function (data) { 
    $('#bookDetailsPlaceHolder').html(data); 
    $('#bookDetailsPlaceHolder').slideDown(); 
    $.validator.unobtrusive.parse('#addCopyForm'); 
}); 
+0

谢谢先生,它解决了这个问题。你能告诉我为什么在'$ .get(...)'的右括号之后加上'$ .validator.unobtrusive.parse('#addCopyForm');'不起作用吗?为什么它之前被调用,即使它被放置在'通话'之后? – Dandry

+1

Ajax是异步的。这意味着在代码的其余部分继续执行时运行它,所以在'$ .get()'方法有机会从控制器获取部分视图之前,'$ .validator.unobtrusive.parse( '#addCopyForm');'命中一行代码(但是这个时候还没有添加html)。 –

+0

非常感谢! – Dandry

1

内尝试的代码

$("form").on("submit", function (e) { 
      e.preventDefault(); 
      $.validator.unobtrusive.parse($('#addCopyForm')); // here you need define your form id 
      if ($(this).valid()) // use to validate the form 
        { 
       //do ajax call 
       $.ajax({ 
        type: "Post", 
        url: "/Books/AddCopy_RenderDetails/" + bookId, 
        contentType: "application/json; charset=utf-8",       
        dataType: "json", 
        success: function (data) {       
        } 
       }); 
      } 
     }); 
+0

谢谢,但我使用'Ajax.BeginForm'节省了我插入所有这些代码。无论如何,这是完成它的另一种方式。 – Dandry