0

I have two DropDownLists. One is for GymLocation and the other is for RoomNumbers in that Gym. I want to allow the user to first select from GymLocation DropDownList and then I want to have the corresponding room numbers in the RoomNumbers DropDownList. Therefore, The RoomNumbers DropDownList will update depending on the selected location (data will be queried from the database). I am not sure how I should do it.

This is BranchViewModel:

public class BranchViewModel
{
    public IEnumerable<Branch> Branch { get; set; }

    public IEnumerable<Room> Rooms { get; set; }
}

This is the controller. Note: I have hard coded a record.

 public ActionResult Index()
 {
     var item = GetBranches(3);
     return View(item);
  }

Here I am getting a specific Branch and all the Room numbers for that branch.

 public BranchViewModel GetBranches(int id)
 {
    var branch = _context.Branches.Where(b => b.Id == id).ToList();
    var rooms = _context.Rooms.Where(b => b.BranchId == id).ToList();

    var List = new BranchViewModel
    {
       Branch = branch,
       Rooms = rooms
     };

     return List;
 }

This is the view:

@model YogaFitnessClub.ViewModels.BranchViewModel

<div class="form-group col-lg-4">
    @Html.LabelFor(m => m.Branch)
    @Html.DropDownListFor(m => m.Branch, new SelectList(Model.Branch, "Id", "LocationName"), "Select From below Room Names", new { @class = "form-control" })
</div>


<div class="form-group col-lg-4">
    @Html.LabelFor(m => m.Branch, "Room Numbers")
    @Html.DropDownListFor(m => m.Rooms, new SelectList(Model.Rooms, "Id", "RoomNumber"), "Select From below Room Numbers", new {  @class = "form-control" })
</div>

Thank you

Big Smile
  • 1,103
  • 16
  • 30
  • First you cannot bind a dropdownlist to a collection of complex objects. Your model needs properties to bind to e.g. `a `int SelectedBranch` and ideally the collection property should be `IEnumerable Branches`. Study the code in [this DotNetFiddle](https://dotnetfiddle.net/1bPZym) –  Jan 11 '18 at 01:04
  • `@Html.DropDownListFor(m => m.Rooms, ...)` => this makes no sense to bind DDLF with `IEnumerable` collection properties. Since you have `Id` property in EF tables, add selected properties for both DDLF with `int` type & bind those properties instead (essentially you're asking about cascading DDLF). – Tetsuya Yamamoto Jan 11 '18 at 02:41
  • 1
    My guess would be that you'll need to do an Ajax callback to your controller with the value of the first DDL so that the values for the second can be populated. In effect you're reloading the view once your first DDL has a value set (just not doing it in a way that causes the view to be noticeably reloaded). – gilliduck Jan 11 '18 at 04:15
  • I do not think this is solvable without using AJAX since you only need to reload the `DropDownList` element, not the whole page. I recommend you to brush up on **WebApi** and **jQuery AJAX**. – bezbos. Jan 11 '18 at 11:15

1 Answers1

3

I have had a similar problem where I had to load cities into a DropDownList based on a selected state. I solved it by using WebApi and AJAX.

Start by creating an action that receives a branchId parameter and then use LINQ to retrieve all gym rooms that match your branchId.

It should look a little bit something like this:

WepApi Controller code(for Rooms):

    [Route("api/roomsByBranch/{branchId}")]
    public List<Room> GetRoomsByGymLocation(int branchId)
        {
            var roomsByGymLocation = _context.Rooms.Where(room => room.BranchId == branchId).ToList();

            return roomsByGymLocation;
        }

WepApi Controller code(for Branches):

    [Route("api/branches")]
    public List<Branch> GetBranches()
        {
            var branches = _context.Branches.ToList();

            return branches;
        }

Here you can give the drop downs an empty list, since you will be using AJAX to fill the list.

View code(Razor):

    <div class="form-group">
        @Html.DropDownListFor(b => b.Branch.Id, new SelectList(new List<string>(), "Id", "Name"), new { @class = "form-control", id="branchesDropDown" })
    </div>
    <div class="form-group">
        @Html.DropDownListFor(r => r.Room.Id, new SelectList(new List<string>(), "Id", "Name"), new { @class = "form-control", id="roomsDropDown" })
    </div>

Now you need to use jQuery AJAX to fill the DropDownList with gym rooms.

View code(scripts):

@section scripts
{    
$(document).ready(function () {
            var branchesDropDown = $("#branchesDropDown ");
            var roomsDropDown= $("#roomsDropDown");

            branchesDropDown.ready(function () {

                    $.ajax({
                        url: "/api/branches",
                        dataType: "json",
                        success: function (data) {
                            $.each(data, function () {
                                branchesDropDown.append("<option value='" + this.Id + "'>" + this.Name + "</option>")
                            });
                        }
                    }).done(function () {
                        $.ajax({
                            url: "/api/roomsByBranch/" + @Model.Branch.Id,
                            dataType: "json",
                            success: function (data) {
                                $.each(data, function () {                                    
                                    roomsDropDown.append("<option value='" + this.Id + "'>" + this.Name + "</option>");
                                    });
                                }
                            });
                        });

            branchesDropDown.on("change", function () {
                $.ajax({
                    url: "/api/roomsByBranch/" + branchesDropDown.val(),
                    dataType: "json",
                    success: function (data) {
                        roomsDropDown.empty();
                        $.each(data, function () {
                            roomsDropDown.append("<option value='" + this.Id + "'>" + this.Name + "</option>");
                        });
                    }
                });
            });
}
bezbos.
  • 1,551
  • 2
  • 18
  • 33
  • Thank you, would you please add how both of the dropdownlists will look like? – Big Smile Jan 11 '18 at 13:08
  • @BigSmile they should be given an empty list since you are going to populate them with data using AJAX. I've updated my answer with an example. – bezbos. Jan 11 '18 at 13:56