dave
dave

Reputation: 743

Submitting form elements with the same name

I have a form which allows the user to create extra "rows" using JQuery (using .clone) so that they can decide how many of the same information they need to submit. My issue is that I cannot work out how to access these form items within my controller.

the form that is being submitted may look like this

<input type="text" name="Amount" id="Amount">
   <select name="Item">
       <option value="1">Item 1"</option>
       <option value="2">Item 2"</option>
       <option value="3">Item 3"</option>
   </select>
<input type="text" name="Amount" id="Amount">
   <select name="Item">
       <option value="1">Item 1"</option>
       <option value="2">Item 2"</option>
       <option value="3">Item 3"</option>
   </select>
<input type="text" name="Amount" id="Amount">
   <select name="Item">
       <option value="1">Item 1"</option>
       <option value="2">Item 2"</option>
       <option value="3">Item 3"</option>
   </select>

Basically, the block between input and the select could be repeated an infinite number of times. When I submit to the controller I am then using FormCollection form to access the form elements. from there I am unsure how I can access the items that have been submitted. I thought of using a for loop and then accessing them via something like form["Amount"][i] but obviously that is not going to work.

Am I going about this the right way and if so, does anyone have any suggestions about how this might work?

Thanks in advance.

Upvotes: 10

Views: 18187

Answers (6)

veggerby
veggerby

Reputation: 9020

Check out Model Binding To A List. Your Action method should be:

public ActionResult MyAction(string[] Amount, int[] Item){
   // ...
}

However this will make you need to "link" the items. Alternatively create a "Item" class:

public class Item {
    public string Amount { get; set; }
    public int Item { get; set; }
}

And

public ActionResult MyAction(IList<Item> items){
   // ...
}

And your markup should be:

<input type="hidden" name="items.Index" value="0" />
<input type="text" name="items[0].Amount" id="items[0].Amount">
   <select name="items[0].Item">
        <option value="1">Item 1"</option>
        <option value="2">Item 2"</option>
        <option value="3">Item 3"</option>
   </select>
<input type="hidden" name="items.Index" value="1" />
<input type="text" name="items[1].Amount" id="items[1].Amount">
   <select name="items[1].Item">
        <option value="1">Item 1"</option>
        <option value="2">Item 2"</option>
        <option value="3">Item 3"</option>
   </select>

Etc...

Upvotes: 11

Akos Lukacs
Akos Lukacs

Reputation: 2047

Old question, but still... You can get the posted values as an array by calling Request.Form.GetValues, or Request.QueryString.GetValues. For example:

string[] amounts = Request.Form.GetValues("Amount");

And the amounts array will contain the correct values, so you can post values containing comas, dots, whatever, and don't worry about splitting/parsing it.

Of course if you are running MVC, use the modelbinder to do it. But you can use this if you are using webforms, a generic handler, etc...

Upvotes: 18

dave
dave

Reputation: 743

I ended up realising that (blush) the mechanism which JQuery uses to find the string within the cloned row (to replace) is basically regex. Thus I just needed to escape the square brackets and period. Once I did this I was able use JQuery to create form as Phil Haack's blog suggested.

Onto my next issue...!

Upvotes: 1

Spencer Ruport
Spencer Ruport

Reputation: 35107

I believe if you have multiple fields named Amount the values will be comma delimited.

To access each one just try:

string[] amounts = Request.Form["Amount"].Split(new char[] { ',' });

Keep in mind though, the inputs are not cleaned on submission so if someone enters a comma into the text box it's going to cause issues.

Hence I'd recommend numbering them.

Upvotes: 7

jscoot
jscoot

Reputation: 2109

You can change the id and name attribute of the input to something like this "Amount[1]","Amount[2]","Amount[3]" (yes, the id and name attribute can contain the special chars "[" or "]"). Then in the controller, write a http request parameter parser to get back the Amounts as collections.

Upvotes: 0

Adam Pierce
Adam Pierce

Reputation: 34345

I would number them Amount1, Amount2, Amount3 etc.

Upvotes: 0

Related Questions