在MVC4 / Razor中实现Ajax级联下拉列表数组的推荐方法? [英] Recommended way to implement array of Ajax cascading dropdown lists in MVC4/Razor?

查看:167
本文介绍了在MVC4 / Razor中实现Ajax级联下拉列表数组的推荐方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个需要呈现记录网格的基于ASP.NET MVC4 / Razor / C#的应用程序。每行都有几列,可能有100行。



每行都有一个checkbox字段,文本字段,然后是三个级联下拉列表。第一个下拉列表在页面加载中预先填充。第二个需要使用Ajax在第一个下拉列表的更改中填充。第三个从第二个变化。每一行都是分开的,不会互相影响。



推荐的方法是什么?级联下拉列表的各种解决方案仅适用于单个级联列表 - 在放置在foreach循环中时,它们不起作用(对我来说)。



我拥有的骨架如下所示:

  @model IList< MyModel> 

@using(Html.BeginForm(MyAction,Home)){
< table>< tr>< th>使用< / th& th>名称< th>< th>列表A< th>列表B< th>列表C< / th>< / tr>
@ Html.EditorForModel()
< / table>
}

模型看起来像这样:

  public class MyModel 
{
public bool Use {get;组; }
public string Name {get;组; }
public int? ListAId {get;组; }
public int? ListBId {get;组; }
public int? ListCId {get;组; }
public IList< Listalist> ListA {get;组; }
}

共享的EditorTemplates文件MyModel.cshtml遵循以下结构:

  @model MyNamespace.MyModel 
< tr>
< td> @ Html.CheckBoxFor(model => model.Use)< / td>
< td> @ Html.DisplayFor(model => model.Name)< / td>
< td> @ Html.DropDownListFor(model => model.ListAId,new SelectList(Model.ListA,Id,Name,Model.ListAId),)< / td>
< td> ??< / td>
< td> ??< / td>
< / tr>

表示我不确定在这里放置什么。



如何在更改ListA选择框时继续使用Ajax呈现ListB选择框,然后更改ListB提交ListC选择框?

解决方案

查看:





Update1:​​假设有Name ROWID,并列出所有相同的数据源。



Update2: github上可用的示例



根据这些响应:





型号:

  using System.Collections.Generic; 

命名空间MyNamespace
{
public class MyModel
{
public MyModel(){ListA = new List< ListAList>(); }
public bool使用{get;组; }
public string Name {get;组; }
public int? ListAId {get;组; }
public int? ListBId {get;组; }
public int? ListCId {get;组; }
public IList< Listalist> ListA {get;组; }
}

public class ListAList
{
public int Id {get;组; }
public string Name {get;组; }
}

}

家庭控制器中的主要操作:

  public ViewResult MyAction()
{
var model = new List< MyModel>(); (int i = 0; i< 10; i ++)
{
var item = new MyModel()
{
Name = string.Format名称{0},i),
使用=(i%2 == 0),
ListAId = null,
ListBId = null,
ListCId = null
};

for(int j = 0; j< 10; j ++)
{
item.ListA.Add(new ListAList()
{
Id = j,
Name = string.Format(Name {0} - {1},i,j)
});
}
model.Add(item);
}

return View(model);
}

家庭控制器中的数据源提供商:

  public JsonResult PopulateOption(int?listid,string name)
{

// todo:准备数据源过滤器

var sites = new []
{
new {id =1,name =Name 1},
new {id =2 name =Name 2},
new {id =3,name =Name 3},
};
return Json(sites,JsonRequestBehavior.AllowGet);
}

EditorTemplate:

  @model MyNamespace.MyModel 
