Reputation: 574
I have a set of list elements, that I create dynamically. Each of these list elements, contains an input text, whose value I want to pass to the controller.
<ul id="list"></ul>
<button id="add">Add</button>
<script>
var counter = 1;
$('#add').click(function () {
var text = '<input type="text" name="(what should I put here?)"></input>';
var li = '<li>' + text + '</li>';
$(li).appendTo('#list');
counter++;
return false;
});
</script>
public IEnumerable<string> list {get; set;}
...
How can I bind those values to my ViewModel implicitly? I have tried to use the counter
variable to assign a name to each created element (like list[counter]
), but on the controller side the list
variable on my ViewModel still comes empty.
Upvotes: 6
Views: 2560
Reputation:
Because your collection is for value type (string
) only, then you can simply use
$('#add').click(function () {
var text = '<input type="text" name="list"></input>';
....
});
It is only necessary to include indexers when the property is a member of a complex object.
If you do include the indexer, it must start at zero and be consecutive (unless you also include a special hidden input for to identify the indexer). Your attempt at using list[counter]
failed because the value of counter
is initialized to 1
(it would have worked had you initialized it to var counter = 0;
)
Upvotes: 2
Reputation: 33306
First I would base your counter on the amount of li's within your un-ordered list with:
$('#list > li').size()
Then in order to keep the model binder happy pre-fix your property with list:
'<input type="text" name="list[' + counter + ']"></input>'
The full code then becomes:
$('#add').click(function () {
var counter = $('#list > li').size();
var text = '<input type="text" name="list[' + counter + ']"></input>';
var li = '<li>' + text + '</li>';
$(li).appendTo('#list');
return false;
});
Please note, you will have to change your view model property to an IList
or List
for indexing to work too:
public IList <string> list {get; set;}
Upvotes: 3