Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass selected item id from dropdown list to controller's action?

General problem overview: I have a create\edit view for a compound item, where I select lots of options for components from drop down lists. I want to be able to add or edit a specific component, selected in a dropdown list.

Here is a short, but complete example:

Suppose I have a Car model

public class Car
{
    public int Id { get; set; }
    public string Name { get; set; }

    public BodyStyle BodyStyle { get; set; }
    public int BodyStyleId { get; set; }
}

BodyStyle is a component of a Car aggregate, defined as:

public class BodyStyle
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Now I have a controller action to create a car,

public ActionResult CreateCar()
{
    //BodyStyles is a mock property with all hardcoded BodyStyles, just for demo
    ViewBag.Styles = new SelectList(BodyStyles, "Id", "Name");
    return View();
}

Here is the part of the CreateCar view, which defines BodyStyle dropdown list.

<div class="form-group">
    @Html.LabelFor(model => model.BodyStyle, new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(model => model.BodyStyleId, (IEnumerable<SelectListItem>)ViewBag.Styles)
        @Html.ActionLink("Create", "CreateBodyStyle")

        @*here is the problem, can't find a way to pass selected BodyStyle Id to EditBodyStyle action*@
        @Html.ActionLink("Edit", "EditBodyStyle") 
    </div>
</div>

Here is the naive implementation of EditBodyStyle

public ActionResult EditBodyStyle(int bodyStyleId)
{
    return View(BodyStyles.First(b => b.Id == bodyStyleId));
}

Is there a way to say to ASP.NET MVC to pass the selected BodyStyle Id from DropDownListFor to EditBodyStyle action?

I've achieved this with javascript, subscribing to onchange and storing the selected value, then using it in the link. But the code becomes a mess, since I have near 10 of such components on several views. The functionality is quite simple, so I wonder if I'm missing some ASP.NET MVC feature, that will help me achieve this only using Razor view engine.

Here is the resulting view, just to get the whole picture:

enter image description here

Where each option of select tag is of format:

<option value="1">Coupe - 2 door</option>
<option value="2">Coupe - 3 door</option>

Current implementation (there is no id's in the view example above, but assume dropdown list and link has ids, as noted in the js):

$(function () {
    $("#editBodyStyleLink").click(function () {
        var id = $("#bodyStylesDropDown").val();
        window.location.href = "/Home/EditBodyStyle/?id=" + id;
    });
});
like image 797
Ilya Ivanov Avatar asked Nov 29 '13 11:11

Ilya Ivanov


People also ask

How do I pass a dropdown value to a controller?

If you want to pass the selected value of your dropdown list into your controller, just add a string parameter with the name drpFields (same as the first parameter of your DropDownList method) into your temp action method.

How do I get the selected option value from a DropDownList?

Method 1: Using the value property: The value of the selected element can be found by using the value property on the selected element that defines the list. This property returns a string representing the value attribute of the <option> element in the list. If no option is selected then nothing will be returned.

How do you bind a selected item in a DropDownList to a text box and edit it?

How to bind a selected item in a drop-down list to a text box and edit it? You can bind a selected value from the drop-down list using the ngModel and edit it inside the text box or numeric input box. The selected item text and value can be got using the change event of the drop-down list through the args. itemData.


1 Answers

First you need to post your bodyStyleId as a parameter (please note I have used Cars for your controller name, you will need to change that to the actual controller name):

   <div class="form-group">
@Html.LabelFor(model => model.BodyStyle, new { @class = "control-label col-md-2" })
<div class="col-md-10">
    @Html.DropDownListFor(model => model.BodyStyleId, (IEnumerable<SelectListItem>)ViewBag.Styles)
    @Html.ActionLink("Create", "CreateBodyStyle")

    @*here is the problem, can't find a way to pass selected BodyStyle Id to EditBodyStyle action*@
    @Html.ActionLink("Edit", "EditBodyStyle", null, new { bodyStyleId = model.BodyStyleId) 
</div>

Then you need to select it when populating your select list items and send it back to the view:

public ActionResult EditBodyStyle(int bodyStyleId)
{
    var styles = BodyStyles.Select(m => new SelectListItem
                {
                    Value = m.Id.ToString(),
                    Text = m.Name,
                    Selected = bodyStyleId.Equals(m.Id.ToString())

                });
    ViewBag.Styles = styles;
    return View(model);
}

The important part which caught me out when doing this is the following line which selects the list:

 Selected = bodyStyleId.Equals(m.Id.ToString())

And finally use this for you dropdown.

@Html.DropDownListFor(model => model.BodyStyleId, (IEnumerable<SelectListItem>)ViewBag.Styles, "Please select")
like image 95
hutchonoid Avatar answered Sep 29 '22 17:09

hutchonoid