I have a model that contains a collection, such as this:
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); });
This works, but it's ugly. And, if I want to show those labels/textboxes for the existing items, there's no clean way to do that either (without duplicating).
I feel like I should be able to use Razor helpers or something to do this. Any ideas? Help me stay DRY.
You approach may lead to unexpected errors if you when you are removing or adding the divs. For example you have 4 items, you remove the first item, then
$('#submodels').children().size()
will return 3, but your last inserted div has the name attribute value setSubModels[3].SomeProperty
which results in a conflict. And if your posted values containSubModels[1]
but notSubModels[0]
the default model binder will fail to bind the list (it will bind it as null). I had to learn this the hard way...To eliminate the aforementioned problem (and your's) I suggest you do something like this:
Then your view (or even better an EditorTemplate for the SubModel type) can also generate code like:
It would also be possible to convert the code generation to a html helper class, and use it in the EditorTemplate and in the JavaScript code
I would recommend you going through the following blog post.