Заполнение раскрывающегося списка с результатом 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.

Другие вопросы по тегам