Why my cascading dropdown menu isn't working and how I figured out I made a simple logic error

40 Views Asked by At

I'm trying to create a cascading dropdown menu involving campuses whose value will populate the building menu dynamically.

The way it's working is that a selection is made:

                    <td>
                        <!-- Your existing College/Site dropdown -->
                        College/Site:
                        <select asp-for="@Model.SelectedCollege" class="form-control" id="campusList">
                            <option value="0">Select College...</option>
                            @foreach (var row in Model.Colleges)
                            {
                                <option value="@row.CampusCode">@row.CampusAbrev</option>
                            }
                        </select>
                    </td>

Once that is done, the AJAX is called:

    $("#campusList").change
    (function () 
        {
            var campus = $("#campusList").val();
            showBuildings(campus); // Make AJAX call to fetch buildings
        }
    );

    function showBuildings(campus) 
    {
        $.ajax
        (
            {
                url: "/Buildings/BuildingsListJson?cid=" + campus,
                type: 'GET',
                //dataType: 'json',
                success: function (data) 
                {
                    populateBuildingDropdown(data); // Populate Building dropdown
                },
                error: function (request, error) 
                {
                    alert("Request: " + JSON.stringify(request));
                }
            }
        );
    }

This is directed to a .cshtml.cs page that then calls to a method that passes in the campus identifier, makes a call to a server, passes in the login credentials, gets a response, reads through the response, and then returns a type IEnumerable<Building> after passing it through a Json deserializer (the method is not included due to containing client specific information but for context, it's titled BuildingsByCampus(campus)):

 public class BuildingsListJsonModel : PageModel
    {
        readonly InventoryService bs;
        public BuildingsListJsonModel(InventoryService isServ)
        {
            bs = isServ;
        }
        public IEnumerable<Building> BuildingsList { get; set; }
        public JsonResult OnGet(string cid)
        {
            BuildingsList = bs.BuildingsByCampus(cid);
            return new JsonResult(BuildingsList);
        }
    }

The final step of this is that the information needs to be passed into another AJAX function that is called in showBuildings(campus) which takes the information and populates the Building menu:

    function populateBuildingDropdown(buildings) {
        var dropdown = $("#buildingsList");
        dropdown.empty(); // Clear existing options

        dropdown.append($("<option />").val("0").text("Select Building..."));
        $.each
        (buildings, function (index, building) 
            {
                // Concatenate BuildingNum and Name to create option text
                var optionText = building.BuildingNum + "-" + building.Name;
                dropdown.append($("<option />").val(building.Name).text(optionText));
            }
        );
    }
                    <td>
                        <!-- Building dropdown (populated dynamically) -->
                        Building:
                        <select asp-for="@Model.SelectedBuilding" class="form-control" id="buildingsList">
                            <option value="0">Select Building...</option>
                            <option value="VARIOUS">VARIOUS</option>
                            <option value="OTHER">OTHER</option>
                        </select>
                    <div id="txtHint">Customer info will be listed here...</div>
                   
                    </td>

The part I'm getting hung up on is what I need to do to pass this information into the populating AJAX function. I only started using AJAX a couple days ago, so I'm not wholly familiar with the syntax, how it runs, how to pass information in, etc., so I'm just not sure what I'm supposed to do next or even what the most efficient way of passing the information over is.

There are a few more things I'll include just for the sake of completeness and because I'm not entirely sure what information may or may not be useful or relevant.

  1. The Building class is contained within the Inventory model
  2. This class does contain two fields of type string named Name and BuildingNum
  3. The values themselves can be listed out when getting the page by iterating through Model.BuildingsList using a foreach loop and calling row.Name and row.BuildingNum
1

There are 1 best solutions below

0
Eric Pilati On

I was about to submit this when I finally figured out why I couldn't get it to work and why logic errors will continue to be the bane of programmer's lives.

  1. In the .cshtml page for BuildingListJson, there was a line:
    @model [other stuff goes here].Buildings.BuildingsListModel
    
    It needed to be this:
    @model [other stuff goes here].Buildings.BuildingsListJsonModel
    
  2. In the populating AJAX function, Name and BuildingNum were not supposed to have the first letter captialized, so it should have looked like this:
    var optionText = building.buildingNum + "-" + building.name;
    dropdown.append($("<option />").val(building.name).text(optionText));
    

Six letters

That was what stood between me and a working cascading dropdown menu. There are still bugs involving other things on the page, but the menu now populates exactly as desired.

If anyone would like to use anything from this to help them when creating anything similar, please feel free. Avoid my mistakes. Avoid the absolute feeling of defeat from a stupid human error.