0

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")
}
3
  • In your $.each(CityList, function(index, locations) { console.log(CityList, index, locations); } what do you observe? Commented Mar 30, 2016 at 17:32
  • My CityList looks good in the console. [Object, Object, Object, Object] It has 4 detailed Objects with proper Text and Value Commented Mar 30, 2016 at 18:26
  • I assume ViewBag.STATEID = ... and ViewBag.CITYID = ... are typos. Based on your view its ViewBag.STATEs = ... and ViewBag.CITYs = ... otherwise you have other problems. Commented Mar 30, 2016 at 23:54

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

11 Comments

thanks. great catch. but it still doesn't work. it doesn't seem to be updating my second list at all. I did some more testing and commented out the whole .each section, leaving just the citySelect.empty(), and this doesn't clear the old list.
Right after your alert(), can you console.log(CityList) and see what you get back?
I get back: [Object, Object, Object, Object] It has 4 detailed Objects with proper Text and Value.
There is your problem. It is returning a SelectList, not a List of City. Updated my response
You should not be returning List<CITY> (there is no point sending extra data across the wire - just return a collection of anonymous objects containing only the properties you need - var CityList = db.CITYs.Where(x => x.STATEID == id).Select(x => new { Value =x. CITYID, Text = x.CITYNAME }); Otherwise this answer is correct.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.