I am not sure if this jquery script is correct. The Sublist populates on changing main list using where clause on whatever value is selected in main list. Do i need action method? What is the best solution?
<script type="text/javascript">
$("#FKCountyId").change(function () {
$.ajax({
url: "@Url.Action("", "")",
dataType: 'json',
type: 'POST',
data: { txt: $("#FKCountyId").val() },
success: function (data) {
$('#FKCityId').empty();
// need help here
},
error: function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
}
});
});
View
@Html.LabelFor(m => m.FKCountyId, new { @class = "col-sm-2 col-sm-2 control-label" })
@Html.DropDownListFor(m => m.FKCountyId, Model.GetCounty())
@Html.LabelFor(m => m.FKCityId, new { @class = "col-sm-2 col-sm-2 control-label" })
@Html.DropDownListFor(m => m.FKCityId, Model.GetCity())
Model
public class NewsModel : BaseModel
{
[Required]
public int? FKCountyId { get; set; }
public string County { get; set; }
[Required]
public int? FKCityId { get; set; }
public string City { get; set; }
public List<SelectListItem> GetCounty()
{
List<SelectListItem> lst = new List<SelectListItem>();
lst.Add(new SelectListItem() { Text = "Please select County", Value = "" });
foreach (var item in LambertonContext.NewsCounties)
{
lst.Add(new SelectListItem() { Text = item.County, Value = item.PKCountyId.ToString() });
}
return lst;
}
public List<SelectListItem> GetCity()
{
List<SelectListItem> lst = new List<SelectListItem>();
lst.Add(new SelectListItem() { Text = "Please select City", Value = "" });
foreach (var item in LambertonContext.NewsCities)
{
lst.Add(new SelectListItem() { Text = item.City, Value = item.PKCityId.ToString() });
}
return lst;
}
}
Your View
and Model
are not correct, One way to achieve your goal is to create a ViewModel
that will handle both of your lists , this way you can leave your base models abstract.
Here's how i would rearrange your code.
Model
using System;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Web.Mvc;
namespace Alundra.Models
{
public class CountyCityViewModel
{
public List<CountyModel> Countymodel { get; set; }
public SelectList SelectedCity { get; set; }
}
public class CountyModel
{
public int ID { get; set; }
public string CountyName { get; set; }
}
public class CityModel
{
public int ID { get; set; }
public string CityName { get; set; }
//Foreign key for the County model
public int CountyID { get; set; }
public virtual CountyModel County { get; set; }
}
}
Controller
using System;
using System.Web.Mvc;
using System.Collections.Generic;
using Alundra.Models;
using System.Linq;
namespace HelloWorldMvcApp
{
public class HomeController : Controller
{
public ActionResult Index()
{
CountyCityViewModel CountyCityviewmodel = new CountyCityViewModel();
CountyCityviewmodel.Countymodel = new List<CountyModel>();
CountyCityviewmodel.Countymodel = GetAllCounties();
return View(CountyCityviewmodel);
}
//This is the action you will call using AJAX from your view
[HttpPost]
public ActionResult GetCityByCountyID(int CountyID)
{
List<CityModel> ListOfCities = new List<CityModel>();
ListOfCities = GetAllCities().Where(s => s.CountyID == CountyID).ToList();
SelectList SelectListOfCities = new SelectList(ListOfCities, "ID", "CityName", 0);
return Json(SelectListOfCities);
}
// Populate counties collection Or you can extract from DB
public List<CountyModel> GetAllCounties()
{
List<CountyModel> Countymodel = new List<CountyModel>();
Countymodel.Add(new CountyModel { ID = 0, CountyName = "Select a county" });
Countymodel.Add(new CountyModel { ID = 1, CountyName = "Freedom county" });
Countymodel.Add(new CountyModel { ID = 2, CountyName= "Not so good county" });
Countymodel.Add(new CountyModel { ID = 3, CountyName = "Best county" });
Countymodel.Add(new CountyModel { ID = 4, CountyName = "Crazy county" });
Countymodel.Add(new CountyModel { ID = 5, CountyName = "Happy county" });
return Countymodel;
}
//Populate cities collection Or you can extract from DB
public List<CityModel> GetAllCities()
{
List<CityModel> CityModel = new List<CityModel>();
CityModel.Add(new CityModel { ID = 1, CountyID = 3, CityName = "City1-1" });
CityModel.Add(new CityModel { ID = 2, CountyID = 3, CityName = "City2-1" });
CityModel.Add(new CityModel { ID = 3, CountyID = 2, CityName = "City4-1" });
CityModel.Add(new CityModel { ID = 4, CountyID = 2, CityName = "City1-2" });
CityModel.Add(new CityModel { ID = 5, CountyID = 1, CityName = "City1-3" });
CityModel.Add(new CityModel { ID = 6, CountyID = 5, CityName = "City4-2" });
CityModel.Add(new CityModel { ID = 7, CountyID = 5, CityName = "City4-2" });
CityModel.Add(new CityModel { ID = 8, CountyID= 1, CityName = "City4-2" });
CityModel.Add(new CityModel { ID = 9, CountyID = 2, CityName = "City4-2" });
CityModel.Add(new CityModel { ID = 10, CountyID = 4, CityName = "City4-2" });
return CityModel;
}
}
}
and finally your view
@model Alundra.Models.CountyCityViewModel
@{
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<script>
function GetCitieslist(Countyid) {
var procemessage = "<option value='0'> Please wait...</option>";
$("#ddlcity").html(procemessage).show();
var url = '@Url.Action("GetCityByCountyID")';
$.ajax({
url: url,
data: { CountyID: Countyid },
cache: false,
type: "POST",
success: function (data) {
var markup = "<option value='0'>Select City</option>";
for (var i = 0; i < data.length; i++) {
markup += "<option value=" + data[i].Value + ">" + data[i].Text + "</option>";
}
$("#CitiesDropDown").html(markup).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
</script>
<h4><i class="fa fa-connectdevelop fa-3x pull-left fa-border"></i><span class="label label-warning">Cascade Dropdown menues using JQuery</span></h4>
@using (Html.BeginForm())
{
@Html.DropDownListFor(m => m.Countymodel, new SelectList(Model.Countymodel, "ID", "CountyName"), new { @id = "StateDropDown", @onchange = "javascript:GetCitieslist(this.value);" })
<br />
<br />
<select id="CitiesDropDown" name="ddlcity" style="width: 200px">
</select>
}
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
EXTRA: You can implement a loading image while the cities DD is getting the data.
Here's a .net fiddle link to a working example