проверка на стороне клиента динамически генерируемых элементов формы в mvc 3.0 - PullRequest
1 голос
/ 29 июля 2011

Я много читал о том, как проверять динамически сгенерированный контент в mvc 3.0, такой как написанный xhalent , но я не могу понять, как использовать его в моем коде.Я имею в виду, что это не работает для динамически генерируемых элементов формы.Вот мои классы моделей:

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

И это представление, в котором начинается форма:

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

И это частичноепросмотр по адресу:

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

1 Ответ

4 голосов
/ 29 июля 2011

Во-первых, если ваше частичное представление, добавьте это вверху

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

Это должно добавить ненавязчивые атрибуты валидации data-val- * к сгенерированному контенту.И в вашей функции успешной загрузки ajax вставьте this в конце

 $().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"); 

                    }
                });
            });
        });

На этот раз он должен автоматически проанализировать загруженный контент и применить к нему проверки

Iвзглянул на ваш проект и обнаружил, что причина динамической проверки не работает.Практически у вас есть больше проблем, чем проверка.Во-первых, техника, которую вы используете для рендеринга адресов, неверна.Таким образом, все вводимые вами данные имеют одинаковые значения идентификатора и имени.Вот почему валидатор не может отличить динамически добавляемый контент от предыдущего, он считает, что все входные данные одинаковы, и проверяет все улицы в соответствии с первой улицей.Более того, если вы разместили этот контент для создания на сервере, механизм связывания модели asp.net mvc не смог бы связать массив улиц - по той же причине, по которой валидатор не может работать.Взгляните на эту статью для правильного создания содержимого списка на стороне клиента.А для последующего динамического внедрения вы можете изменить код контроллера следующим образом:

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

Передача правильного идентификатора со стороны клиента зависит от вас :).

Кроме того, вы не правильно используете шаблоны EditorTemplates, они предназначены для использования с Html.DisplayFor(), и вам не нужно указывать их имя вручную.Читайте о них больше, там есть десятки статей в сети

...