2016-05-23 18 views
0

Ich weiß, dass diese Art von Problem bereits viele Male gelöst wurde, aber ich bin nicht in der Lage, meine basierend auf den bereitgestellten Lösungen zu beheben.MVC - jQuery-Validierung funktioniert nicht auf dynamisch hinzugefügte Elemente

Ich baue eine einfache Bibliotheksanwendung. Es gibt eine Funktion zum Hinzufügen einer Kopie eines Buchs, die jQuery verwendet, um Controller-Aktionen aufzurufen und Teilansichten zurückzugeben, die dann dynamisch zum DOM hinzugefügt werden.

Das letzte dynamisch hinzugefügte Element ist ein Formular mit zusätzlichen Details einer erstellten Kopie. Der Ajax-Aufruf wird ausgelöst, wenn sich ein Wert von DropDownList (#AuthorBooksDropDown) (auch dynamisch hinzugefügt) ändert.

$('#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'); 
}); 

Der Aufruf aufgerufen die AddCopy_RenderDetails Aktion ein Unternehmen von einem DB erhält basierend auf Buch id, und erstellt eine neue Kopie mit bestimmten Feldern bevölkern.

Controller-Aktion:

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); 
     } 

Die Ansicht zeigt Felder bleiben, die gefüllt werden müssen.

@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> 
} 

Auch wenn ich $.validator.unobtrusive.parse('#addCopyForm'); aufgerufen, wenn das Formular (geprüft in Chrom Entwickler-Tool) wiedergegeben wird, Validierung geschieht nach wie vor auf der Server-Seite auf einen Submit-Button drückt als eine POST Aktion wird jedes Mal ausgelöst wird. Ganz zu schweigen davon, dass Validierungsfehler beim TABING zum nächsten Feld nicht angezeigt werden.

Validation Attribute gibt es in Eingaben des Formulars:

enter image description here

ich auch Remote-Validierung hat, die eine eingegebene ISBN ist bereits in der Datenbank überprüft, ob. Offensichtlich funktioniert das auf der Clientseite, was in meinem Fall einfach nicht der Fall ist.

Vielen Dank für Ihre Zeit und Hilfe.

EDIT:

Nun, ich habe folgendes Ende der Ansicht hinzugefügt:

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

Und es funktioniert. Ich habe keine Ahnung, warum das Auslösen einer Funktion nichts bewirkt.

+0

Nur zur Erinnerung, ob #authorBooksPlaceHolder bereits dort in der Ansicht und nicht dynamisch bevölkert. – Shashi

+0

Danke für die Antwort. '# authorBooksPlaceHolder' ist ein statisches div, anfangs mit' display: none'. – Dandry

Antwort

1

Ajax ist asynchron, und Ihre Codezeile $.validator.unobtrusive.parse('#addCopyForm'); wird aufgerufen, bevor der HTML-Code zum DOM hinzugefügt wurde. Bewegen Sie es innerhalb des success Rückruf

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

Danke, Sir, es hat das Problem gelöst. Können Sie mir sagen, warum '$ .validator.unobtrusive.parse ('# addCopyForm');' nach den schließenden Klammern von '$ .get (...)' nicht funktionierte? Warum heißt es vorher, obwohl es nach dem Anruf platziert wird? – Dandry

+1

Ajax ist asynchron. Das bedeutet, dass es ausgeführt wird, während der Rest des Codes weiterhin ausgeführt wird, bevor die '$ .get()' - Methode eine Chance hatte, die Teilansicht vom Controller zurück zu bekommen, die '$ .validator.unobtrusive.parse ('#addCopyForm'); 'Codezeile ist betroffen (aber der HTML-Code wurde zu diesem Zeitpunkt noch nicht hinzugefügt). –

+0

Vielen Dank! – Dandry

1

Versuchen, diesen Frieden Code

$("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

Danke, aber ich habe 'Ajax.BeginForm' benutzt, um den ganzen Code einzufügen. Wie auch immer, dies ist ein anderer Weg, um es zu erledigen. – Dandry