ASP.NET MVC 级联下拉菜单 [英] ASP.NET MVC cascading dropdown

查看:23
本文介绍了ASP.NET MVC 级联下拉菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据库中有三个表,如下所示:

大学身份证名称1 安2 乙学院id id_uni 名称1 1 AA2 1 AA咖啡馆id id_uni id_faculty 名称1 1 1 毫升

我想创建一个级联下拉菜单,让我可以先选择一所大学,然后是学院,然后是咖啡馆.下面的代码是我到目前为止所尝试的.

 public ActionResult Create(){ViewBag.fak_kod = new SelectList(db.Fakulteler, "id", "adi");ViewBag.unikod = new SelectList(db.Universitetler, "id", "adi");返回视图();}//POST: kafedras/创建//为了防止过度发布攻击,请启用您要绑定的特定属性,例如//更多详细信息,请参见 http://go.microsoft.com/fwlink/?LinkId=317598.[HttpPost][验证AntiForgeryToken]public ActionResult Create([Bind(Include = "id,unikod,fak_kod,adi")] kafedra kafedra){如果(模型状态.IsValid){db.kafedra.Add(kafedra);db.SaveChanges();return RedirectToAction("索引");}ViewBag.fak_kod = new SelectList(db.Fakulteler, "id", "adi", kafedra.fak_kod);ViewBag.unikod = new SelectList(db.Universitetler, "id", "adi", kafedra.unikod);返回视图(kafedra);}

还有这个 cshtml

<h4>kafedra</h4><小时/>@Html.ValidationSummary(true, "", new { @class = "text-danger" })<div class="form-group">@Html.LabelFor(model => model.unikod, "unikod", htmlAttributes: new { @class = "control-label col-md-2" })<div class="col-md-10">@Html.DropDownList("unikod", null, htmlAttributes: new { @class = "form-control" })@Html.ValidationMessageFor(model => model.unikod, "", new { @class = "text-danger" })

<div class="form-group">@Html.LabelFor(model => model.fak_kod, "fak_kod", htmlAttributes: new { @class = "control-label col-md-2" })<div class="col-md-10">@Html.DropDownList("fak_kod", null, htmlAttributes: new { @class = "form-control" })@Html.ValidationMessageFor(model => model.fak_kod, "", new { @class = "text-danger" })

如何更新此代码以创建包含三个表的级联下拉列表?

解决方案

首先,创建一个视图模型,该模型具有渲染选项和存储所选项目值的属性.

公共类 CreateVm{[必需的]公共 int SelectedUniversity { set;get;}[必需的]公共 int SelectedFaculty { set;get;}公共列表大学{设置;获取;}公共列表院系{设置;获取;}公共 CreateVm(){this.Faculties = new List();this.Universities = new List();}}

现在在您的 GET 操作中,创建一个对象,加载 Universities 属性并将对象发送到视图

