Заполнение раскрывающегося списка с результатом JSON - каскадный DropDown с использованием MVC3, JQuery, Ajax, JSON
У меня есть каскадный утопленник с помощью MVC. Примерно так: если вы выберете страну в первом раскрывающемся списке, соответственно, должны быть заполнены государства этой страны во втором.
На данный момент все кажется хорошо, и я получаю ответ Json (видел его с помощью инструментов F12), и это выглядит примерно так [{ "stateId":"01", "StateName": "arizona" } , { "stateId" : "02", "StateName":"California" }, etc..] ..
Я хотел бы знать, как заполнить мой second-dropdown
с этими данными. Мой второй выпадающий идентификатор "StateID
". Любая помощь будет принята с благодарностью.
Ниже приведен код, используемый для создания ответа JSON с сервера:
[HttpPost]
public JsonResult GetStates(string CountryID)
{
using (mdb)
{
var statesResults = from q in mdb.GetStates(CountryID)
select new Models.StatesDTO
{
StateID = q.StateID,
StateName = q.StateName
};
locations.statesList = stateResults.ToList();
}
JsonResult result = new JsonResult();
result.Data = locations.statesList;
return result;
}
Ниже приведен HTML-код на стороне клиента, мой код бритвы и мой скрипт. Я хочу написать код внутри "success
: "так что он населяет штаты dropdown
с данными JSON.
<script type="text/javascript">
$(function () {
$("select#CountryID").change(function (evt) {
if ($("select#CountryID").val() != "-1") {
$.ajax({
url: "/Home/GetStates",
type: 'POST',
data: { CountryID: $("select#CountryID").val() },
success: function () { alert("Data retrieval successful"); },
error: function (xhr) { alert("Something seems Wrong"); }
});
}
});
});
</script>
7 ответов
Начнем с того, что внутри функции обработчика событий jQuery this
относится к элементу, вызвавшему событие, поэтому вы можете заменить дополнительные вызовы на $("select#CountryID")
с $(this)
, Хотя там, где это возможно, вы должны обращаться к свойствам элементов напрямую, а не с помощью функций jQuery, поэтому вы можете просто this.value
скорее, чем $(this).val()
или же $("select#CountryID").val()
,
Затем внутри ваших вызовов AJAX success
функция, вам нужно создать серию <option>
элементы. Это можно сделать с помощью базы jQuery()
функция (или $()
коротко). Это будет выглядеть примерно так:
$.ajax({
success: function(states) {
// states is your JSON array
var $select = $('#StateID');
$.each(states, function(i, state) {
$('<option>', {
value: state.stateId
}).html(state.StateName).appendTo($select);
});
}
});
Вот демоверсия jsFiddle.
Соответствующие документы JQuery:
jQuery.each()
jQuery()
В моем проекте я делаю так, это ниже
В МОЕМ контроллере
public JsonResult State(int countryId)
{
var stateList = CityRepository.GetList(countryId);
return Json(stateList, JsonRequestBehavior.AllowGet);
}
В модели
public IQueryable<Models.State> GetList(int CountryID)
{
var statelist = db.States.Where(x => x.CountryID == CountryID).ToList().Select(item => new State
{
ID = item.ID,
StateName = item.StateName
}).AsQueryable();
return statelist;
}
Ввиду
<script type="text/javascript">
function cascadingdropdown() {
$("#stateID").empty();
$("#stateID").append("<option value='0'>--Select State--</option>");
var countryID = $('#countryID').val();
var Url="@Url.Content("~/City/State")";
$.ajax({
url:Url,
dataType: 'json',
data: { countryId: countryID },
success: function (data) {
$("#stateID").empty();
$("#stateID").append("<option value='0'>--Select State--</option>");
$.each(data, function (index, optiondata) {
$("#stateID").append("<option value='" + optiondata.ID + "'>" + optiondata.StateName + "</option>");
});
}
});
}
</script>
я думаю это поможет тебе......
Шаг 1:
Сначала нам нужен класс модели, который определяет свойства для хранения данных.
public class ApplicationForm { public string Name { get; set; } public string State { get; set; } public string District { get; set; } }
Шаг 2:
Теперь нам нужен начальный контроллер, который будет возвращать представление Index, упаковывая список состояний в ViewBag.StateName.
public ActionResult Index() { List<SelectListItem> state = new List<SelectListItem>(); state.Add(new SelectListItem { Text = "Bihar", Value = "Bihar" }); state.Add(new SelectListItem { Text = "Jharkhand", Value = "Jharkhand" }); ViewBag.StateName = new SelectList(state, "Value", "Text"); return View(); }
В приведенном выше контроллере у нас есть список, содержащий состояния, присоединенные к ViewBag.StateName. Мы могли бы получить список состояний из базы данных, используя запрос Linq или что-то в этом роде, и упаковать его во ViewBag.StateName, так что давайте перейдем к данным в памяти.
Шаг 3:
Когда у нас есть контроллер, мы можем добавить его представление и начать создавать форму Razor.
@Html.ValidationSummary("Please correct the errors and try again.") @using (Html.BeginForm()) { <fieldset> <legend>DropDownList</legend> @Html.Label("Name") @Html.TextBox("Name") @Html.ValidationMessage("Name", "*") @Html.Label("State") @Html.DropDownList("State", ViewBag.StateName as SelectList, "Select a State", new { id = "State" }) @Html.ValidationMessage("State", "*") @Html.Label("District") <select id="District" name="District"></select> @Html.ValidationMessage("District", "*") <p> <input type="submit" value="Create" id="SubmitId" /> </p> </fieldset> }
Вы можете видеть, что я добавил правильные метки и поля проверки для каждого элемента управления вводом (два DropDownList и один TextBox), а также итоговую сумму проверки вверху. Обратите внимание, что я использовал HTML вместо Razor helper, это потому, что когда мы выполняем вызов JSON с использованием jQuery, мы вернем HTML-разметку предварительно заполненного тега option. Теперь давайте добавим код jQuery на странице просмотра выше.
Шаг 4:
Вот код jQuery, вызывающий JSON-вызов DDL-метода с именем контроллера DistrictList с параметром (который является выбранным именем состояния). Метод DistrictList возвращает данные JSON. С помощью возвращенных данных JSON мы создаем тег HTML-разметки и присоединяем эту HTML-разметку к 'District', который является элементом управления DOM.
@Scripts.Render("~/bundles/jquery") <script type="text/jscript"> $(function () { $('#State').change(function () { $.getJSON('/DDL/DistrictList/' + $('#State').val(), function (data) { var items = '<option>Select a District</option>'; $.each(data, function (i, district) { items += "<option value='" + district.Value + "'>" + district.Text + "</option>"; }); $('#District').html(items); }); }); }); </script>
Пожалуйста, убедитесь, что вы используете ссылки на библиотеки jQuery перед тегом.
Шаг 5:
В приведенном выше коде jQuery мы выполняем JSON-вызов DDL-метода с именем контроллера DistrictList с параметром. Вот код метода DistrictList, который будет возвращать данные JSON.
public JsonResult DistrictList(string Id) { var district = from s in District.GetDistrict() where s.StateName == Id select s; return Json(new SelectList(district.ToArray(), "StateName", "DistrictName"), JsonRequestBehavior.AllowGet); }
Обратите внимание, что метод DistrictList будет принимать параметр 'Id' (это всегда должен быть 'Id') типа строки, отправляемого вызовом jQuery JSON. Внутри метода я использую параметр "Id" в запросе linq, чтобы получить список совпадающих районов, и концептуально в списке данных районов должно быть поле состояния. Также обратите внимание, что в запросе linq я делаю вызов метода District.GetDistrict().
Шаг 6:
В приведенном выше вызове метода District.GetDistrict () District является моделью, в которой есть метод GetDistrict (). И я использую метод GetDistrict () в запросе linq, поэтому этот метод должен иметь тип IQueryable. Вот код модели.
public class District { public string StateName { get; set; } public string DistrictName { get; set; } public static IQueryable<District> GetDistrict() { return new List<District> { new District { StateName = "Bihar", DistrictName = "Motihari" }, new District { StateName = "Bihar", DistrictName = "Muzaffarpur" }, new District { StateName = "Bihar", DistrictName = "Patna" }, new District { StateName = "Jharkhand", DistrictName = "Bokaro" }, new District { StateName = "Jharkhand", DistrictName = "Ranchi" }, }.AsQueryable(); } }
Шаг 7:
Вы можете запустить приложение здесь, потому что каскадный выпадающий список уже готов. Я собираюсь сделать некоторые проверки работ, когда пользователь нажимает кнопку отправки. Итак, я добавлю еще один результат действия версии POST.
[HttpPost] public ActionResult Index(ApplicationForm formdata) { if (formdata.Name == null) { ModelState.AddModelError("Name", "Name is required field."); } if (formdata.State == null) { ModelState.AddModelError("State", "State is required field."); } if (formdata.District == null) { ModelState.AddModelError("District", "District is required field."); } if (!ModelState.IsValid) { //Populate the list again List<SelectListItem> state = new List<SelectListItem>(); state.Add(new SelectListItem { Text = "Bihar", Value = "Bihar" }); state.Add(new SelectListItem { Text = "Jharkhand", Value = "Jharkhand" }); ViewBag.StateName = new SelectList(state, "Value", "Text"); return View("Index"); } //TODO: Database Insertion return RedirectToAction("Index", "Home"); }
Попробуйте это внутри вызова ajax:
$.ajax({
url: "/Home/GetStates",
type: 'POST',
data: {
CountryID: $("select#CountryID").val()
},
success: function (data) {
alert("Data retrieval successful");
var items = "";
$.each(data, function (i, val) {
items += "<option value='" + val.stateId + "'>" + val.StateName + "</option>";
});
$("select#StateID").empty().html(items);
},
error: function (xhr) {
alert("Something seems Wrong");
}
});
РЕДАКТИРОВАТЬ 1
success: function (data) {
$.each(data, function (i, val) {
$('select#StateID').append(
$("<option></option>")
.attr("value", val.stateId)
.text(val.StateName));
});
},
<script type="text/javascript">
$(document).ready(function () {
$("#ddlStateId").change(function () {
var url = '@Url.Content("~/")' + "Home/Cities_SelectedState";
var ddlsource = "#ddlStateId";
var ddltarget = "#ddlCityId";
$.getJSON(url, { Sel_StateName: $(ddlsource).val() }, function (data) {
$(ddltarget).empty();
$.each(data, function (index, optionData) {
$(ddltarget).append("<option value='" + optionData.Text + "'>" + optionData.Value + "</option>");
});
});
});
});
</script>
Попробуй это:
public JsonResult getdist(int stateid)
{
var res = objdal.getddl(7, stateid).Select(m => new SelectListItem { Text = m.Name, Value = m.Id.ToString() });
return Json(res,JsonRequestBehavior.AllowGet);
}
Вам следует рассмотреть возможность использования некоторого механизма представления на стороне клиента, который связывает модель (в вашем случае JSON, возвращенную из API) с шаблоном (HTML-код для SELECT). Angular и React могут быть сложными для этого варианта использования, но механизм представления JQuery позволяет легко загружать модель JSON в шаблон, используя MVC-подобный подход:
<script type="text/javascript">
$(function () {
$("select#CountryID").change(function (evt) {
if ($("select#CountryID").val() != "-1") {
$.ajax({
url: "/Home/GetStates",
type: 'POST',
data: { CountryID: $("select#CountryID").val() },
success: function (response) {
$("#stateID").empty();
$("#stateID").view(response);
},
error: function (xhr) { alert("Something seems Wrong"); }
});
}
});
});
</script>
Это намного чище, чем генерация необработанного HTML в JavaScript. Подробности смотрите здесь: https://jocapc.github.io/jquery-view-engine/docs/ajax-dropdown
Я знаю, что этому посту год, но я нашел его, и вы тоже. Я использую следующее решение, и оно работает очень хорошо. Строго набирается без необходимости писать одну строчку Javascript.
http://mvc4ajaxdropdownlist.codeplex.com/
Вы можете скачать его через Visual Studio в виде пакета NuGet.