50

I am using MVC and I am still new with MVC. Can anyone tell me if you can fill a drop down list with data on selection of another drop down list.

I want to use Jquery to avoid postbacks and therefore making the page smoother.

Enzero
  • 1,141
  • 2
  • 17
  • 36
Mark Fenech
  • 1,358
  • 6
  • 26
  • 36

1 Answers1

169

enter image description here

enter image description here

enter image description here

Model:

namespace MvcApplicationrazor.Models
{
    public class CountryModel
    {
        public List<State> StateModel { get; set; }
        public SelectList FilteredCity { get; set; }
    }
    public class State
    {
        public int Id { get; set; }
        public string StateName { get; set; }
    }
    public class City
    {
        public int Id { get; set; }
        public int StateId { get; set; }
        public string CityName { get; set; }
    }
}   

Controller:

public ActionResult Index()
        {
            CountryModel objcountrymodel = new CountryModel();
            objcountrymodel.StateModel = new List<State>();
            objcountrymodel.StateModel = GetAllState();
            return View(objcountrymodel);
        }


        //Action result for ajax call
        [HttpPost]
        public ActionResult GetCityByStateId(int stateid)
        {
            List<City> objcity = new List<City>();
            objcity = GetAllCity().Where(m => m.StateId == stateid).ToList();
            SelectList obgcity = new SelectList(objcity, "Id", "CityName", 0);
            return Json(obgcity);
        }
        // Collection for state
        public List<State> GetAllState()
        {
            List<State> objstate = new List<State>();
            objstate.Add(new State { Id = 0, StateName = "Select State" });
            objstate.Add(new State { Id = 1, StateName = "State 1" });
            objstate.Add(new State { Id = 2, StateName = "State 2" });
            objstate.Add(new State { Id = 3, StateName = "State 3" });
            objstate.Add(new State { Id = 4, StateName = "State 4" });
            return objstate;
        }
        //collection for city
        public List<City> GetAllCity()
        {
            List<City> objcity = new List<City>();
            objcity.Add(new City { Id = 1, StateId = 1, CityName = "City1-1" });
            objcity.Add(new City { Id = 2, StateId = 2, CityName = "City2-1" });
            objcity.Add(new City { Id = 3, StateId = 4, CityName = "City4-1" });
            objcity.Add(new City { Id = 4, StateId = 1, CityName = "City1-2" });
            objcity.Add(new City { Id = 5, StateId = 1, CityName = "City1-3" });
            objcity.Add(new City { Id = 6, StateId = 4, CityName = "City4-2" });
            return objcity;
        }

View:

@model MvcApplicationrazor.Models.CountryModel
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script language="javascript" type="text/javascript">
    function GetCity(_stateId) {
        var procemessage = "<option value='0'> Please wait...</option>";
        $("#ddlcity").html(procemessage).show();
        var url = "/Test/GetCityByStateId/";

        $.ajax({
            url: url,
            data: { stateid: _stateId },
            cache: false,
            type: "POST",
            success: function (data) {
                var markup = "<option value='0'>Select City</option>";
                for (var x = 0; x < data.length; x++) {
                    markup += "<option value=" + data[x].Value + ">" + data[x].Text + "</option>";
                }
                $("#ddlcity").html(markup).show();
            },
            error: function (reponse) {
                alert("error : " + reponse);
            }
        });

    }
</script>
<h4>
 MVC Cascading Dropdown List Using Jquery</h4>
@using (Html.BeginForm())
{
    @Html.DropDownListFor(m => m.StateModel, new SelectList(Model.StateModel, "Id", "StateName"), new { @id = "ddlstate", @style = "width:200px;", @onchange = "javascript:GetCity(this.value);" })
    <br />
    <br />
    <select id="ddlcity" name="ddlcity" style="width: 200px">

    </select>

    <br /><br />
  }
live-love
  • 48,840
  • 22
  • 240
  • 204
chamara
  • 12,649
  • 32
  • 134
  • 210
  • In case someone is not using List, make sure your type is serializable. – st_stefanov Mar 22 '17 at 10:11
  • 1
    I have copied the code exactly but I get an error popup: "error : [object Object]" no matter what I select from the state dropdown – Jason Ebersey Apr 25 '17 at 18:38
  • 7
    @JasonEbersey I got the same thing. I had to replace `var url = "/Test/GetCityByStaeId/"; ` with `var url = "Url.Action(GetCityByStaeId)";` in order to get this to work since these actions were not in the `test` controller in my project. That may help you out. – Anders Oct 12 '17 at 17:22
  • 1
    If you are using a model: `@Html.DropDownListFor(m => m.JobId, Enumerable.Empty(), "Choose a job", new { @class = "form-control form-control-sm", @id = "ddlJob", })` – live-love Jul 04 '19 at 22:34
  • 2
    Nice work, you have my Up-vote. For what it's worth after all those years, I have just run this sample in .Net Core 3.1 and SelectList seems to have changed casing, so data[x].Value and data[x].Text should be data[x].value and data[x].text – TheRoadrunner Dec 29 '19 at 10:20
  • 1
    Good Solution. Btw this worked for me var url='@Url.Action("GetCityByStateId","test")' – Salman Saleh Apr 12 '20 at 20:32
  • Worked in .NET core 3.1 with the substitutions suggested by TheRoadrunner and Salman Saleh. Since my GetCityByStateId action was in my Home controller I had to set the url either to ```url = "Home/GetCityByStateId";``` or to ```url = '@Url.Action("GetCityByStateId","Home")';```. The ```Url.Action( .. )``` method is C#, so when used in the razor page should be prefixed by ```@``` besides its overloading accepting either (action) or (action, controller) accept them as strings so their names must be enclosed in double quotes, so single quotes must be used as JavaScript string delimiter. – Fry Simpson May 18 '20 at 14:08