I write a demo to show my idea here, hope it could solve your problem or come up with some ideas at least.
I think you can prepare all the data when initialize selectors, that means you can finish the init task via 1 http request. And add onchange event on the select DOM.
My view, home.cshtml
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<div>
<select id="city"></select>
<select id="town"></select>
</div>
<script>
$(function () {
initSel();
});
$("#city").change(function () {
var cityid = $("#city option:checked").val();
console.log(cityid);
$.ajax({
url: "https://localhost:44319/home/getTownsById",
data: {
cityId: cityid
},
success: function (data) {
console.info("towns:" + data);
$("#town").html("");
for (var i = 0; i < data.length; i++) {
$("#town").append('<option value= ' + data[i].townId + '>' + data[i].townName + '</option>');
}
}
});
});
function initSel() {
$.ajax({
url: "https://localhost:44319/home/init",
dataType:"json",
success: function (data) {
console.info(data);
for (var i = 0; i < data.cities.length; i++) {
$("#city").append('<option value= ' + data.cities[i].cityId + '>' + data.cities[i].cityName + '</option>');
}
for (var i = 0; i < data.towns.length; i++) {
$("#town").append('<option value= ' + data.towns[i].townId + '>' + data.towns[i].townName + '</option>');
}
}
});
}
</script>
And this is my home controller:
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public JsonResult init() {
List<City> cities = new List<City>
{
new City{ CityId="city1", CityName="city1"},
new City{ CityId="city2", CityName="city2"},
new City{ CityId="city3", CityName="city3"}
};
var firstCityId = cities[0].CityId;
var towns = getTownsById(firstCityId);
Dictionary<string, object> res = new Dictionary<string, object>();
res.Add("cities", cities);
res.Add("towns", towns);
return Json(res);
}
public List<Town> getTownsById(string cityId) {
List<Town> data = new List<Town>
{
new Town{ CityId="city1",TownId="town1", TownName="town1"},
new Town{ CityId="city1",TownId="town2", TownName="town2"},
new Town{ CityId="city2", TownId="town3", TownName="town3"},
new Town{ CityId="city2", TownId="town4", TownName="town4"},
new Town{ CityId="city3", TownId="town5", TownName="town5"}
};
var towns = data.AsQueryable().Where(town => town.CityId == cityId);
return towns.ToList<Town>();
}
}
}