Recommended way to implement array of Ajax cascadi

2019-08-12 18:41发布

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?

1条回答
beautiful°
2楼-- · 2019-08-12 19:33

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:

the result

查看更多
登录 后发表回答