Wizeman1986
Wizeman1986

Reputation: 183

three level cascading drop down list

I am a beginner in programming being stuck the last 2 days on that and i am hopping on your help :)

I am building an mvc 4 app and I have a partial view with a list of departments and when you choose the department you can see the item types for this specific department in a drop down list in Browse view.

What I am trying to make is one more dropdown list in Browse view that will show the items according to the selected department and item types.

So this is my code :

View :

@using (Html.BeginForm("Browse", "Bookings", FormMethod.Post, new { id = "TypeItemFormID", data_itemsListAction = @Url.Action("ItemsList") }))
{
<fieldset>
    <legend> Type/Item</legend>
    @Html.DropDownList("department", ViewBag.ItemTypesList as SelectList, "Select a Type", new {id="ItemTypeID"})
    <div id="ItemsDivId">
        <label for="Items">Items </label>
        <select id="ItemsID" name="Items"></select>
    </div>
    <p>
        <input type ="submit" value="Submit" id="SubmitID" />
    </p>
 </fieldset>
}
<script src ="@Url.Content("~/Scripts/typeItems.js")"></script>

The controller :

public class BookingsController : Controller
    {

        private BookingSystemEntities db = new BookingSystemEntities();
        //
        // GET: /Bookings/

        public ActionResult Index()
        {
            ViewBag.Message = "Select your Department";
            var departments = db.Departments.ToList();
            return View(departments);
        }

        public ActionResult Browse(string department, string ID)
        {

            ViewBag.Message = "Browse for Equipment";

           var departments = db.Departments.Include("Items").Single(i => i.DepartmentName == department);

           ViewBag.ItemTypesList = GetItemTypeSelectList(department);

           return View();

        }

        public ActionResult Details(int id)
        {
            var item = db.Items.Find(id);

            return View(item);
        }

        //
        // GET: /Home/DepartmentMenu
        [ChildActionOnly]
        public ActionResult DepartmentMenu()
        {
            var departments = db.Departments.ToList();
            return PartialView(departments);
        }


        public SelectList GetItemTypeSelectList(string department)
        {
            var departments = db.Departments.Include("Items").Single(i => i.DepartmentName == department);
            List<SelectListItem> listItemTypes = new List<SelectListItem>();
            foreach (var item in departments.Items.Select(s => s.ItemType.ItemTypeName).Distinct())
            {
                listItemTypes.Add(new SelectListItem
                {
                    Text = item,
                    Value = item,
                }

                     );
            }

            return new SelectList(listItemTypes.ToArray(),
                                "Text",
                                "Value");

        }

        public ActionResult ItemsList(string ID)
        {
            string Text = ID;
            var items = from s in db.Items
                        where s.ItemType.ItemTypeName == Text
                        select s;

            if (HttpContext.Request.IsAjaxRequest())
                return Json(new SelectList(
                                items.ToArray(),
                                "ItemId",
                                "ItemName")
                           , JsonRequestBehavior.AllowGet);

            return RedirectToAction("Browse");
        } 


    }

The Javascript :

$(function () {

    $('#ItemsDivId').hide();
    $('#SubmitID').hide();

    $('#ItemTypeID').change(function () {
        var URL = $('#TypeItemFormID').data('itemsListAction');
        $.getJSON(URL + '/' + $('#ItemTypeID').val(), function (data) {
            var items = '<option>Select a Item</option>';
            $.each(data, function (i, item) {
                items += "<option value='" + item.Value + "'>" + item.Text + "</option>";
                // state.Value cannot contain ' character. We are OK because state.Value = cnt++;
            });
            $('#ItemsID').html(items);
            $('#ItemsDivId').show();

        });
    });

    $('#ItemsID').change(function () {
        $('#SubmitID').show();
    });
});

And at last my Model :

 public class Department
    {
        public int DepartmentId { get; set; }

        [DisplayName("Department")]
        public string DepartmentName { get; set; }

        public List<Item> Items { get; set; }

    }

public class ItemType
    {
        public int ItemTypeId { get; set; }

        [DisplayName("Type")]
        public string ItemTypeName { get; set; }

        [DisplayName("Image")]
        public string ItemTypeImage { get; set; }

        public List<Item> Items { get; set; }

    }

 public class Item
    {
        public int ItemId { get; set; }

        [DisplayName("Name")]
        public string ItemName { get; set; }

        [DisplayName("Description")]
        public string ItemDescription { get; set; }

         [DisplayName("Ref Code")]
        public string ItemReferenceCode { get; set; }

        [ForeignKey("ItemType")]
        public int ItemTypeId { get; set; }
        public virtual ItemType ItemType { get; set; }

        [ForeignKey("Department")]
        public int DepartmentId { get; set; }
        public Department Department { get; set; }

        [DisplayName("Computer Location")]
        public string ComputerLocation { get; set; }

        [DisplayName("Author Name")]
        public string AuthorName { get; set; }

        [DisplayName("Published Year")]
        public string PublishedYear { get; set; }

    }

Upvotes: 1

Views: 755

Answers (1)

cgotberg
cgotberg

Reputation: 2085

Here's how I would accomplish something like this. It isn't the only way to do it.

 $('#ItemTypeID').on('change', function() {
        $.ajax({
            type: 'POST',
            url: '@Url.Action("GetItemTypeForm")',
            data: { itemTypeId: $('#ItemTypeID').val() },
            success: function(results) {
                var options = $('#ItemTypeFormId');
                options.empty();
                options.append($('<option />').val(null).text("- Select an Item Type  -"));
                $.each(results, function() {
                    options.append($('<option />').val(this.ItemTypeFormId).text(this.Value));
                });
            }
        });
    });

Then you'd have a controller that looks something like this.

[HttpPost]
    public JsonResult GetItemTypeForm(string itemTypeId)
    {
        //pseudo code
        var data = Repostitory.GetData(itemTypeId) 

        return Json(data);
    }

Upvotes: 2

Related Questions