public AcitonResult Create(){var vm=new CreateVm();vm.Universities=GetUniversities();返回视图(vm);}私人列表获取大学(){返回 db.Universitetler.Select(x=>new SelectListItem { Value = x.Id,文字 = x.Name).ToList();}

现在在您的视图中,它是我们的 CreateVm 视图模型的强类型.我们将使用 DropDownListFor 辅助方法来呈现下拉列表

@model CreateVm@using (Html.BeginForm("Create", "Home")){@Html.DropDownListFor(a=>a.SelectedUniversity,Model.Universities,"选择一个")@Html.DropDownListFor(a => a.SelectedFaculty , Model.Faculties, "选择一个",new { data_url = Url.Action("GetFaculties") })<输入类型=提交"/>}

这将呈现 2 个下拉菜单,一个带有大学选项,第二个是空的(因为我们没有将任何内容加载到 Faculties 属性).现在我们将有一些 javascript(我们在这里使用 jquery 以便于 DOM 操作),它将侦听第一个下拉列表(大学)的更改事件,读取选定的值并对 GetFaculties<进行 ajax 调用/code> 方法并传递选定的大学选项值.

你可以看到,我为第二个下拉列表设置了一个 html5 数据属性,我将相对 url 存储到 GetFaculties 方法.因此,在我的 javascript 中,我可以简单地读取此数据属性值并调用该 url 以获取数据.

$(function () {$("#SelectedUniversity").change(function () {var v = $(this).val();var url = $("#SelectedFaculty").data("url") + '?u=' + v;var $fac= $("#SelectedFaculty");$.getJSON(url, function (data) {$fac.empty();$.each(data, function (i, item) {$fac.append($("

现在,让我们添加一个 GetFaculties 操作方法,该方法接受大学 id 并在 SelectListItem 列表中以 JSON 数组的形式返回该大学的学院.

public ActionResult GetFaculties(int u){varfacultyList = db.Fakulteler.Where(a=>a.id_uni==u).Select(x=>new SelectListItem { Value=x.Id,Text=x.Name).ToList();返回 Json(facultyList, JsonRequestBehavior.AllowGet);}

您可以在 HttpPost 操作中使用相同的视图模型

[HttpPost]公共操作结果创建(CreateVm vm){如果(模型状态.IsValid){//从vm读取并保存var k=新卡费德拉{UniveristyId=vm.SelectedUniversity,FacultyId=vm.SelectedFaculty,};db.kafedra.Add(k);db.SaveChanges();return RedirectToAction("索引");}vm.Universities=GetUniversities();返回视图(vm);}

I have three tables in my database as follows:

University 
 id   Name
 1     A
 2     B

Faculty 
id   id_uni   name
1      1       AA
2      1       AA

cafedry
id    id_uni    id_faculty   name

1       1            1        cc

I would like to create a cascading dropdown which will allow me to first select a University then a Faculty followed by a Cafedry. Below code is what i have tried so far.

 public ActionResult Create()
    {
        ViewBag.fak_kod = new SelectList(db.Fakulteler, "id", "adi");
        ViewBag.unikod = new SelectList(db.Universitetler, "id", "adi");
        return View();
    }

    // POST: kafedras/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "id,unikod,fak_kod,adi")] kafedra kafedra)
    {
        if (ModelState.IsValid)
        {
            db.kafedra.Add(kafedra);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.fak_kod = new SelectList(db.Fakulteler , "id", "adi", kafedra.fak_kod);
        ViewBag.unikod = new SelectList(db.Universitetler, "id", "adi", kafedra.unikod);
        return View(kafedra);
    }

and this cshtml

<div class="form-horizontal">
    <h4>kafedra</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.unikod, "unikod", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("unikod", null, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.unikod, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.fak_kod, "fak_kod", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("fak_kod", null, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.fak_kod, "", new { @class = "text-danger" })
        </div>
    </div>

How can update this code to create a cascading dropdown with the three tables?

解决方案

To start with, create a view model which has properties to render the options and store the selected item value.

public class CreateVm
{
   [Required]
   public int SelectedUniversity { set;get;}

   [Required]
   public int SelectedFaculty { set;get;}  

   public List<SelectListItem> Universities { set;get;}    
   public List<SelectListItem> Faculties { set;get;}

   public CreateVm()
   {
       this.Faculties = new List<SelectListItem>();
       this.Universities = new List<SelectListItem>();
   }  
}

Now in your GET action, create an object of this, load the Universities property and send the object to the view

public AcitonResult Create()
{ 
   var vm=new CreateVm();
   vm.Universities= GetUniversities();
   return View(vm);
}
private List<SelectListItem> GetUniversities()
{
    return db.Universitetler
             .Select(x=>new SelectListItem { Value = x.Id,
                                             Text = x.Name)
             .ToList();
}

Now in your View, which is strongly typed to our CreateVm view model. we will use the DropDownListFor helper method to render the drop-downs

@model CreateVm
@using (Html.BeginForm("Create", "Home"))
{
   @Html.DropDownListFor(a=>a.SelectedUniversity,Model.Universities,"Select one")
   @Html.DropDownListFor(a => a.SelectedFaculty , Model.Faculties, "Select one",
                                       new { data_url = Url.Action("GetFaculties") })
   <input type="Submit" />
}

This will render 2 dropdowns, one with University options and the second one will be empty (because we did not load anything to the Faculties property). Now we will have some javascript(we are using jquery here for easy DOM manipulation) which will listen to the change event of the first drop-down(Universities) ,read the selected value and make an ajax call to the GetFaculties method and passing the selected university option value.

You can see that , i set a html5 data attribute for the second dropdown where i am storing the relative url to the GetFaculties method. So in my javascript, i can simply read this data attribute value and make a call to that url to get the data.

$(function () {
    $("#SelectedUniversity").change(function () {
        var v = $(this).val();
        var url = $("#SelectedFaculty").data("url") + '?u=' + v;
        var $fac= $("#SelectedFaculty");
        $.getJSON(url, function (data) {
                $fac.empty();
                $.each(data, function (i, item) {
                    $fac.append($("<option>").text(item.Text).val(item.Value));
                });
            });    
    });
});

Now, let's add a GetFaculties action method which accepts the university id and return the faculties for that university in a list of SelectListItem as JSON array.

public ActionResult GetFaculties(int u)
{
    var facultyList = db.Fakulteler
                        .Where(a=>a.id_uni==u)
                        .Select(x=>new SelectListItem { Value=x.Id,
                                                       Text=x.Name).ToList();
    return Json(facultyList , JsonRequestBehavior.AllowGet);
}

You may use the same view model in the HttpPost action

[HttpPost]
public ActionResult Create(CreateVm vm)
{
    if (ModelState.IsValid)
    {
        //read from vm and save
        var k=new kafedra { 
                           UniveristyId=vm.SelectedUniversity, 
                           FacultyId=vm.SelectedFaculty, 
                        };
        db.kafedra.Add(k);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    vm.Universities= GetUniversities();
    return View(vm);
}

这篇关于ASP.NET MVC 级联下拉菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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