2

So I have a table that works like this: https://gfycat.com/WeakBlueIslandwhistler

Generated by:

<table class="table table-bordered table-with-button table-condensed " id="hidTable">
                            <thead>
                            <tr>
                                <th>HID #</th>
                                <th>Lines</th>
                            </tr>
                            </thead>
                            @for (int j = 0; j < 3; j++)
                            {
                                <tr>
                                    <td>
                                        <input class="form-control table-with-button" type="number" placeholder="HID" id="hid-@j">
                                    </td>
                                    <td>
                                        <input class="form-control table-with-button" type="number" placeholder="Lines" id="lines-@j">
                                    </td>
                                </tr>
                            }
 </table>

New rows and textboxes are created by calling a javascript method.

Essentially, there are an unknown number of pairs of text fields in this table, and the data pairs need to be passed to the controller... (I'm thinking storing it as an object in tempdata?)

Each textbox has a unique id (hid-1, hid-2 hid-3 and lines-1, lines-2, lines-3 respectively)

What is the best way to iterate over these textboxes, save their value (I can handle validation prior to saving) and then pass it to the backend?

Bitz
  • 1,128
  • 11
  • 33
  • Note that your code will never be able to 2-way bind correctly and you need a collection of a model with 2 properties ( `int Hid` and `int Line`) and then to generate the view correctly and allow correct binding and validation, refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –  Oct 27 '16 at 22:11

1 Answers1

2

The MVC Modelbinder will be able to directly bind the POST data if you meet some conditions:

  • The name and id of the dynamically added HTML inputs conform to the naming scheme used by MVC. I.e. to bind the first element of a collection, the value of the html id attribute should be {collectionName}_0 and the value of the name attribute should be {collectionName}[0]
  • The ViewModel contains collections to which the list of inputs can be bound.

So in your case, define a ViewModel that contains lists for HIDs and Lines

public class PostDataModel {
    public ICollection<int> Hids { get; set; }
    public ICollection<int> Lines { get; set; }
}

Then make sure that the javascript code that adds additional lines sets idand name correctly.

The generated inputs for the 0th line should look like this:

<input class="form-control table-with-button" type="number" placeholder="HID" id="Hids_0" name="Hids[0]">
<input class="form-control table-with-button" type="number" placeholder="Lines" id="Lines_0" name="Lines[0]">

If the User can delete any line before sumbitting, watch out for non sequential indices!

Then just submit the form with a normal POST and correlate HIDs and Lines using their index.

Community
  • 1
  • 1
Georg Patscheider
  • 9,357
  • 1
  • 26
  • 36
  • Wow, thanks, that works perfectly! Is this behaviour specific to icollections or can it be used for other collection types? (Out of curiosity, really- I am sticking with your solution.) Lets say I would want indexes at some point. – Bitz Oct 27 '16 at 15:52
  • You do not need the indexer because its a collection of simple values (the indexers are only required for collections of complex objects and it can simply be `` (the `id` attribute is unnecessary) –  Oct 27 '16 at 22:02