Asp.Net MVC validation & knockout foreach

I have a MVC 4 validation & Knockout issue.

I tried this solution :

Translate knockout into razor to keep it's validation working

But i have the same problem as listed in comment of the valid answer => the validation works only for the first element.

After several searches, i found this article on model binding to a list :

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

I am wondering how to merge those two solutions.

Sample with validation working only for the first element :

Dim dummy As ViewModels.ObjectViewModel = Model.MyObjects.FirstOrDefault

@<tbody data-bind='foreach: MyObjects'>
   <td>                   
     @Html.TextBoxFor(Function(model) dummy.Label, New With {.data_bind = "value: Label"})
   </td>
</tbody>

Sample with validation working, but without the knockout foreach, i can't add items dynamically

<tbody>
     @Code
         Dim i As Integer = 0
         For Each object In Model.MyObjects
            @<tr>
               <td>  
                   @Html.TextBoxFor(Function(m) Model.MyObjects(i).Label)                  
               </td>       
            </tr>                        
            i+= 1
         Next
     End Code
</tbody>

Maybe something with knockout variable : $index() ?

Answers


In the past I’ve tried to force combining razor and knockout. But more recently I just opt to go one way or the other. If I’m going to render something on the client side, then I’ll just go ahead and define everything in terms of HTML directly instead of going through razor.

Probably your best bet here is to just define the HTML elements directly. If you need to have validation on place, then just make sure of two things:

  1. Set the corresponding jquery validate attributes (e.g. data-val-true) so that the form validates on the client side.
  2. If you’re submitting data to an ASP.NET MVC Controller make sure the elements have the same name/id as needed by the controller so that the binding takes place on the controller method parameters.

So, after many searches and tests, i have found the solution :

1° Step is to put a correct name for the validation.

Razor View Code :

Dim dummy As ViewModels.ObjectViewModel = Model.MyObjects.FirstOrDefault

<tbody data-bind='foreach: MyObjects'>
  <td>
      @Html.TextBoxFor(Function(model) dummy.Label, New With {.data_bind = "value: Label, attr: { name: 'MyObjects[' + $index() + '].Label'}"})                  
  </td>
</tbody>

You get this HTML for the first item : name="MyObjects[0].Label"

Which is cool and makes validation work.

But if you add an item dynamically, the validation won't work for the new item.

2° Step is to make the unobstrusive validation re parse your form.

JavaScript

viewModel.addObject = function () {
        viewModel.MyObjects.push(new object())
        $("form").data("validator", null);
        $.validator.unobtrusive.parse($("form"));    
    };

Those two answers helped me a lot :

Knockout MVC with existing C# code - looping

MVC Model Validation on a dynamic form?


Need Your Help

Referring to templated function in template

c++ c++11 template-templates

I would like to be able to name to a templated function in a template.