ASP.NET MVC 3 - add / remove from the collection before sending

I have a model containing a collection, such as:

  class MyModel
 {
     public List <MySubModel> SubModels {get;  set;  }
 } 

In the view, I want to dynamically add / remove from this list using Javascript before submitting. Right now I have this:

  $ ("# new-submodel"). click (function () {
     var i = $ ("# submodels"). children (). size ();
     var html = '<div> \
                     <label for = "SubModels ['+ i +']. SomeProperty"> SomeProperty </label> \
                     <input name = "SubModels ['+ i +']. SomeProperty" type = "textbox" /> \
                 </div> '
     $ ("# submodels"). append (html);
 });

It works, but it is ugly. And, if I want to show these labels / text fields for existing elements, there is no clean way to do this (without duplication).

It seems to me that I can use Razor helpers or something like that. Any ideas? Help me stay dry.

+7
source share
2 answers

The approach can lead to unforeseen errors if you delete or add a div. For example, you have 4 elements, you delete the first element, then $('#submodels').children().size() will return 3, but your last inserted div has the value of the name attribute SubModels[3].SomeProperty , which leads to conflict. And if your published values ​​contain SubModels[1] but not SubModels[0] , the SubModels[0] will not be able to link the list by default (it will bind it as null). I had to study this hard ...

To fix the above problem (and yours), I suggest you do something like this:

 $("#addBtn").click(function() { var html = '<div class="submodel">\ <label>SomeProperty</label>\ <input type="textbox" />\ </div>'; // you can convert this to a html helper! $("#submodels").append(html); refreshNames(); // trigger after html is inserted }); $(refreshNames); // trigger on document ready, so the submodels generated by the server get inserted! function refreshNames() { $("#submodels").find(".submodel").each(function(i) { $(this).find("label").attr('for', 'SubModels[' + i + '].SomeProperty'); $(this).find("label").attr('input', 'SubModels[' + i + '].SomeProperty'); }); } 

Then your look (or even the best EditorTemplate for the SubModel type) can also generate code, for example:

  <div class="submodel"> @Html.LabelFor(x => x.SomeProperty); @Html.EditorFor(x => x.SomeProperty); </div> 

It would also be possible to convert the code generation to the html helper class and use it in the EditorTemplate and in the JavaScript code

+7
source

I would recommend you go through the next blog post .

+3
source

All Articles