Ctrl_Alt_Defeat
Ctrl_Alt_Defeat

Reputation: 4009

Construct Dropdown in MVC?

I have a list of Car Manufacturers stored in my Database. This is part of my main layout of my site so in my layout.cshtml. I have a CarManufacturers controller that returns the data from the DB where the list of Car Manufacturers are stored.

I then have a CarManufacturers view model like below:

public class CarManufacturersViewModel
{
    public IEnumerable<SelectListItem> CarManufacturersList { get; set; }

    public int SelectedCarManufacturer { get; set; }
}

The method to Get Car manufacturers from the Db and return the Partial view is below:

    [HttpGet]
    [ChildActionOnly]
    public ActionResult Index()
    {
        var carManufacturers = _dbService.GetAll<CarManufacturer>();

        var model = new CarManufacturersViewModel
        {
            CarManufacturersList = carManufacturers.Select(c => new SelectListItem
            {
                Value = c.Id.ToString(),
                Text = c.Name
            })
        };

        return PartialView("_CarManufacturersDropDown", model);
    }

When you select a car manufacturer from the drop down list in the cshtml view another action on the controller is hit - which is below:

    [HttpPost]
    public ActionResult Index(CarManufacturersViewModelwModel model)
    {
        return RedirectToAction("MyAction", "MyController", new { carManufacturerId = model.SelectedCarManufacturer });
    }

My view then in the partial is as below:

@model MyProj.Models.CarManufacturersViewModel
<script type="text/javascript">

    $(document).ready(function() {

        $('#carmanufacturers').change(function () {
            $(this).closest('form').submit();
        });

    });
</script>

@using (Html.BeginForm("Index", "CarManufacturers", FormMethod.Post))
{
    @Html.DropDownListFor(model => model.SelectedCarManufacturer, Model.CarManufacturersList, "Car Manufacturer Details", new { id = "carmanufacturers" })
}

This works but I want to not use a @Html.DropDownListFor and just build my own bootstrap Dropdown list - some like here so the markup is:

<div class="dropdown">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
    Dropdown
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
    <li role="presentation" class="divider"></li>
    <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
  </ul>
</div>

How can I achieve this with MVC - so I still retrieve the data for the dropdown list from the database and then each item in the dropdown list will pass its own id to the Post method?

Upvotes: 0

Views: 149

Answers (1)

user2160375
user2160375

Reputation:

You can do it in two ways.

First:

<div class="dropdown" id="manuDropWrap">
  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
    Dropdown
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    @foreach (var manu in Model.CarManufacturersList)
    {
      <li role="presentation"><a role="menuitemm" href="#" data-id="@manu.Value">@manu.Text</a></li>
    }
  </ul>
  <input type="hidden" value="@Model.SelectedCarManufacturer" name="@Html.NameFor(m => m.SelectedCarManufacturer)" id="selectedManu" />
</div>

<script type="text/html">
  $("#manuDropWrap > li").each(function () {
                $(this).click(function() {
                    var id = $(this).attr("data-id");
                    $("#selectedManu").val(id);
                    $(this).closest('form').submit();
                });
            });
</script>

Second:

You can prepare own HtmlHelper extensions that generates proper html.

Remarks: written from memory, small mistakes can happen.

Upvotes: 1

Related Questions