Brendan Elding
Brendan Elding

Reputation: 11

MVC 5 - Each iteration of foreach loop creates new radio button group. How can I access results in the controller?

I'm creating an MVC 5 web app. In the view I am creating a table and iterating through a foreach loop to create a row with 3 radio buttons in each row, each row being a radio button group. The radio buttons are all pre-populated.

After I hit submit, I need to get the value of each group of radio buttons to use in the Controller.

Problematic code from the view

        @using (Html.BeginForm("Submit", "Home"))
        {
            <table>
                <tr><td>Application</td><td>Direct Debit only</td><td>Credit and Debit</td><td>Neither</td></tr>
                @{
                    int i = 0;

                    foreach (var app in Model.Applications)
                    {
                        i++;
                        string appCardType = "app" + i;
                        <tr>
                            <td>@app.Value.Name</td>
                            <td><input type="radio" name="@appCardType" @(app.Value.CardType.ToString() == "DebitOnly" ? "checked" : "" ) /></td>
                            <td><input type="radio" name="@appCardType" @(app.Value.CardType.ToString() == "CreditAndDebit" ? "checked" : "" ) /></td>
                            <td><input type="radio" name="@appCardType" @(app.Value.CardType.ToString() == "Neither" ? "checked" : "" ) /></td>
                        </tr>
                    }
                }
            </table>

            <input type="submit" value="Apply Settings" />
        }

the (currently empty) controller

    public ActionResult Submit()
    {


        return View();
    }

Anyone know how I can access the data provided by the user in the controller?

Cheers

Upvotes: 0

Views: 2890

Answers (2)

Brendan Elding
Brendan Elding

Reputation: 11

so after enlisting the help of another developer there was actually a super easy solution. Not sure if its "good code", but I'll paste my solution below.

In the View, I added a value attribute to each of the radio buttons. I did originally try using the Id attribute but that just did nothing.

        @using (Html.BeginForm("Submit", "Home"))
        {
            <table>
                <tr><td>Application</td><td>Direct Debit only</td><td>Credit and Debit</td><td>Neither</td></tr>
                @{
                    int i = 0;

                    foreach (var app in Model.Applications)
                    {
                        i++;
                        string appCardType = "app" + i;
                        <tr>
                            <td>@app.Value.Name</td>
                            <td><input type="radio" name="@appCardType" value="1" @(app.Value.CardType.ToString() == "DebitOnly" ? "checked" : "" ) /></td>
                            <td><input type="radio" name="@appCardType" value="2" @(app.Value.CardType.ToString() == "CreditAndDebit" ? "checked" : "" ) /></td>
                            <td><input type="radio" name="@appCardType" value="3" @(app.Value.CardType.ToString() == "Neither" ? "checked" : "" ) /></td>
                        </tr>
                    }
                }
            </table>

            <input type="submit" value="Apply Settings" />
        }

In the Controller, I then returned everything in the form (which was just the radio buttons) using FormCollection.

    public ActionResult Submit(FormCollection fm)
    {
        string Allpayments = Request.Form["app1"];
        string Callpay = Request.Form["app2"];
        string ThinGateway = Request.Form["app3"];
        string IVR = Request.Form["app4"];
        string TextPay = Request.Form["app5"];
        string SMSEngine = Request.Form["app6"];
        string AndroidMobileApp = Request.Form["app7"];
        string IOSMobileApp = Request.Form["app8"];
        string WindowsMobileApp = Request.Form["app9"];

        return View();
    }

This works and was pretty simple.

Upvotes: 0

Developer
Developer

Reputation: 6450

Assuming your Model is as below:

 public class Application
 {
    public List<CardType> Applications { get; set; }

    public List<CardType> SelectedCardTypes { get; set; }
  }

 public class CardType
 {
    public string Name { get; set; }
    public string Value { get; set; }
 }

Adding some dummy values in Index action:

 public ActionResult Index()
    {
        var vm = new Application();
        vm.Applications = new List<CardType>
       {
           new CardType {Value = "DebitOnly", Name = "Card 1" },
           new CardType {Value = "CreditAndDebit", Name = "Card 2" },
           new CardType {Value = "DebitOnly", Name = "Card 3" },
           new CardType {Value = "CreditAndDebit", Name = "Card 4" },
           new CardType {Value = "Neither", Name = "Card 5" },
           new CardType {Value = "DebitOnly", Name = "Card 6" },
           new CardType {Value = "Neither", Name = "Card 7" },
       };
        return View(vm);
    }

And your View:

 @using (Html.BeginForm("Submit", "Home"))
 {
  <table>
      <tr>
       <td>Application</td><td>Direct Debit only</td><td>Credit and          Debit</td><td>Neither</td></tr>
    @{
        int i = 0;

        foreach (var app in Model.Applications)
        {

           // string appCardType = "cardType" + i;
            <tr>
                <td>@app.Name
                <input type="hidden" name="SelectedCardTypes[@i].Name" value="@app.Name" />
                </td>

                <td>
                <input type="radio" name="SelectedCardTypes[@i].Value" value="DebitOnly"  @(app.Value.ToString() == "DebitOnly" ? "checked" : "" ) /></td>
                <td><input type="radio" name="SelectedCardTypes[@i].Value" value="CreditAndDebit" @(app.Value.ToString() == "CreditAndDebit" ? "checked" : "" ) /></td>
                <td><input type="radio" name="SelectedCardTypes[@i].Value" value="Neither" @(app.Value.ToString() == "Neither" ? "checked" : "" ) /></td>
            </tr>
            i++;
        }
    }
</table>

        <input type="submit" value="Apply Settings" />
        }

Now if you submit, you will get a collection of CardType with corresponding Name and selected type in post method:

  [HttpPost]
    public ActionResult Submit(Application application)
    {

        return View();
    }

enter image description here

Upvotes: 1

Related Questions