Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
200 views
in Technique[技术] by (71.8m points)

c# - ASP.NET MVC cascading dropdown

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...