2016-05-23 3 views
0

Я знаю, что эта проблема была решена уже много раз, однако я не могу получить мое исправление на основе предоставленных решений.MVC - проверка jQuery не работает с динамически добавленными элементами

Я создаю приложение для простой библиотеки. Существует функция добавления копии книги, в которой jQuery используется для вызова действий контроллера и возврата частичных представлений, которые затем динамически добавляются в DOM.

Последний добавленный динамический элемент - это форма с дополнительной информацией о созданной копии. Вызов ajax запускается, когда изменяется значение DropDownList (#AuthorBooksDropDown) (также добавляется динамически).

$('#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'); вызывается, когда форма оказывается (проверено в хром Дев инструментов), проверка по-прежнему происходит на стороне сервера при нажатии на кнопку отправки в действие POST в настоящее время срабатывает каждый раз. Не говоря уже о том, что ошибки проверки не отображаются в TABing в следующем поле.

атрибутов Validation есть в форме входа в:

enter image description here

У меня также есть дистанционные проверки, который проверяет, является ли введен ISBN уже в базе данных. Очевидно, это работает на стороне клиента, что в моем случае просто нет.

Благодарим вас за внимание и помощь.

EDIT:

Ну, я добавил следующее в конце представления:

<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

Спасибо, сэр, он решил проблему. Не могли бы вы рассказать мне, почему добавление '$ .validator.unobtrusive.parse ('# addCopyForm');' после закрытия скобок '$ .get (...)' не сработало? Почему он называется раньше, хотя он помещен «после» вызова? – 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

Смежные вопросы