MVC - jQuery验证不适用于动态添加的元素

时间:2016-05-23 12:57:54

标签: javascript jquery ajax asp.net-mvc validation

我知道这种问题已经解决了很多次,但是根据提供的解决方案我无法修复。

我正在构建一个简单的库应用程序。有一个功能可以添加一本书的副本,它使用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 dev工具中检查),但在按下提交按钮时,服务器端仍会进行验证,因为每次都会触发POST操作。更不用说在TABing到下一个字段时不会显示验证错误。

验证属性存在于表单的输入中:

enter image description here

我还有远程验证,用于检查输入的ISBN是否已存在于数据库中。显然这适用于客户端,在我的情况下根本就没有。

感谢您的时间和帮助。

修改

好吧,我在视图的末尾添加了以下内容:

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

它有效。我不知道为什么在函数上触发它什么都不做。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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) {                         
                    }
                });
            }
        });