How to access dynamically created checkbox value i

2019-05-31 10:10发布

问题:

I have the view that contains the checkbox and Submit button as shown below.

@using (Html.BeginForm())
    {
        <fieldset>
            <legend style="font-size: 100%; font-weight: normal">Delete</legend>
            <p> Are you sure you want to delete?</p>
            @foreach (string resource in resources)
            {
                if (resource != "")
                {
                    <input type="checkbox" name="Resources" title="@resource" value="@resource" checked="checked"/>@resource
                    <br />
                }
            }
            <br />

            @Html.HiddenFor(m => m.AttendeeListString)
        @Html.HiddenFor(m => m.ResourceListString)

            <span class="desc-text">
                <input type="submit" value="Yes" id="btnYes" />
            </span>
            <span class="desc-text">
                <input type="submit" value="No" id="btnNo" />
            </span>
        </fieldset>
    }

Below is the Controller code...

public ActionResult DeleteResource(RoomModel roomModel)
{
...
}

RoomModel contains some other data...

Now how can i access the checkbox value in controller? Note : I have lot more information that need to be send to Controller when i clicked on submit button... Can anybody suggest some solution....

Answer :

I have added these two property to My model

public List<SelectListItem> Resources
{
    get;
    set;
}

public string[] **SelectedResource**
{
    get;
    set;
}

And My view check box i have updated as follows

@foreach (var item in Model.Resources)
{
<input type="checkbox" name="**SelectedResource**" title="@item.Text" value="@item.Value" checked="checked"/>@item.Text
<br /><br />
}

And in Controller ...

if (roomModel.SelectedResource != null)
{
    foreach (string room in roomModel.**SelectedResource**)
    {
      resourceList.Add(room);
    }
}

Note: The name of check box and Property in the model should be same. In my case it is SelectedResource

回答1:

You have a few options. The easiest would be:

1) Parameter bind a view model with the Resources property. I recommend this way because it's the preferred MVC paradigm, and you can just add properties for any additional fields you need to capture (and can take advantage of validation easily by just adding attributes).

Define a new view model:

public class MyViewModel
{
    public MyViewModel()
    {
       Resources = new List<string>();
    }

    public List<string> Resources { get; set; }

    // add properties for any additional fields you want to display and capture
}

Create the action in your controller:

public ActionResult Submit(MyViewModel model)
{
      if (ModelState.IsValid)
      {
           // model.Resources will contain selected values
      }
      return View();   
}

2) Parameter bind a list of strings named resources directly in the action:

public ActionResult Submit(List<string> resources)
{
      // resources will contain selected values

      return View();   

}

It's important to note that in the question, the view is creating checkboxes that will send the string value of all checked resources, not boolean values (as you might expect if you used the @Html.CheckBox helper) indicating if each item is checked or not. That's perfectly fine, I'm just pointing out why my answer differs.



回答2:

In MVC action, have a parameter that corresponds to the name of the checkbox, something like:

bool resources
bool[] resources


回答3:

use javascript or jquery to collect all the value and post to the controller

var valuesToSend='';

$('input:checked').each(function(){
valuesToSend+=$(this).val() + "$";//assuming you are passing number or replace with your logic.
});

and after submit call ajax function

$.ajax({
url:'yourController/Action',
data:valuesTosend,
dataType:'json',
success:function(data){//dosomething with returndata}
})

or else you can pass the model to controller. if you implemented Model -View-ViewModel pattern.

public class yourViewModel
{
    public string Id { get; set; }
    public bool Checked { get; set; }
}

Action methods

[HttpPost]
    public ActionResult Index(IEnumerable<yourViewModel> items)
    {
         if(ModelState.IsValid)
          {
            //do with items. (model is passed to the action, when you submit)
          }
    } 


回答4:

I'm assuming that the resources variable is generated in the Controller or can be placed onto the ViewModel. If so, then this is how I would approach it:

Your view model would have a Resources dictionary added to it, and would look something like this:

public class RoomModel
{
    public Dictionary<string,bool> Resources { get; set; }

    // other values...
}

You populate the Resources Dictionary with the names of your resource items as the key (string) and set the "checked" value (bool) to a default state of false.

e.g. (in your [HttpGet] controller)

// assuming that `resource` is your original string list of resources
string [] resource = GetResources();
model.Resources = new Dictionary<string, bool>();
foreach(string resource in resources)
{
  model.Resources.Add(resource, false);
}   

To render in the view, do this:

@foreach (string key in Model.Resources.Keys)
{
  <li>
    @Html.CheckBoxFor(r => r.Resources[key])
    @Html.LabelFor(r => r.Resources[key], key)
  </li>
}

This will then enable the [HttpPost] controller to automatically populate the dictionary onto the Model when you post back:

public ActionResult DeleteResource(RoomModel roomModel)
{
  // process checkbox values
  foreach(var checkbox in roomModel.Resources)
  {
    // grab values
    string resource = checkbox.Key;
    bool isResourceChecked = checkbox.Value;

    //process values...
    if(isResourceChecked)
    {
      // delete the resource
    }

    // do other things...
  }
}


回答5:

I have added these two property to My model

public List<SelectListItem> Resources
{
    get;
    set;
}

public string[] **SelectedResource**
{
    get;
    set;
}

And My view check box i have updated as follows

@foreach (var item in Model.Resources)
{
<input type="checkbox" name="**SelectedResource**" title="@item.Text" value="@item.Value" checked="checked"/>@item.Text
<br /><br />
}

And in Controller ...

if (roomModel.SelectedResource != null)
{
    foreach (string room in roomModel.**SelectedResource**)
    {
      resourceList.Add(room);
    }
}

Note: The name of check box and Property in the model should be same. In my case it is SelectedResource