使用 JSON 结果填充下拉列表 - 使用 MVC3、JQuery、Ajax、JSON 级联下拉列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14339089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:28:24  来源:igfitidea点击:

Populating dropdown with JSON result - Cascading DropDown using MVC3, JQuery, Ajax, JSON

asp.net-mvcjsonjquery

提问by Ren

I've got a cascading drop-drown using mvc. Something like, if you select a country in the first-dropdown, the states of that country in the second one should be populated accordingly.

我有一个使用 mvc 的级联溺水。例如,如果您在第一个下拉列表中选择一个国家,则应相应填充第二个下拉列表中该国家/地区的州。

At the moment, all seems fine and I'm getting Json response (saw it using F12 tools), and it looks something like [{ "stateId":"01", "StateName": "arizona" } , { "stateId" : "02", "StateName":"California" }, etc..] ..

目前,一切似乎都很好,我收到了 Json 响应(使用 F12 工具看到它),它看起来像 [{ "stateId":"01", "StateName": "arizona" } , { "stateId" : "02", "StateName":"California" }, etc..] ..

I'd like to know how to populate my second-dropdownwith this data. My second drop-down's id is "StateID". Any help would be greatly appreciated.

我想知道如何second-dropdown用这些数据填充我的。我的第二个下拉列表的 ID 是“ StateID”。任何帮助将不胜感激。

Below is the code used to produce the JSON Response from the server:

下面是用于从服务器生成 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;
}

Below is the client-side HTML, my razor-code and my script. I want to write some code inside "success:" so that it populates the States dropdownwith the JSON data.

下面是客户端 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> 

回答by Anthony Grist

To begin with, inside a jQuery event handler function thisrefers to the element that triggered the event, so you can replace the additional calls to $("select#CountryID")with $(this). Though where possible you should access element properties directly, rather than using the jQuery functions, so you could simply do this.valuerather than $(this).val()or $("select#CountryID").val().

首先,内部的一个jQuery事件处理函数this是指触发事件的元素,这样你就可以取代额外调用$("select#CountryID")$(this)。尽管在可能的情况下,您应该直接访问元素属性,而不是使用 jQuery 函数,因此您可以简单地执行this.value而不是$(this).val()or $("select#CountryID").val()

Then, inside your AJAX calls successfunction, you need to create a series of <option>elements. That can be done using the base jQuery()function (or $()for short). That would look something like this:

然后,在您的 AJAX 调用success函数中,您需要创建一系列<option>元素。这可以使用 basejQuery()函数(或$()简称)来完成。这看起来像这样:

$.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);
        });
    }
});

Here's a jsFiddle demo.

这是一个jsFiddle 演示

Relevant jQuery docs:

相关的 jQuery 文档:

回答by Rajpurohit

In my project i am doing like this it's below

在我的项目中,我是这样做的,它在下面

iN MY Controller

在我的控制器中

        public JsonResult State(int countryId)
        {               
            var stateList = CityRepository.GetList(countryId);
            return Json(stateList, JsonRequestBehavior.AllowGet);
        }

In Model

在模型中

        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;
       }

In view

在视图中

<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>

i think this will help you......

我想这会帮助你......

回答by kavitha Reddy

Step 1:

