1

I have read a lot about how to validate dynamically generated content in mvc 3.0 such as the one xhalent has written , But I cant understand how to use it in my code. I mean it does not work for dynamically generated form elements. Here is my Model classes:

 public class Person
{
    [Required]
    public string Name { get; set; }

    [Required]
    public string Phone { get; set; }

    public IList<Address> Addresses{get;set;}

    public Person()
    {
        Addresses = new List<Address>()
                            {
                                new Address(){Street="1"},new Address(){Street="2"}
                            };
    }


}

public class Address
{
    [Required(ErrorMessage="Error")]
    public string Street { get; set; }
}

And this the view in which the form is begin displayed:

<script src="<%: Url.Content("~/Scripts/jquery-1.5.1.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>"
    type="text/javascript"></script>

<% using (Html.BeginForm())
       { %>
    <%: Html.ValidationSummary(true) %>
    <fieldset>
        <legend>Person</legend>
        <%: Html.EditorForModel() %>
            <div class="phone-numbers">
                <%
           foreach (var item in Model.Addresses)
       {

            %>
            <%Html.RenderPartial("EditorTemplates/Addresses", item);%>
            <%} %>
        </div>

    <div style="padding: 10px 0px 10px 0px">
        <a id="add-phone" href="javascript:void(0);">Add another</a>
    </div>
    <input type="submit" value="Create" />
</fieldset>
<% } %>
</div>

  $().ready(function () {
             $("#add-phone").click(function () {
                 $.ajax({
                     url: '<%: Url.Action("GetNewAddress") %>',
                     success: function (data) {
                         $(".phone-numbers").append(data);                   
                    }
                });
            });
        });

And this is the partial view for Address:

<div style="padding: 5px 0px 5px 0px" name="editorRow" id="editorRow">
        <%: Html.LabelFor(m => m.Street) %>
        <%: Html.EditorFor(m => m.Street)%>
        <%:Html.ValidationMessageFor(m=>m.Street) %>
    </div>
archil
  • 39,013
  • 7
  • 65
  • 82
Babak Fakhriloo
  • 2,076
  • 4
  • 44
  • 80

1 Answers1

4

First, if your partial view, add this at the top

<%
 if (Html.ViewContext.FormContext == null)
    {
        Html.ViewContext.FormContext = new FormContext();
    }
%>

This should add unobtrusive data-val-* validation attributes to generated content. And in your success function of ajax downloading, insert this at the end

 $().ready(function () {
             $("#add-phone").click(function () {
                 $.ajax({
                     url: '<%: Url.Action("GetNewAddress") %>',
                     success: function (data) {
                         $(".phone-numbers").append(data);      

                         $("form").removeData("validator");
                         $("form").removeData("unobtrusiveValidation");
                         $.validator.unobtrusive.parse("form"); 

                    }
                });
            });
        });

This time it should automatically parse the downloaded content and apply validations to it

I took a look at your project and found the reason of dynamic validation not working. Practically you've got more problems in there than the validation. First, the technique you use for rendering addresses is not correct. That way, all the inputs you generate have the same id and name values. That's the reason why validator cannot distinguish between dynamically added content and previous one, it thinks all the inputs are the same and validates all streets according to first street. And moreover, if you posted that content to create on server, asp.net mvc model binder could not have binded the array of streets - for the same reason why validator cannot work. Take a look at this article for proper generation of list contents on client side. And for later, dynamic injection, you can change the controller code like

public ActionResult GetNewAddress(string id)
        {
            ViewData.TemplateInfo.HtmlFieldPrefix = string.Format("[{0}]", id);
            return View("EditorTemplates/Addresses", new Address());
        }

Passing correct id from client side is up to you :).

Also, you do not use EditorTemplates correctly, they are meant to be used with Html.DisplayFor(), and you should not have to specify their name by hand. Read about them more, there're dozens of articles there on the web

Community
  • 1
  • 1
archil
  • 39,013
  • 7
  • 65
  • 82
  • Thanks archil, but it not working, I uploaded the whole project and would really appreciate it if you take a look. I am a newbie to Jquery. This the [link](http://ifile.it/317tufm/Improved.zip) – Babak Fakhriloo Jul 29 '11 at 07:30
  • First I used the way joe[Link](http://www.joe-stevens.com/2011/07/24/asp-net-mvc-2-client-side-validation-for-dynamic-fields-added-with-ajax/) for generating ids for input controls. But i thought it has conflict with the the way you have explained. – Babak Fakhriloo Jul 29 '11 at 08:31
  • That is asp.net mvc 2. You use asp.net mvc 3 (correctly). mvc 3 has the validation changed fully from mvc 2, so that link will not work with default unobtrusive validation in mvc 3 – archil Jul 29 '11 at 08:41
  • Is there any tutorial or something likewise that can help me out? – Babak Fakhriloo Jul 29 '11 at 13:21
  • I already pointed out that http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx can help you in acting with collections. And google for display and editor templates, you will find dozens of tutorials – archil Jul 29 '11 at 13:25
  • Thanks, but there (the link you mentioned) is nothing about mvc 3 way of validation. – Babak Fakhriloo Jul 29 '11 at 13:32
  • you do not read my answer carefully, do you? :) validation method I answered (adding some scripts in success function) is correct and it works. Problem is in rendering collection of addresses. Correct that errors by reading info on the link and the validation will start working. – archil Jul 29 '11 at 13:35
  • Thanks a lot, wish you luck:) – Babak Fakhriloo Jul 29 '11 at 13:57
  • Mine worked just adding the $.validator.unobtrusive.parse("form"); after loading the div with the html – Mike Oct 18 '18 at 16:02