coto2
coto2

Reputation: 179

Cascading drop down won't populate

I am very new to MVC5 and JQuery and I trying to create a cascading drop down. When the user selects a Practice from the drop down I am trying to get the Opticians that work in that Practice to populate.

Optician Model:

 public class Optician
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid OpticianId { get; set; }

    [ForeignKey("User")]
    public string UserId { get; set; }
    public virtual ApplicationUser User { get; set; }
    public IEnumerable<SelectListItem> UserList { get; set; }

    [ForeignKey("Practice")]
    public Guid PracticeId { get; set; }
    public virtual Practice Practice { get; set; }
    public IEnumerable<SelectListItem> PracticeList { get; set; }

    public virtual ICollection<ApplicationUser> Users { get; set; }

    public virtual ICollection<Practice> Practices { get; set; }
}

Practice Model:

public class Practice
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Display(Name = "Practice")]
    public Guid PracticeId { get; set; }

    [Display(Name = "Practice Name")]
    public string PracticeName { get; set; }


    public virtual ICollection<Optician> Opticians { get; set; }

    public virtual ICollection<Booking> Bookings { get; set; }
}

Application User Model:

public class ApplicationUser : IdentityUser
{
    [Display(Name = "Title")]
    public string Title { get; set; }

    [Display(Name = "First Name")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    public string LastName { get; set; }
}

Controller :

public ActionResult TestDropDown()
    {
        var PracticeListItems = (from d in db.Practices
                                 select d.PracticeName).ToList();

        SelectList Practice = new SelectList(PracticeListItems);
        ViewData["Practice"] = Practice;

        return View();
    }

    public JsonResult Opticians(Guid? Id)
    {
        var OpticianList = (from d in db.Opticans
                            where d.PracticeId == Id
                            select d.User.FirstName).ToList();

        return Json(OpticianList);
    }

The View:

<script src="~/Scripts/jquery-1.10.2.js"></script>

<script>
$(document).ready(function () {
    $("#Optician").prop("disabled", true);
    $("#Practice").change(function () {
        if ($("#Practice").val() != "Select") {
            var PracticeOptions = {};
            PracticeOptions.url = "/Bookings1/Opticians";
            PracticeOptions.type = "POST";
            PracticeOptions.data = JSON.stringify({ Practice: $("#Practice").val() });
            PracticeOptions.datatype = "json";
            PracticeOptions.contentType = "application/json";
            PracticeOptions.success = function (OpticianList) {
                $("#Optician").empty();
                for (var i = 0; i < OpticianList.length; i++) {
                    $("#Optician").append("<option>" + StatesList[i] + "</option>");
                }
                $("#Optician").prop("disabled", false);
            };
            PracticeOptions.error = function () { alert("Error in getting Practices"); };
            $.ajax(PracticeOptions);
        }
        else {
            $("#Optician").empty();
            $("#Optician").prop("disabled", true);
        }
    });
});

@using (Html.BeginForm("TestDropDown", "Bookings1", FormMethod.Post))
{
@Html.AntiForgeryToken()
<h4>Select Practcie & Opticians</h4>
<hr />
@Html.ValidationSummary()
<div class="form-group">
    @Html.Label("Select Practice :", new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.DropDownList("Practice", ViewData["Practices"] as SelectList, new { @class = "form-control" })
    </div>
</div><br />
<div class="form-group">
    @Html.Label("Select Optician :", new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        <select id="Optician"></select>
    </div>
</div>
<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" class="btn btn-default" value="Submit" />
    </div>
</div>
}

However, when I run the application the Practice Name populates but the Optician First Name does not. There are no errors and I am unsure of where I am going wrong. Any help would be greatly appreciated.

Upvotes: 2

Views: 85

Answers (1)

JamieD77
JamieD77

Reputation: 13949

Seems like you have a few issues with your code.. Starting with your SelectList.

When you define your select list it helps if you tell it what your Value and Text properties are..

public ActionResult TestDropDown()
{
    var practices = new SelectList(db.Practices, "PracticeId", "PracticeName");
    ViewData["Practices"] = practices;
    return View();
}

Then you should probably return more information in your Opticians json result

[HttpPost]
public JsonResult Opticians(Guid? Id)
{
    var opticianList = db.Opticians.Where(a => a.PracticeId == Id).Select(a => a.User).ToList();

    return Json(opticianList);
}

In your javascript once you get the names sorted out out you can reference the property FirstName of the result.

$(document).ready(function () {
    $("#Optician").prop("disabled", true);
    $("#Practice").change(function () {
        $.ajax({
            url = "@Url.Action("Opticians","Bookings1")",
            type = "POST",
            data = {Id : $(this).val() }
        }).done(function(OpticianList){
            $("#Optician").empty();
            for (var i = 0; i < OpticianList.length; i++) {
                $("#Optician").append("<option>" + OpticianList[i].FirstName + "</option>");
            }
            $("#Optician").prop("disabled", false);
        });
    });
});

I'm not sure why you were passing paramater Practice to an action that took a parameter Id but it should be fixed in the code above.

Upvotes: 2

Related Questions