7

Using MVC 5 with a Razor (.cshtml) view

You have a list of values in a model that needs to ultimately get data from a control in the view and append them to the list.

For example:

The model contains: public List<string> value { get; set; }

The List is allowed to contain up to 70 values, but can contain less.

In the view you have a button that dynamically adds @Html.editorfor fields, much like this: enter image description here

For each new field that is created, it's corresponding value must be appended to the List<string> value. So in this example,

The user clicks "Add Field", the new text box appears, and he enters "Line 1"

  • When submitted, this field will post to the first index of the value list like so: value[0] = "Line 1"

The user clicks "Add Field" again to add another value - he enters "Line 2"

  • When submitted, this field will post to the second index of the value list like so: value[1] = "Line 2"

The User can add UP TO 70 fields (i.e He can click "add field" 65 times to add 65 values to the value list)

What would be the quickest and most efficient way to bind the data in this manner?

Community
  • 1
  • 1
Collateral.dmg
  • 128
  • 1
  • 10
  • 1
    In your buttons `.click()` event, just dynamically add `` to the DOM. You do not need indexers if the collection is a collection of `string` (or any other simple value type) –  Jul 01 '16 at 23:29

1 Answers1

10

Before you submit make sure those dynamically added inputs have correct model names and you should be fine. So in your example it would be something similar to this:

   <input type="text" name="value[0]" value="Line 1"/>
   <input type="text" name="value[1]" value="Line 2"/>
   <input type="text" name="value[3]" value="Line 3"/>

And the model binder will automatically create a List of string with those 3 strings ("Line 1","Line 2","Line 3") in them and assign it to the corresponding property, in this case, value.

EDIT: Here's how your addField function could look like to do just that:

 function addField(){
    var addedFieldCount=$('input.dynamic-field').length;
    if(addedFieldCount==70){//But you should check it on the server side too.
       alert('No more field allowed');
       return;
    }
    $('#fieldContainer').append('<input name="value['+addedFieldCount+']"/>');
 }

That's all. If you call it hard coding then go call it.

EDIT2: As Stephen Muecke noted, you do not need indexer when you're dealing with a collection of string. (I was not aware of that :)). So your function becomes even simpler:

 function addField(){
    var addedFieldCount=$('input.dynamic-field').length;
    if(addedFieldCount==70){//But you should check it on the server side too.
       alert('No more field allowed');
       return;
    }
    $('#fieldContainer').append('<input name="value"/>');
 }    
Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206
  • Also you don't know how many fields the user wants to input, hence you won't know how many `` to put in the view – Collateral.dmg Jul 01 '16 at 15:57
  • @Collateral.dmg, when I posted my answer, the OP hadn't provided any more information. He just needed to bind the values on the client side to the model. – Mikayil Abdullayev Jul 01 '16 at 19:20
  • Also, if you want built-in model binding to match DOM input values to the model values you have to supply your request with inputs that have corresponding model names. And it's the job of client side to determine how to populate those inputs. And to put restriction on them, in this case to allow 70 inputs maximum, you can use client side or server side validation or combination of those two. – Mikayil Abdullayev Jul 01 '16 at 19:24
  • 1
    Note that you do not need to append the indexer because the property is just `List` (and its better not to add them because it allows the flexibility to also delete textboxes) –  Jul 01 '16 at 23:31
  • My model values are always `null`. I think it is because my custom inputs don't have the attribute `value`. By default input element will not create the attribute `value` on its own. I can get the value with js/jQuery API, but model binding does not work. Any though on that? – Alex Feb 27 '18 at 11:08