Отображение раскрывающегося списка с результатом JSON - каскадирование DropDown с использованием MVC3, JQuery, Ajax, JSON
У меня есть каскадный капля-утопление с использованием mvc. Что-то вроде, если вы выберете страну в первом выпадающем списке, состояния этой страны во втором должны быть заполнены соответствующим образом.
На данный момент все кажется прекрасным, и я получаю ответ Json (видел его с помощью инструментов F12), и он выглядит примерно как [{ "stateId": "01", "StateName": "arizona" }, { "stateId": "02", "StateName": "California" } и т.д.]..
Я хотел бы знать, как заполнить мой второй выпадающий список этими данными. Мой второй раскрывающийся идентификатор - "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-код, мой бритвенный код и мой script. Я хочу написать код внутри "success:", чтобы он заполнил раскрывающийся список состояний данными 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>
Ответы
Ответ 1
Для начала внутри 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 demo.
Соответствующие документы jQuery:
Ответ 2
В моем проекте я делаю это ниже
iN MY Controller
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>
Я думаю, это поможет вам...
Ответ 3
Шаг 1:
-
Вначале нам нужен класс модели, который определяет свойства для хранения данных.
public class ApplicationForm
{
public string Name { get; set; }
public string State { get; set; }
public string District { get; set; }
}
Шаг 2:
-
Теперь нам нужен начальный контроллер, который вернет представление индекса, упаковывая список состояний в 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, потому что, когда мы вызываем JSON-вызов с использованием jQuery, он возвращает HTML-разметку предварительно заполненного тега опции. Теперь давайте добавим код 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");
}
Ответ 4
Попробуйте это внутри вызова 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));
});
},
Ответ 5
<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>
Ответ 6
Я знаю, что этот пост - год, но я нашел его, и вы тоже. Я использую следующее решение, и оно работает очень хорошо. Сильная типизация без необходимости писать одну строку Javascript.
mvc4ajaxdropdownlist.codeplex.com
Вы можете загрузить его через Visual Studio в виде пакета NuGet.
Ответ 7
Вам следует рассмотреть возможность использования некоторого механизма просмотра на стороне клиента, который привязывает модель (в вашем случае 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