第1步:

  • At very first, we need a model class that defines properties for storing data.

    public class ApplicationForm
    {
        public string Name { get; set; }
        public string State { get; set; }
        public string District { get; set; }
    }
    

    Step 2:

  • Now, we need an initial controller that will return an Index view by packing list of states in 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();
    }
    

    In above controller we have a List containing states attached to ViewBag.StateName. We could get list of states form database using Linq query or something and pack it to ViewBag.StateName, well let's go with in-memory data.

    Step 3:

  • Once we have controller we can add its view and start creating a Razor form.

      @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>
    }
    

    You can see I have added proper labels and validation fields with each input controls (two DropDownList and one TextBox) and also a validation summery at the top. Notice, I have used which is HTML instead of Razor helper this is because when we make JSON call using jQuery will return HTML markup of pre-populated option tag. Now, let's add jQuery code in the above view page.

    Step 4:

    Here is the jQuery code making JSON call to DDL named controller's DistrictList method with a parameter (which is selected state name). DistrictList method will returns JSON data. With the returned JSON data we are building tag HTML markup and attaching this HTML markup to ‘District' which is DOM control.

      @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>
    

    Please make sure you are using jQuery library references before the tag.

    Step 5:

  • In above jQuery code we are making a JSON call to DDL named controller's DistrictList method with a parameter. Here is the DistrictList method code which will return JSON data.

    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);
    }
    

    Please note, DistrictList method will accept an ‘Id' (it should be 'Id' always) parameter of string type sent by the jQuery JSON call. Inside the method, I am using ‘Id' parameter in linq query to get list of matching districts and conceptually, in the list of district data there should be a state field. Also note, in the linq query I am making a method call District.GetDistrict().

    Step 6:

    In above District.GetDistrict() method call, District is a model which has a GetDistrict() method. And I am using GetDistrict() method in linq query, so this method should be of type IQueryable. Here is the model code.

    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();
        }
    }
    

    Step 7:

    You can run the application here because cascading dropdownlist is ready now. I am going to do some validation works when user clicks the submit button. So, I will add another action result of POST version.

    [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");
    }
    
  • 首先,我们需要一个模型类来定义存储数据的属性。

    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 助手,这是因为当我们使用 jQuery 进行 JSON 调用时,将返回预填充选项标签的 HTML 标记。现在,让我们在上面的视图页面中添加 jQuery 代码。

    第四步:

    这是使用参数(选择的状态名称)对 DDL 命名控制器的 DistrictList 方法进行 JSON 调用的 jQuery 代码。DistrictList 方法将返回 JSON 数据。使用返回的 JSON 数据,我们正在构建标签 HTML 标记并将此 HTML 标记附加到 DOM 控件“District”。

      @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 代码中,我们使用参数对名为控制器的 DistrictList 方法的 DDL 进行 JSON 调用。这是将返回 JSON 数据的 DistrictList 方法代码。

    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 方法将接受 jQuery JSON 调用发送的字符串类型的“Id”(它应该始终为“Id”)参数。在该方法中,我在 linq 查询中使用 'Id' 参数来获取匹配区列表,从概念上讲,在区数据列表中应该有一个 state 字段。另请注意,在 linq 查询中,我正在调用 District.GetDistrict() 方法。

    第 6 步:

    在上面 District.GetDistrict() 方法调用中,District 是一个具有 GetDistrict() 方法的模型。我在 linq 查询中使用 GetDistrict() 方法,所以这个方法应该是 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");
    }
    

回答by pala?н

Try this inside the ajax call:

在 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");
  }
});

EDIT 1

编辑 1

success: function (data) {

  $.each(data, function (i, val) {
    $('select#StateID').append(
    $("<option></option>")
      .attr("value", val.stateId)
      .text(val.StateName));
  });
},

回答by kavitha Reddy

   <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>

回答by Frank Bonnet

I know this post is a year old but I found it and so might you. I use the following solution and it works very well. Strong typed without the need to write a single line of Javascript.

我知道这篇文章已经有一年了,但我找到了它,你也可以。我使用以下解决方案,效果很好。强类型无需编写一行 Javascript。

mvc4ajaxdropdownlist.codeplex.com

mvc4ajaxdropdownlist.codeplex.com

You can download it via Visual Studio as a NuGet package.

您可以通过 Visual Studio 将其下载为 NuGet 包。

回答by Jovan MSFT

You should consider using some client-side view engine that binds a model (in your case JSON returned from API) to template (HTML code for SELECT). Angular and React might be to complex for this use case, but JQuery view engineenables you to easily load JSON model into template using MVC-like approach:

您应该考虑使用一些客户端视图引擎,将模型(在您的情况下是从 API 返回的 JSON)绑定到模板(用于 SELECT 的 HTML 代码)。对于这个用例,Angular 和 React 可能会很复杂,但是JQuery 视图引擎使您能够使用类似 MVC 的方法轻松地将 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 (response) {
                             $("#stateID").empty();
                             $("#stateID").view(response);
                    },
                    error: function (xhr) { alert("Something seems Wrong"); }
                });
            }
        });
    });
</script> 

It is much cleaner that generating raw HTML in JavaScript. See details here: https://jocapc.github.io/jquery-view-engine/docs/ajax-dropdown

在 JavaScript 中生成原始 HTML 要干净得多。在此处查看详细信息:https: //jocapc.github.io/jquery-view-engine/docs/ajax-dropdown

回答by Meera

Try this:

尝试这个:

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);
}