Ajax调用后MVC3不显眼的validation工作

好的,这是交易,我已经看到有关这个问题的几个职位,但没有任何工作对我来说。

基本上,我有部分视图加载的select下拉列表,我试图根据之前select的下拉列表筛选每个后续下拉列表的内容。

如果我只是调用div容器中的部分视图,并加载页面,从数据注释validation工作正常, 主要是必需的属性

但是,如果我尝试通过AJAX加载相同的部分,则需要validation不起作用,任何人都可以在此之后发布表单和KABOOM。

我发现人们说,在callback成功,你需要有客户端validation重新parsing的forms,我正在尝试,但它似乎并没有工作。

我有一个看起来像这样的看法…

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

部分视图非常简单,基本上看起来像这样…

 @model Area51.Models.Workflow.AddReportableItemToBatchActionModel <hr /> <h3>Select the Item to Add</h3> @Html.EditorFor(x => x.Item) <br /> 

同样,如果我只是RenderPartial,validation工作正常,但是当我尝试通过ajax,validation消失。 “重新绑定validation”警报触发,但$ .validator.unobtrusive.parse(“#frmAddItem”); 似乎没有做一件事情。

任何人都可以帮助我失踪? 这将不胜感激。

更新1 ======================== =====>

好的,我尝试添加$ .validator.unobtrusive.parse(“#frmAddItem”); 在文件准备好事件的部分视图的底部,它似乎也没有工作,基本上没有任何改变,我仍然可以提交表格。

我在这里find了一个post: http ://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/提到,当jqvalidation的MVC版本看到一个表单已经有validation规则绑定到它,它只是忽略了.validator调用。 我实现了这位先生使用的脚本扩展,现在validation正在使用新的扩展重新绑定到表单。 我可以通过将html附加到窗体并调用新的扩展来testing,并重新绑定到新的文本框。

但是,这个问题还没有完全解决。 我用Firebug来检查ajax调用返回的字段上的实际内容,并注意到一些非常奇怪的东西。

当我使用RenderPartial来调用这个动作时,它会写出下面的select:

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

但是,当我把ajax调用到同一个确切的控制器操作时,它给了我这个回报:

 <select id="Item" name="Item"> 

我尝试将脚本标记添加到部分视图,但它没有解决问题。 为什么Ajax调用会剥离不显眼的validation标签有什么原因?

更新2 ======================== =====>

好的,那么发生了什么,我有一个编辑模板的下拉select列表,并将其转换为htmlselect。 我发现一篇文章提到为了获得数据validation属性写在一个编辑器模板上,你必须有一个表单上下文。 由于Html.RenderPartial是在一个表单中完成的,所以编辑器模板有一个表单上下文来处理。 当我只是试图通过ajax调用部分,没有forms上下文的工作,而不是抱怨它只是没有写出数据validation属性。 在SelectListDropDown的编辑器模板中添加新的表单上下文修复了这个问题。

 @{ // fix to stop stupid crappy brad wilson mvc3 code from stripping the jq data valdiation attributes if (ViewContext.FormContext == null) { ViewContext.FormContext = new FormContext(); } } 

$.validator.unobtrusive.parse("#frmAddItem"); 将工作。 请注意,它必须在部分中,通过ajax加载(在部分中的表单下方)

 <form id="frmAddItem" method="POST" action="..."> <!-- all the items --> </form> <script type="text/javascript"> $.validator.unobtrusive.parse("#frmAddItem"); </script> 

我正在增加我的经验,因为上述build议不适合我。 这个解决scheme确实可以帮助其他人从search引擎引导到这个页面:

Add OnSuccess="$.validator.unobtrusive.parse('YourFormName');" 给你AjaxOptions

使用Ajax.ActionLink的示例:

 @Ajax.ActionLink("This is a test to get unobtrusive javascript working", "Name_of_your_controller_action", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "UserDiv", OnSuccess="$.validator.unobtrusive.parse('UserDetailsForm');" } ) 

该解决scheme可在以下urlfind: http : //blog.janjonas.net/2011-07-24/asp_net-mvc_3-ajax-form-jquery-validate-supporting-unobtrusive-client-side-validation-and-server-side-validation

我写了这个小片段,你可以把它放在你的JavaScript文件中,它将处理所有的ajax加载的表单。

 //enable unobtrusive validation for ajax loaded forms $(document).ajaxSuccess(function (event, xhr, settings) { //process only if html was returned if ($.inArray('html', settings.dataTypes) >= 0) { //will parse the element with given id for unobtrusive validation function parseUnobtrusive(elementId) { if (elementId) { $.validator.unobtrusive.parse('#' + elementId); } } //get the form objects that were loaded. Search within divs //in case the form is the root element in the string var forms = $('form', '<div>' + xhr.responseText + '</div>'); //process each form retrieved by the ajax call $(forms).each(function () { //get the form id and trigger the parsing. //timout necessary for first time form loads to settle in var formId = this.id; setTimeout(function () { parseUnobtrusive(formId); }, 100); }); } }); 

另一个select,而不是伎俩,这对我有效。 只需在由ajax调用返回的局部视图的开始处添加以下行即可

 this.ViewContext.FormContext = new FormContext(); 

参考

我只能得到validation工作内部OnComplete而不是OnSuccess

这是AJAX代码:

 @using (Ajax.BeginForm("Index", null, new AjaxOptions { OnSuccess = "onSuccess", OnComplete = "onComplete"}, new { id = "mainForm" })) 

这是我的脚本:

 function onComplete(result) { $.validator.unobtrusive.parse("#mainForm"); alert("Complete"); };