Paul X
Paul X

Reputation: 379

MVC Dependent List linked to model (not static list)

I am having an issue getting a dependent list to work when linking to the MVC model. In the other responses online they use static lists do demonstrate (which I can get to work), but I am missing this one last step to link to my real data. When I do the code below, nothing happens.

My guess it is one simple line I need in the javascript part that I use to set the list (right under the "WORKS SO FAR" alert). Or it seems there should be a way to just update the dropdownlistfor with my new selectlist (instead of using the each method to push one by one).

Controller:

public class EMPLOYEEsController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult Create()
{
    ViewBag.STATEID = new SelectList(db.STATEs, "STATEID", "STATENAME");
    ViewBag.CITYID = new SelectList(db.CITYs, "CITYID", "CITYNAME");
    return View();
}

    [HttpGet]
    public ActionResult UpdateCity(string id)
    {
        SelectList CityList = new SelectList(db.CITYs.Where(x => x.STATEID.Equals(id)), "CITYID", "CITYNAME");
        return Json(CityList, JsonRequestBehavior.AllowGet);
    }
}

View:

@model myproj.Models.EMPLOYEE

@{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>

@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()

<script type="text/javascript" src="/scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
    $(function () {
        $('#STATEID').change(function () {
            $.ajax({
                url: '@Url.Action("UpdateCity")',
                type: 'GET',
                dataType: 'json',
                cache: false,
                data: { id: $(this).val() },
                success: function (CityList) {
                    alert('WORKS SO FAR');
                    var citySelect = $('#CITYID');
                    citySelect.empty();
                    $.each(CityList, function (index, locations) {
                        citySelect.append(
                            $('<option/>')
                                .attr('value', CityList.CITYID)
                                .text(CityList.CITYNAME)
                            );
                    });
               },
                error: function() { alert('ERROR'); }
            });
        });
    });
</script>

<div class="form-horizontal">
<h4>EMPLOYEE</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
    @Html.LabelFor(model => model.EMPLOYEENAME, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.EMPLOYEENAME, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.EMPLOYEENAME, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.STATEID, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(model => model.STATEID, (IEnumerable<SelectListItem>)ViewBag.STATEs, "Select State", new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.STATEID, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.CITYID, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(model => model.CITYID, (IEnumerable<SelectListItem>)ViewBag.CITYs, "Select City", new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.CITYID, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Create" class="btn btn-default" />
    </div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

Upvotes: 0

Views: 56

Answers (1)

Andy T
Andy T

Reputation: 9881

CityList is your list of cities. However, you are trying to get the CityList.CityID. What you want is the CityId and CityName of the current city which $.each provides as the second parameter in the callback.

You should be able to get it with:

                   $.each(CityList, function (index, locationSelectItem) {
                        citySelect.append(
                            $('<option/>')
                                .attr('value', locationSelectItem.Text)
                                .text(locationSelectItem.Value)
                            );
                    });

While it makes sense to have StateId and CityId be SelectList since they will be used by the view, you should change your UpdateCity to return a List

Upvotes: 1

Related Questions