Manuel Reis
Manuel Reis

Reputation: 574

Bind to list ASP.NET MVC dynamic jQuery index

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.

HTML

<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>

View Model

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

Answers (2)

user3559349
user3559349

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

hutchonoid
hutchonoid

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;
});

jsFiddle

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

Related Questions