Reputation: 743
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
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
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
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
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
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