< tr>
< td> @ Html.CheckBoxFor(model => model.Use)< / td>
< td> @ Html.DisplayFor(model => model.Name)< / td>
< td> @ Html.DropDownListFor(model => model.ListAId,new SelectList(Model.ListA,Id,Name,Model.ListAId),,new {@id = string .Format(ListA {0},Model.Name),@ class =ajaxlistA})< / td>
< td>< select class =ajaxlistBid =ListB @(Model.Name)>< / select>< / td>
< td>< select class =ajaxlistCid =ListC @(Model.Name)>< / select>< / td>
< / tr>

和Ajax功能的主视图:

  @using MyNamespace 
@model IList&MyModel>

@using(Html.BeginForm(MyAction,Home)){
< table>< tr>< th>使用< / th& th>名称< th>< th>列表A< th>列表B< th>列表C< / th>< / tr>
@ Html.EditorForModel()
< / table>
}

< script src =@ Url.Content(〜/ Scripts / jquery-1.7.1.js)type =text / javascript>< /脚本>


< script>
$(document).ready($(function(){
$('。ajaxlistA')。change(function(){
//当第一个选择的值更改触发器ajax请求
list = $(this);
var listvalue = list.val();
var listname = list.attr('id');
$ .getJSON ('@ Url.Action(PopulateOption,Home)',{listid:listvalue,name:listname},function(result){
//假设服务器返回json更新$ b的内容$ b // second selectbox
var listB = $('#'+ listname).parent()。parent()。find('。ajaxlistB');
listB.empty();
$ .each(result,function(index,item){
listB.append(
$('< option />',{
value:item.id,
文本:item.name
})
);
});
});
});
$('。ajaxlistB')。change(function(){
//当第一个选择更改的值触发ajax请求
list = $(this);
var listvalue = list.val();
var listname = list.attr('id');
$ .getJSON('@ Url.Action(PopulateOption,Home)' {listid:listvalue,name:listname},function(result){
//假设服务器返回json更新
的内容//第二个选择框
var listB = $('# '+ listname).parent()。parent()。find('。ajaxlistC');
listB.empty();
$ .each(result,function(index,item){
listB.append(
$('< option />',{
value:item.id,
text:item.name
})
);
}) ;
});
});
}));
< / script>

结果:




I am writing an ASP.NET MVC4 / Razor / C# based application that needs to render a grid of records. Each row has several columns, and there may be 100 or so rows.

Each row has a checkbox field, text field and then three cascading dropdown lists. The first dropdown is prepopulated on page load. The second needs to be populated using Ajax on change of the first dropdown list. The third from a change on the second. Each row is separate and does not influence each other.

What is the recommended way to implement something like this? The various solutions for cascading dropdown lists are only for single cascading lists - they do not work (for me) when placed inside a foreach loop.

The skeleton of what I have is shown below:

@model IList<MyModel>

@using (Html.BeginForm("MyAction", "Home")) {
  <table><tr><th>Use?</th><th>Name</th><th>List A</th><th>List B</th><th>List C</th></tr>
  @Html.EditorForModel()
</table>
}

The model looks something like this:

public class MyModel
{
  public bool Use { get; set; }
  public string Name { get; set; }
  public int? ListAId { get; set; }
  public int? ListBId { get; set; }
  public int? ListCId { get; set; }
  public IList<ListAList> ListA { get; set; }
}

The shared EditorTemplates file MyModel.cshtml follows this structure:

@model MyNamespace.MyModel
<tr>
  <td>@Html.CheckBoxFor(model => model.Use)</td>
  <td>@Html.DisplayFor(model => model.Name)</td>
  <td>@Html.DropDownListFor(model => model.ListAId, new SelectList(Model.ListA, "Id", "Name", Model.ListAId), "")</td>
  <td>??</td>
  <td>??</td>
</tr>

The ?? indicates I am unsure what to put in here.

How do I proceed to render the ListB select box using Ajax on change of the ListA select box, then on change of ListB render the ListC select box?

解决方案

check this:

Update1: Suppose that there is Name ROWID, (and list all the same data source).

Update2: the example available on github

Based on these responses:

Model:

