MVC3不显眼的验证工作不AJAX调用后, [英] MVC3 Unobtrusive Validation Not Working after Ajax Call

查看:109
本文介绍了MVC3不显眼的验证工作不AJAX调用后,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,这里是交易,我看到几个帖子在SO涉及这个问题,但没有为我工作。

基本上,我正在从局部视图加载选择下拉菜单,我想过滤以后每次滴下来的内容的基础上,pviously选择下拉的$ P $。

如果我只是把调用的DIV容器中的部分观点,并加载页面,从数据注释验证工作正常,主要必需属性的。

但是,如果我尝试通过AJAX加载相同的部分,因为它是建立在这里,需要的验证不起作用,任何人都可以在那之后,并张贴的形式KABOOM。

我发现有人说,在成功的回调,你需要有客户端验证重新分析的形式,和我想的是,但它似乎并不奏效。

我有一个观点,看起来像这样...

  @model Area51.Models.Workflow.AddReportableItemToBatchActionModel
@ {
    ViewBag.Title =添加申报项目批;
    布局=〜/查看/共享/ _Layout.cshtml;
}

<脚本类型=文/ JavaScript的>

    $(函数(){
        VAR fadeDelay = 150;

        $(。jqDatePicker)。日期选择器({
            DATEFORMAT:'M / D / YY,
            调用onSelect:功能(日期){
                $(#categoryContainer)显示(fadeDelay)。
            }
        });

        $('#分类)。改变(函数(){
            RetrieveItemsForCategory();
            $(#itemContainer)显示(100)。
        });

        $('#项目)。住('变化',函数(){
            RenderPartialForUOMByItem();
        });



        功能RetrieveItemsForCategory(){

            VAR类别= $(#范畴:选择)VAL()。

            $阿贾克斯({
                键入:POST,

                网址:@ Url.Action(RenderPartialForLocationItemsByCategory,BatchWorkflow),

                数据:'类别='+类别,

                成功:函数(结果){
                    $(#itemContainer)的HTML(result.toString());
                    $(#itemContainer)显示(100)。
                    RebindValidation();
                },

                错误:函数(REQ,状态,错误){
                    警报(对不起,不能要求为您选择的项目在这个时候!);
                }

            });


        }


        功能RenderPartialForUOMByItem(){

            。VAR项目= $(#项目:选择)VAL();

            $阿贾克斯({
                键入:POST,

                网址:@ Url.Action(RenderPartialForUOMByItem,BatchWorkflow),

                数据:项=+项目,

                成功:函数(结果){
                    $(#quantityContainer)的HTML(result.toString());
                    $(#quantityContainer)显示(100)。
                    RebindValidation();
                },

                错误:函数(REQ,状态,错误){
                    警报(对不起,不能要求为您选择的项目在这个时候!);
                }

            });
        }

        功能RebindValidation(){
            警报(重新绑定验证);
            $ .validator.unobtrusive.parse(#frmAddItem);
        }

    }); //结束onload事件
< / SCRIPT>

< H3类=pageHeader>批次:@ Model.BatchName< / H3>

<分区对齐=中心>

@ {Html.BeginForm(AddItemToBatch,BatchWorkflow,空,FormMethod.Post,新{ID =frmAddItem});}

    @ Html.ValidationSummary(真)

    <字段集的风格=宽度:60%>
        <传奇>添加一个项目批< /传说>

     < D​​IV>
          < H3>选择日期项目是新增和LT; / H3>
          @ Html.EditorFor(X => x.EventDate,空)
          < BR />
      < / DIV>

      < D​​IV ID =categoryContainer的风格=显示:无>
        <小时/>
          < H3>选择一个清单分类和LT; / H3>
          @ Html.EditorFor(X => x.Category,空)
          < BR />
      < / DIV>

      < D​​IV ID =itemContainer的风格=显示:无>
        @ * @ {Html.RenderAction(RenderPartialForLocationItemsByCategory,BatchWorkflow,新{类= Model.Category});} * @
      < / DIV>


      < D​​IV ID =quantityContainer的风格=显示:无>
        @ * @ {Html.RenderAction(RenderPartialForUOMByItem,BatchWorkflow,新{项目= Model.Item});} * @
      < / DIV>

      < D​​IV ID =reportingDataContainer的风格=显示:无>
        <小时/>
          < H3>是受此加入多少数量的一批< / H3>
          @ Html.EditorFor(X => x.ConsumedWineQuantity)(加仑)
        < BR />
        <小时/>
          &其中; H3>?什么作为此加法的结果的增加批处理音量与所述; / H3>
          @ Html.EditorFor(X => x.ProducedWineQuantity)(加仑)
      < / DIV>

        < D​​IV的风格=显示:块>
        < D​​IV>< / DIV>
            <跨度><按钮式=按钮ID =btnCancel级=LinkBut​​ton的值=取消的onclick =location.href ='@ Url.Action(家,家,NULL) ;>取消< /按钮>< / SPAN>
            <跨度><按钮类型=提交ID =btnSubmit按钮级=LinkBut​​ton的VALUE =添加>添加项目< /按钮>< / SPAN>
        < / DIV>


    < /字段集>
        @ {Html.EndForm(); }
< / DIV>
 

该部分的意见非常简单,基本上是这样的...

  @model Area51.Models.Workflow.AddReportableItemToBatchActionModel

      <小时/>
          < H3>选择项目添加< / H3>
          @ Html.EditorFor(X => x.Item)
          < BR />
 

再有,如果我刚才的RenderPartial,确认工作正常,但是当我尝试通过Ajax来做到这一点,验证消失。而重新绑定验证警惕火灾,但$ .validator.unobtrusive.parse(#frmAddItem);似乎并没有做任何事情。

谁能帮我缺少的是什么?这将是极大的AP preciated。

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

OK,我尝试添加了$ .validator.unobtrusive.parse(#frmAddItem);在一个文档准备事件的局部视图的底部,它似乎没有任何工作,基本上什么都没有改变,我仍然可以提交表单。

我没有在这里找到一个帖子:<一href="http://xhalent.word$p$pss.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/">http://xhalent.word$p$pss.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/所提到的MVC版本jqvalidation中看到一种形式的时候就已经绑定了验证规则,它只是忽略.validator电话。我实现了这个绅士使用的脚本扩展,并采用了新的扩展验证,现在重新绑定到窗体。我可以通过附加的HTML表单,并调用新的扩展测试,并且它重新绑定到新的文本框。

然而,这仍然没有完全固定的问题。我用Firebug检查出从Ajax调用回来领域的实际内容,并发现了一些很奇怪的。

在我使用的RenderPartial打电话的动作,它写出了以下选择:

 &LT;该项目是必填栏位选择ID =数据-VAL-所需的产品NAME =项目=数据-VAL-号码=字段项目必须是一个数字。数据-VAL =真正的&GT;
 

然而,当我做了Ajax调用完全相同的控制器动作,它给了我这回:

 &LT;选择一个id =项NAME =项目&GT;
 

我尝试添加脚本标记的局部视图,以及,但它并没有解决这个问题。是有一些原因的Ajax调用将剥离不显眼的验证标记?

&LT; =======================更新2 ==================== =========>

好了,发生了什么事,是我胸有成竹地拿着一个选择列表,并把它转换为HTML选择下拉编辑模板。我发现提到,为了得到数据验证属性写出来的编辑模板,你必须有一个形式背景下一个职位。由于Html.RenderPartial正在一个表单内完成,则编辑模板里有一个形式方面的工作。我只是想呼吁通过AJAX的部分,没有形式方面的工作,并且而不是抱怨它只是没有写出来验证属性的数据。添加一个新的窗体上下文中的SelectListDropDown编辑模板固定的问题。

  @ {//修复停止愚蠢糟糕的布拉德·威尔逊MVC3 code,从剥离JQ数据valdiation属性
    如果(ViewContext.FormContext == NULL)
    {
        ViewContext.FormContext =新FormContext();
    }
}
 

解决方案

$ validator.unobtrusive.parse(#frmAddItem); 将工作。请注意,必须在局部您通过AJAX(在部分下面的表格)加载

 &LT;形式ID =frmAddItem方法=POST行动=...&GT;
    &LT;! - 所有项目 - &GT;
&LT; /形式GT;
&LT;脚本类型=文/ JavaScript的&GT;
    $ .validator.unobtrusive.parse(#frmAddItem);
&LT; / SCRIPT&GT;
 

Ok, here is the deal, I have seen a few posts on SO relating to this issue, but nothing is working for me.

Basically, I have select drop downs that are being loaded from partial views, I am trying to filter contents of each subsequent drop down, based on the previously selected drop down.

If I just put the call to the partial view in the div containers, and load the page, the validation from data annotations works fine, primarily Required attribute.

However, if I try to load the same partial via AJAX as it is setup here, the Required validation does not work, anyone can post the form after that and KABOOM.

I have found people saying that in the Success callback you need to have the client side validator reparse the form, and I am trying that, but it doesn't seem to be working.

I have a view which looks like this...

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

The Partial Views are very simple, they basically look like this...

@model Area51.Models.Workflow.AddReportableItemToBatchActionModel

      <hr />
          <h3>Select the Item to Add</h3>
          @Html.EditorFor(x => x.Item)
          <br />

Again, if I just RenderPartial, the validation works fine, however when I try to do it via ajax, the validation goes away. The "Rebinding Validation" alert fires, but the $.validator.unobtrusive.parse("#frmAddItem"); doesn't seem to be doing a thing.

Can anyone help with what I am missing? It would be greatly appreciated.

<======================= UPDATE 1 =============================>

OK, I tried adding the $.validator.unobtrusive.parse("#frmAddItem"); at the bottom of the the partial view in a document ready event and it didn't seem to work either, basically nothing changed, I could still submit the form.

I did find a post here : http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/ that mentioned that when the MVC version of the jqvalidation sees a form already has validation rules bound to it, it just ignores the .validator call. I implemented the script extension that this gentleman used, and the validation is now rebinding to the form using the new extension. I can test this by appending html to the form and calling the new extension, and it is rebinding to the new text box.

However, this still has not completely fixed the issue. I used Firebug to check out the actual content on the fields coming back from the ajax call, and noticed something very strange.

When I use the RenderPartial to call the action, it writes out the following 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">

However, when I make the ajax call to the same exact controller action, it gives me this back :

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

I tried adding the script tags to the partial view as well, but it didn't fix the issue. Is there some reason why the ajax call would be stripping the unobtrusive validation tags?

<======================= UPDATE 2 =============================>

Ok, so what was happening, is I had an editor template for the drop down that took a select list and converted it to an html select. I found a post that mentioned that in order to get data validation attributes to write out on an editor template, you have to have a form context. Since the Html.RenderPartial was being done within a form, then the editor template had a form context to work with. When I was just trying to call the partial via ajax, there was no form context to work with, and instead of complaining it just didn't write out the data validation attributes. Adding a new Form Context in the editor template for the SelectListDropDown fixed the issue.

@{ // 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"); will work. Do note that it must be in the partial that you load through ajax (below the form in the partial)

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

这篇关于MVC3不显眼的验证工作不AJAX调用后,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