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
421 views
in Technique[技术] by (71.8m points)

c# - How can I make a cascading dropdown list?

I have Companies and Vacancies tables.

Company has n number of Vacancies. I need to make two dropdown lists.

In one it will be Company, when I select it, there will be Vacancies related to this company.

Here is model of Companies

 public Company()
    {
        this.Clients = new HashSet<Client>();
        this.Vacancies = new HashSet<Vacancy>();
    }

    [Key]
    public int CompanyID { get; set; }
    public string CompanyName { get; set; }
    public string Id { get; set; }

    public virtual AspNetUser AspNetUser { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Client> Clients { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Vacancy> Vacancies { get; set; }
}

Here is model for Vacancies

 public partial class Vacancy
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Vacancy()
    {
        this.Interviews = new HashSet<Interview>();
    }

    [Key]
    public int VacancyId { get; set; }
    public string VacancyName { get; set; }
    public Nullable<int> CompanyID { get; set; }

    public virtual Company Company { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Interview> Interviews { get; set; }

Here is controller where I need to do this

 [HttpGet]
    public ActionResult WelcomeScreen()
    {
        // Формируем список команд для передачи в представление
        SelectList teams = new SelectList(db.Vacancy, "VacancyId", "VacancyName");
        ViewBag.Teams = teams;

        return View();
    }


    //Заносим инфу о вакансии в таблицу
    [HttpPost]
    public ActionResult WelcomeScreen(Interview interview)
    {
        db.Interview.Add(interview);
        db.SaveChanges();
        //Int32 id = interview.Interview_Id;
        //TempData["id"] = id;

        return RedirectToAction("Index", "Questions", new { id = interview.Interview_Id });
    }

How I need to make Cascade Dropdown list?

UPDATE

I try solution

Here is my controller (Questions controller)

 [HttpGet]
    public ActionResult WelcomeScreen()
    {
        // Формируем список команд для передачи в представление
        //SelectList teams = new SelectList(db.Vacancy, "VacancyId", "VacancyName");
        //ViewBag.Teams = teams;

        ViewBag.Companies = new SelectList(db.Companies, "CompanyID", "CompanyName");
        return View();
    }


    //Заносим инфу о вакансии в таблицу
    [HttpPost]
    public ActionResult WelcomeScreen(Interview interview)
    {
        db.Interview.Add(interview);
        db.SaveChanges();
        //Int32 id = interview.Interview_Id;
        //TempData["id"] = id;

        return RedirectToAction("Index", "Questions", new { id = interview.Interview_Id });
    }
    public ActionResult Vacancies(int companyId)
    {
        var items = db.Vacancy
                      .Where(x => x.CompanyID == companyId)
                      .Select(x => new SelectListItem
                      {
                          Value = x.VacancyId.ToString(),
                          Text = x.VacancyName
                      })
                      .ToList();
        return Json(items, JsonRequestBehavior.AllowGet);
    }

Here is script

 <script>
    $(function () {
        $("#Company").change(function (e) {
            var $vacancy = $("#vacancy");
            var url = $vacancy.data("url") + '?companyId=' + $(this).val();
            $.getJSON(url, function (items) {
                $.each(items, function (a, b) {
                    $vacancy.append('<option value="' + b.Value + '">' + b.Text + '</option>');
                });
            });
        });
    });
</script>

And here is View

 <div class="right-grid-in-grid">

                <div style="margin-left:20px;">
                    @Html.DropDownList("Company", ViewBag.Companies as SelectList, new { @class =  "greeting"})
                    @Html.ValidationMessageFor(model => model.VacancyId, "", new { @class = "text-danger" })
                </div>

                <div style="margin-left:20px;">
                    <select name="id" id="vacancy" data-url="@Url.Action("Vacancies","Questions")" class="greeting"/>
                </div>
                </div>

But AJAX not works.

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

The idea of cascading dropdown is, When you load the page, you load the dropdown content for the first SELECT element. The second SELECT element will be an empty one. When user selects an option from the first dropdown, send that to the server which returns the content needed to build the second dropdown.

So in the GET action of your page, get the data needed to render the first dropdown.

public ActionResult Welcome()
{
  ViewBag.Companies = new SelectList(db.Companies, "CompanyID", "CompanyName");
  return View();
}

Now in the view, you can use the DropDownList helper method to render the SELECT element with the data we set to the ViewBag.Companies. We will also add our second dropdown as well.

@Html.DropDownList("Company", ViewBag.Companies as SelectList)
<select name="id" id="vacancy" data-url="@Url.Action("Vacancies","Home")">

Now we will use some ajax code(using jQuery in this example) to get the content for the second dropdown. Register an event handler for the change event of the first dropdown, get the selected value, make an ajax call to the Vacancies action method which returns the data needed to build the second dropdown in JSON format. Use this JSON data to build the second dropdown in javascript.

$(function(){
    $("#Company").change(function (e) {
        var $vacancy = $("#vacancy");
        var url = $vacancy.data("url")+'?companyId='+$(this).val();
        $.getJSON(url, function (items) {
            $.each(items, function (a, b) {
                $vacancy.append('<option value="' + b.Value + '">' + b.Text + '</option>');
            });
        });
    });    
});

Now the last part is, implementing the Vacancies method.

public ActionResult Vacancies(int companyId)
{
    var items = db.Vacancies
                  .Where(x=>x.CompanyID==comapnyId)
                  .Select(x => new SelectListItem { Value = x.VacancyId.ToString(),
                                                    Text = x.VacancyName })
                  .ToList();
    return Json(items, JsonRequestBehavior.AllowGet);
}

Assuming db is your DbContext class object.

Ajax is not necessary for implementing cascading dropdowns. You can post the form with the selected companyId and the action method can return the same with second dropdown filled. But people usually use ajax to give a nice user experience


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

...