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

Posted

技术标签:

【中文标题】使用 JSON 结果填充下拉列表 - 使用 MVC3、JQuery、Ajax、JSON 的级联下拉【英文标题】:Populating dropdown with JSON result - Cascading DropDown using MVC3, JQuery, Ajax, JSON 【发布时间】:2012-12-29 15:09:22 【问题描述】:

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

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

我想知道如何用这些数据填充我的second-dropdown。我的第二个下拉列表的 id 是“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:”中编写一些代码,以便使用 JSON 数据填充州 dropdown

<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 指的是触发事件的元素,因此您可以用$(this) 替换对$("select#CountryID") 的额外调用。尽管您应该尽可能直接访问元素属性,而不是使用 jQuery 函数,因此您可以简单地使用 this.value 而不是 $(this).val()$("select#CountryID").val()

然后,在您的 AJAX 调用 success 函数中,您需要创建一系列 &lt;option&gt; 元素。这可以使用基本的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 文档:

jQuery.each() jQuery()

【讨论】:

非常感谢您的帮助..!! 每个迭代状态(第一个参数)。状态被传递给成功函数。 States 是从服务器返回的数据。 @user1980311 $("this") 不正确 - 这会将字符串“this”传递给函数,您实际上想要传递 this 所指的内容,因此请不要使用双引号;不过,正如我所说,使用this.value 更可取(它更容易输入,更容易阅读,消除了对 jQuery 函数的调用)。 关于$.each() 调用:被分配为success 函数的匿名函数有一个名为states 的参数。当 jQuery 成功接收到来自服务器的响应时,它将接收到的任何内容作为参数传递给该函数。 states 只是一个给定的名称,以便可以在函数内部引用响应(在本例中为数组),理论上它几乎可以调用任何东西。 未捕获类型错误:无法读取 jquery.selectric.js 中未定义的属性“offsetTop”。似乎比 ajax 查询加载 dom 更快【参考方案2】:

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

我的控制器

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

第 4 步:

这里是 jQuery 代码,使用参数(选择状态名称)对 DDL 命名控制器的 DistrictList 方法进行 JSON 调用。 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”参数来获取匹配地区的列表,从概念上讲,在地区数据列表中应该有一个状态字段。另请注意,在 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");

【讨论】:

【参考方案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));
  );
,

【讨论】:

感谢您的回复。它现在可以工作了,但是你会推荐在 jquery 中使用 html 标签吗?使用您遵循的类似方法还有其他更好的方法吗? - 谢谢 @user1980311:是的,当然有更好的方法。试试更新的代码。 酷。我现在就试试这个。只是想知道,我可以使用类似的方法来更新 或

,或者可能是 Jquery 中的手风琴......?..-谢谢

是的,在每个循环中,您可以将 json 内容附加到 &lt;div&gt;,如 jsfiddle.net/tnFzL【参考方案5】:

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

mvc4ajaxdropdownlist.codeplex.com

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

【讨论】:

【参考方案6】:

您应该考虑使用一些客户端视图引擎,将模型(在您的情况下是从 API 返回的 JSON)绑定到模板(用于 SELECT 的 HTML 代码)。对于这个用例,Angular 和 React 可能会很复杂,但 JQuery view engine 使您能够使用类似 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> 

在 JavaScript 中生成原始 HTML 更加简洁。在此处查看详细信息:https://jocapc.github.io/jquery-view-engine/docs/ajax-dropdown

【讨论】:

【参考方案7】:

试试这个:

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

【讨论】:

【参考方案8】:
<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>

【讨论】:

以上是关于使用 JSON 结果填充下拉列表 - 使用 MVC3、JQuery、Ajax、JSON 的级联下拉的主要内容,如果未能解决你的问题,请参考以下文章

MVC 4,选择自动完成值时如何填充 3 个文本框?

如何在 React 中用 JSON 数据填充下拉列表?

如何通过 ajax 使用数据库数据填充 ASP.NET MVC 4 下拉列表

MVC 视图 - 无法在选择下拉列表中填充列表

如何使用对象 MVC 5 C# 的 Javascript 列表填充剃刀 DropDownListFor

根据上一个列表中选择的值填充下拉列表(asp.net mvc3)