2012-05-31 3 views
2

В моем представлении я создаю всю таблицу html, доступную для редактирования. Каждое поле в таблице имеет проверку. Вот пример кода ...MVC3 Проверка для элементов управления в цикле

<tbody> 
    foreach (Item item in Model.Items) 
    { 
     <tr> 
      <td> 
       @Html.TextBoxFor(x => em.Value) 
       @Html.ValidationMessageFor(x => em.Value) 
      </td> 
     </tr> 
    } 
</tbody> 

Это создает две проблемы в браузере.

1) Поскольку атрибут name для всех элементов управления одинаковый, когда одно поле недействительно, сообщения об ошибках отображаются во всех полях с тем же именем.

2) Возможно, связанное с именами также при проверке формы, если элемент управления в первой строке недействителен, форма недействительна. Но элементы управления во всех других строках не будут аннулировать форму (даже если отображаются сообщения об ошибках).

if (!$(form).valid()) { 
    return false; 
} 

Любые мысли были бы полезны.

UPDATE: РЕШЕНИЕ

Per Бобек предложение, я создал пользовательские расширения для TextBoxInLoopFor и ValidationMessageInLoop. Ниже приведено решение:

public static MvcHtmlString TextBoxInLoopFor<TModel, IItem, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IItem item, object htmlAttributes) 
{ 
    var model = item as IInLoopForModel; 
    if (model == null) 
     return MvcHtmlString.Empty; 

    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
    var fieldName = ExpressionHelper.GetExpressionText(expression); 
    var name = model.Name + fieldName; 

    var tag = new TagBuilder("input"); 
    tag.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 
    tag.Attributes.Add("id", name); 
    tag.Attributes.Add("for", name); 
    tag.Attributes.Add("name", name); 
    tag.Attributes.Add("value", metadata.Model.ToString()); 

    // Add the validation attributes 
    ModelState modelState; 
    if (html.ViewData.ModelState.TryGetValue(name, out modelState)) 
    { 
     if (modelState.Errors.Count > 0) 
      tag.AddCssClass(HtmlHelper.ValidationInputCssClassName); 
    } 
    tag.MergeAttributes(html.GetUnobtrusiveValidationAttributes(name, metadata)); 

    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal)); 
} 

public static MvcHtmlString ValidationMessageInLoopFor<TModel, IItem, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IItem item) 
{ 
     var model = item as IInLoopForModel; 
    if (model == null) 
     return MvcHtmlString.Empty; 

    var fieldName = ExpressionHelper.GetExpressionText(expression); 
    var name = model.Name + fieldName; 

    var tag = new TagBuilder("span"); 
    tag.Attributes.Add("class", "field-validation-valid"); 
    tag.Attributes.Add("data-valmsg-replace", "true"); 
    tag.Attributes.Add("data-valmsg-for", name); 
    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal)); 
} 

ответ

1

Это недействительно. Помощники MVC3 для ввода добавляют идентификатор для каждого из них, поэтому здесь у вас будет несколько текстовых полей с одинаковым идентификатором - это недействительно в HTML.

Вы должны вручную создать TextBoxFor и ValidationFor ваше каждое свойство на модели, или, если это возможно попробовать:

foreach (Item item in Model.Items) 
    { 
     <tr> 
      <td> 
       @Html.TextBoxFor(x => item.Value) 
       @Html.ValidationMessageFor(x => item.Value) 
      </td> 
     </tr> 
    } 
+0

Думал это был путь. Исследуйте сейчас. –

+0

Спасибо, bobek. Добавлен код решения выше. –

0

Я хотел бы предложить, используя метаданные в вашем domain.model. Вот небольшой пример для вас, чтобы понять процесс:

namespace yourDomain.Domain.Model 
{ 
    [MetadataType(typeof(fooEntityMeta))] 
    public partial class fooEntity 
    { 
} 

и выбрать поле значения от вашего лица; сделать это требуется

public class fooEntityMeta 
    { 
     [Required(ErrorMessage = "Value is required")] 
     public string Value; 
     ... 
    } 


вот ссылка, которая поможет вам в процессе: http://msdn.microsoft.com/en-us/magazine/ee336030.aspx

Смежные вопросы