1

I'm looking to have something like the following:

@foreach(var option in ViewBag.OptionsAvailable)
{
        //the 'option' variable will be used in these fields, of course
        <input type='checkbox' name='thingToUse' />
        <input type='text' name='textToSaveForThing' />
}

ViewBag.OptionsAvailable can be of variable length. I would like to take one of these options and add it to Model.Options with the saved value IF its checkbox is selected. The idea here is that, on the HttpPost controller method, I want to only acknowledge/save the value in the textbox if its corresponding checkbox is selected. What's the best way to approach this?

I've come across this explanation of binding to a list, but I'm not sure how to evolve upon that to create what I want.

2
  • How is the option variable used? Commented Aug 11, 2015 at 18:38
  • Updated question, see code change and bolded explanation. Commented Aug 11, 2015 at 18:44

2 Answers 2

5

Start by creating a view model to represent what you want to display/edit

public class OptionVM
{
  public string Text { get; set; }
  public bool IsSelected { get; set; }
  public string Answer { get; set; }
  .... // other properties 
}

Then in the controller, initialize a collection of your view model and pass it to the view

public ActionResult Edit()
{
  List<OptionVM> model = new List<OptionVM>();
  .... // populate it
  return View(model);
}

and the view

@model List<yourAssembly.OptionVM>
@using (Html.BeginForm())
{
  for (int i = 0; i < Model.Count; i++)
  {
    <label>
      @Html.CheckBoxFor(m => m[i].IsSelected)
      <span>@Model[i].Text</span>
    </label>
    @Html.TextBoxFor(m => m[i].Answer)
    @Html.ValidationMessageFor(m => m[i].Answer)
  }
  <input type="submit" ... />
}

and submit to

public ActionResult Edit(List<OptionVM> model)
{
  // for example, get the answers where the checkbox has been selected
  var selectedAnswers = model.Where(m => m.IsSelected).Select(m => m.Answer);
}

and you could enhance this by using a foolproof [RequiredIfTrue] or similar validation attribute applied to the Answer property to ensure the textbox has a value if the corresponding checkbox is checked

Sign up to request clarification or add additional context in comments.

Comments

1

There is no need to have two inputs. You can use the "value" attribute of the checkboxes, and store that information. Also, in your controller, you can simply add a parameter with the same name as your input.

View

@using (Html.BeginForm())
{
    foreach (string option in ViewBag.OptionsAvailable)
    {
        <input type='checkbox' name='checkboxes' value="@option" />
        @option <!-- text to display -->
    }
    <button type="submit">Submit</button>
}

Controller

[HttpGet]
[ActionName("Index")]
public ActionResult GetCar()
{
    ViewBag.OptionsAvailable = new List<string>
    {
        "Red",
        "Yellow",
        "Blue"
    };
    return View(new Car());
}

[HttpPost]
[ActionName("Index")]
public ActionResult PostCar(string[] checkboxes)
{
    Car car = new Car
    {
        ColorsSelected = new List<string>()
    };

    foreach (string value in checkboxes)
    {
        car.ColorsSelected.Add(value);
    }
    return RedirectToAction("Index");
}

4 Comments

Suppose I need to use whatever specific value is set in the textbox, however. Wouldn't I need the second field then? How can I set the checkbox's value if it's to be inserted in that checkbox?
What's the point of having textboxes to fill if you're only going to send a few? I think you're looking for another type of input.
What do you mean a few? It's technically a date field, but the input will be text.
Why don't you post the real problem instead of a superset of it? :) I'll be able to help then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.