using System.Collections.Generic;

namespace MyNamespace
{
    public class MyModel
    {
        public MyModel() { ListA = new List<ListAList>(); }
        public bool Use { get; set; }
        public string Name { get; set; }
        public int? ListAId { get; set; }
        public int? ListBId { get; set; }
        public int? ListCId { get; set; }
        public IList<ListAList> ListA { get; set; }
    }

    public class ListAList
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

}

Main action in the Home Controller:

public ViewResult MyAction()
{
    var model = new List<MyModel>();
    for (int i = 0; i < 10; i++)
    {
        var item = new MyModel() 
            {
            Name = string.Format("Name{0}", i),
            Use = (i % 2 == 0),
            ListAId = null,
            ListBId = null,
            ListCId = null
            };

        for (int j = 0; j < 10; j++)
        {
            item.ListA.Add( new ListAList() 
                {
                    Id=j,
                    Name = string.Format("Name {0}-{1}",i,j)
                });
        }
        model.Add(item);
    }

    return View(model);
}

Data source provider in the Home controller:

public JsonResult PopulateOption(int? listid, string name)
{

    //todo: preparing the data source filter

    var sites = new[]
    {
        new { id = "1", name = "Name 1" },
        new { id = "2", name = "Name 2" },
        new { id = "3", name = "Name 3" },
    };
    return Json(sites, JsonRequestBehavior.AllowGet);
}

EditorTemplate:

@model MyNamespace.MyModel
<tr>
    <td>@Html.CheckBoxFor(model => model.Use)</td>
    <td>@Html.DisplayFor(model => model.Name)</td>
    <td>@Html.DropDownListFor(model => model.ListAId, new SelectList(Model.ListA, "Id", "Name", Model.ListAId), "", new { @id = string.Format("ListA{0}", Model.Name), @class="ajaxlistA" })</td>
    <td><select class="ajaxlistB" id="ListB@(Model.Name)"></select></td>
    <td><select class="ajaxlistC" id="ListC@(Model.Name)"></select></td>
</tr>

And the main view with Ajax functions:

@using MyNamespace
@model IList<MyModel>

@using (Html.BeginForm("MyAction", "Home")) {
  <table><tr><th>Use?</th><th>Name</th><th>List A</th><th>List B</th><th>List C</th></tr>
@Html.EditorForModel()
</table>
}

<script src="@Url.Content("~/Scripts/jquery-1.7.1.js")" type="text/javascript"></script>


<script>
    $(document).ready( $(function () {
        $('.ajaxlistA').change(function () {
            // when the value of the first select changes trigger an ajax request
            list = $(this);
            var listvalue = list.val();
            var listname = list.attr('id');
            $.getJSON('@Url.Action("PopulateOption", "Home")', { listid: listvalue, name: listname }, function (result) {
                // assuming the server returned json update the contents of the 
                // second selectbox
                var listB = $('#' + listname).parent().parent().find('.ajaxlistB');
                listB.empty();
                $.each(result, function (index, item) {
                    listB.append(
                        $('<option/>', {
                            value: item.id,
                            text: item.name
                        })
                    );
                });
            });
        });
        $('.ajaxlistB').change(function () {
            // when the value of the first select changes trigger an ajax request
            list = $(this);
            var listvalue = list.val();
            var listname = list.attr('id');
            $.getJSON('@Url.Action("PopulateOption", "Home")', { listid: listvalue, name: listname }, function (result) {
                // assuming the server returned json update the contents of the 
                // second selectbox
                var listB = $('#' + listname).parent().parent().find('.ajaxlistC');
                listB.empty();
                $.each(result, function (index, item) {
                    listB.append(
                        $('<option/>', {
                            value: item.id,
                            text: item.name
                        })
                    );
                });
            });
        });
    }));
</script>

And the result:

这篇关于在MVC4 / Razor中实现Ajax级联下拉列表数组的推荐方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