OK, o to chodzi, widziałem kilka wpisów na temat SO związanych z tym problemem, ale nic nie działa dla mnie.MVC3 Dyskretna walidacja nie działa po wywołaniu Ajaxa
Zasadniczo, wybrałem rozwijane listy rozwijane, które są ładowane z widoków częściowych, próbuję filtrować zawartość każdego kolejnego rozwijania w oparciu o wcześniej wybrane rozwijane menu.
Jeśli właśnie wprowadziłem wywołanie do widoku częściowego w kontenerach div i załaduję stronę, sprawdzanie poprawności z adnotacji danych działa poprawnie, przede wszystkim Wymagany atrybut.
Jednakże, jeśli próbuję załadować to samo częściowe poprzez AJAX, jak to jest tutaj ustawione, Wymagana weryfikacja nie działa, każdy może opublikować formularz po tym i KABOOM.
Znalazłem ludzi mówiących, że w oddzwanianiu powodzenia musisz mieć narzędzie do sprawdzania poprawności formularza po stronie klienta i próbuję tego, ale nie działa.
Mam widoku, który wygląda tak ...
@model Area51.Models.Workflow.AddReportableItemToBatchActionModel
@{
ViewBag.Title = "Add Reportable Item to Batch";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript">
$(function() {
var fadeDelay = 150;
$(".jqDatePicker").datepicker({
dateFormat: 'm/d/yy',
onSelect: function (date) {
$("#categoryContainer").show(fadeDelay);
}
});
$('#Category').change(function() {
RetrieveItemsForCategory();
$("#itemContainer").show(100);
});
$('#Item').live('change', function() {
RenderPartialForUOMByItem();
});
function RetrieveItemsForCategory() {
var category = $("#Category :selected").val();
$.ajax({
type: "POST",
url: '@Url.Action("RenderPartialForLocationItemsByCategory","BatchWorkflow")',
data: 'category=' + category,
success: function (result) {
$("#itemContainer").html(result.toString());
$("#itemContainer").show(100);
RebindValidation();
},
error: function (req, status, error) {
alert("Sorry! Could not request items for your selection at this time.");
}
});
}
function RenderPartialForUOMByItem() {
var item = $("#Item :selected").val();
$.ajax({
type: "POST",
url: '@Url.Action("RenderPartialForUOMByItem","BatchWorkflow")',
data: "item=" + item,
success: function (result) {
$("#quantityContainer").html(result.toString());
$("#quantityContainer").show(100);
RebindValidation();
},
error: function (req, status, error) {
alert("Sorry! Could not request items for your selection at this time.");
}
});
}
function RebindValidation() {
alert("Rebinding Validation");
$.validator.unobtrusive.parse("#frmAddItem");
}
}); // End OnLoad Event
</script>
<h3 class="pageHeader">Batch : @Model.BatchName</h3>
<div align="center">
@{Html.BeginForm("AddItemToBatch", "BatchWorkflow", null, FormMethod.Post, new { id = "frmAddItem" });}
@Html.ValidationSummary(true)
<fieldset style="width:60%">
<legend>Add an Item to the Batch</legend>
<div>
<h3>Select Date Item was Added</h3>
@Html.EditorFor(x => x.EventDate,null)
<br />
</div>
<div id="categoryContainer" style="display:none">
<hr />
<h3>Select an Inventory Category</h3>
@Html.EditorFor(x => x.Category,null)
<br />
</div>
<div id="itemContainer" style="display:none">
@* @{Html.RenderAction("RenderPartialForLocationItemsByCategory", "BatchWorkflow", new { category = Model.Category });}*@
</div>
<div id="quantityContainer" style="display:none">
@* @{Html.RenderAction("RenderPartialForUOMByItem", "BatchWorkflow", new { item = Model.Item });}*@
</div>
<div id="reportingDataContainer" style="display:none">
<hr />
<h3>What quantity of the batch was affected by this addition?</h3>
@Html.EditorFor(x => x.ConsumedWineQuantity) (Gallons)
<br />
<hr />
<h3>What was the increase in Batch Volume as a result of this addition?</h3>
@Html.EditorFor(x => x.ProducedWineQuantity) (Gallons)
</div>
<div style="display:block">
<div></div>
<span><button type="button" id="btnCancel" class="linkButton" value="Cancel" onclick="location.href='@Url.Action("Home","Home",null)';">Cancel</button></span>
<span><button type="submit" id="btnSubmit" class="linkButton" value="Add">Add Item</button></span>
</div>
</fieldset>
@{ Html.EndForm(); }
</div>
częściowego widoki są bardzo proste, w zasadzie wyglądają tak ...
@model Area51.Models.Workflow.AddReportableItemToBatchActionModel
<hr />
<h3>Select the Item to Add</h3>
@Html.EditorFor(x => x.Item)
<br />
Ponownie, jeśli tylko renderPartial sprawdzanie poprawności działa dobrze, jednak gdy próbuję to zrobić za pomocą ajax, walidacja znika. Alert "Rebinding Validation" zostanie uruchomiony, ale $ .validator.unobtrusive.parse ("# frmAddItem"); chyba nic nie robi.
Czy ktoś może pomóc w tym, czego mi brakuje? Byłoby to bardzo docenione.
< ======================= AKTUALIZACJA 1 ==================== =========>
OK, próbowałem dodać $ .validator.unobtrusive.parse ("# frmAddItem"); w dolnej części częściowego widoku w przypadku zdarzenia gotowego do druku i też nie działało, zasadniczo nic się nie zmieniło, wciąż mógłbym przesłać formularz.
Znalazłem post tutaj: http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/, który wspomniał, że gdy wersja jqwaldztwa MVC widzi formularz już związany z regułami sprawdzania powiązanymi z nim, to po prostu ignoruje wywołanie .validator. Zaimplementowałem rozszerzenie skryptu, którego ten dżentelmen używał, a sprawdzanie poprawności odwołuje się teraz do formularza przy użyciu nowego rozszerzenia. Mogę to przetestować poprzez dołączenie html do formularza i wywołanie nowego rozszerzenia i ponowne przypisanie do nowego pola tekstowego.
Jednak nadal nie rozwiązało to całkowicie problemu. Użyłem Firebug do sprawdzenia rzeczywistej zawartości pól powracających z połączenia ajax i zauważyłem coś bardzo dziwnego.
Kiedy używam renderPartial zadzwonić akcję, to pisze się następujące wybierz:
<select id="Item" name="Item" data-val-required="The Item field is required." data-val-number="The field Item must be a number." data-val="true">
Jednak, kiedy nawiązać połączenie ajax do tego samego działania kontrolera dokładnym, to daje mi to z powrotem:
<select id="Item" name="Item">
Próbowałem dodać tagi skryptów do częściowego widoku, ale nie rozwiązało problemu. Czy jest jakiś powód, dla którego wywołanie ajax byłoby pozbawione dyskretnych znaczników walidacyjnych?
< ======================= UPDATE 2 ==================== =========>
Ok, więc co się stało, to miałem szablon edytora dla rozwijanego, który wziął listę wyboru i przekonwertował ją do html select. Znalazłem wpis, w którym wspomniałem, że aby uzyskać atrybuty sprawdzania poprawności danych do wypisania na szablonie edytora, musisz mieć kontekst formularza. Ponieważ program Html.RenderPartial był wykonywany w formularzu, szablon edytora miał kontekst formularza do pracy. Kiedy próbowałem wywoływać częściowe poprzez ajax, nie było kontekstu formularza do pracy, a zamiast narzekać, po prostu nie wypisałem atrybutów sprawdzania poprawności danych. Dodanie nowego Kontekstu formularza w szablonie edytora dla SelectListDropDown rozwiązało problem.
@{ // fix to stop stupid crappy brad wilson mvc3 code from stripping the jq data valdiation attributes
if (ViewContext.FormContext == null)
{
ViewContext.FormContext = new FormContext();
}
}
możliwy duplikat [Problem z uzyskaniem dyskretnego sprawdzania poprawności działającego z mvc 3 na jquery ajax post] (http: //stackoverflow.com/questions/7005052/trouble-getting-unobtrusive-validation-working-with-mvc-3-on-jquery-ajax-post) – jgauffin
Również duplikat: http://stackoverflow.com/questions/6812779/mvc-3-razor-load-partial-with-validation – jgauffin
Dodanie rzeczy ViewContext.FormContext naprawiło mój problem. – K0D4