wake-up-neo.net

So filtern Sie die Optionen einer Dropdown-Liste mithilfe einer anderen Dropdown-Liste

Ich bin sehr neu in ASP.NET und verwende das MVC 3-Framework von ASP.Net. Ich habe versucht, die Optionen einer Dropdown-Liste mithilfe einer anderen Dropdown-Liste zu filtern, und das gelingt mir nicht. Ich habe versucht, dies zuerst zu tun, indem ich sowohl die Liste der Hauptkategorien als auch die der Unterkategorien ausgefüllt und auf die Seite geladen habe. Anschließend habe ich das Klassenattribut der Optionen jeder Unterkategorie auf ihre übergeordnete Kategorie festgelegt. Schließlich wird beim Klicken auf die übergeordnete Kategorie in der ersten Dropdown-Liste nur die untergeordnete Unterkategorie angezeigt und der Rest ausgeblendet (so habe ich es zuvor in Java gemacht). Aber in ASP.Net MVC ist der HTML-Code so unterschiedlich, dass ich nicht einmal das Klassenattribut für jede Option der Dropdown-Liste festlegen kann. Im Allgemeinen wird die Klasse für alle Dropdown-Listen festgelegt, nicht für jede Option. Dies ist, was ich gerade habe. Dies ist meine Ansicht

<p>
@Html.LabelFor(model => model.CategoryId)
@Html.DropDownListFor(x => x.CategoryId , new SelectList(Model.Categories, "CategoryId", "CategoryName"), new { onchange= "this.form.submit();"})
</p>

<p>
@Html.LabelFor(model => model.SubCategories)
@Html.DropDownListFor(x => x.SubCategories, new SelectList(Model.SubCategories, "SubCategoryId", "SubCategoryName"), new { @class = "Category1.categoryname" })
 </p>

Das ist mein Modell

public class TestQuestionsViewModel
{
    public string CategoryId { get; set; }
    public IEnumerable<Category> Categories { get; set; }

    public string SubCategoryId { get; set; }
    public IEnumerable<SubCategory> SubCategories { get; set; }
 }

Dies ist meine Controller-Klassenmethode

    public ActionResult Create()
    {

        var model = new TestQuestionsViewModel
        {

            Categories = resetDB.Categories.OrderBy(c => c.categoryid),
            SubCategories = resetDB.SubCategories.OrderBy(sc => sc.subcategoryid)
         };
     return View(model);
    }

Meine Fragen sind: Wie kann ich die Klassenattribute für die einzelnen Optionen festlegen? Oder wenn jemand einen Vorschlag hat, wie man das anders macht, bin ich offen für jede Lösung. Vielen Dank.

12
Sophonias

Es scheint mir keine gute Idee zu sein, alle Unterelemente auf die Seite zu laden, wenn die Seite zuerst geladen wird. Was ist, wenn Sie 100 Kategorien haben und jede Kategorie 200 Unterkategorieelemente hat? Möchten Sie wirklich 20000 Artikel laden?

Ich denke, Sie sollten schrittweise laden. Versehen Sie die Dropdown-Liste Hauptkategorie mit den Werten. Lassen Sie den Benutzer ein Element davon auswählen. Rufen Sie den Server an und rufen Sie die Unterkategorien ab, die zur ausgewählten Kategorie gehören, und laden Sie diese Daten in die zweite Dropdown-Liste. Sie können dazu jQuery ajax verwenden, damit der Benutzer nicht das Gefühl hat, dass eine Seite vollständig neu geladen wird, wenn er eine Dropdown-Liste auswählt. So werde ich es machen.

Erstellen Sie das ViewModel mit beiden Kategorieeigenschaften

public class ProductViewModel
{
    public int ProductId { set;get;}
    public IEnumerable<SelectListItem> MainCategory { get; set; }
    public string SelectedMainCatId { get; set; }
    public IEnumerable<SelectListItem> SubCategory { get; set; }
    public string SelectedSubCatId { get; set; }
}

Lassen Sie Ihre GET Action-Methode diese stark typisierte Ansicht mit gefülltem Inhalt für MainCategory zurückgeben

public ActionResult Edit()
{
   var objProduct = new ProductViewModel();             
   objProduct.MainCategory = new[]
   {
      new SelectListItem { Value = "1", Text = "Perfume" },
      new SelectListItem { Value = "2", Text = "Shoe" },
      new SelectListItem { Value = "3", Text = "Shirt" }
   };
   objProduct.SubCategory = new[] { new SelectListItem { Value = "", Text = "" } };
   return View(objProduct);
}

und in Ihrer stark getippten Ansicht,

@model MvcApplication1.Models.ProductViewModel
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
@using (Html.BeginForm())
{    
    @Html.DropDownListFor(x => x.SelectedMainCatId, new SelectList(Model.MainCategory,"Value","Text"), "Select Main..")
    @Html.DropDownListFor(x => x.SelectedSubCatId, new SelectList(Model.SubCategory, "Value", "Text"), "Select Sub..")    
    <button type="submit">Save</button>
}
<script type="text/javascript">
    $(function () {
        $("#SelectedMainCatId").change(function () {
            var val = $(this).val();
            var subItems="";
            $.getJSON("@Url.Action("GetSub","Product")", {id:val} ,function (data) {
              $.each(data,function(index,item){
                subItems+="<option value='"+item.Value+"'>"+item.Text+"</option>"
              });
              $("#SelectedSubCatId").html(subItems)
            });
        });
    });
</script>

Fügen Sie Ihrem Controller die GetSub-Aktionsmethode hinzu, um die Unterkategorien für die ausgewählte Kategorie zurückzugeben. Wir senden die Antwort als Json zurück

 public ActionResult GetSub(int id)
 {
    List<SelectListItem> items = new List<SelectListItem>();
    items.Add(new SelectListItem() { Text = "Sub Item 1", Value = "1" });
    items.Add(new SelectListItem() { Text = "Sub Item 2", Value = "8"});
    // you may replace the above code with data reading from database based on the id

    return Json(items, JsonRequestBehavior.AllowGet);
 }

Jetzt sind die ausgewählten Werte in Ihrer HTTPOST-Aktionsmethode verfügbar

    [HttpPost]
    public ActionResult Edit(ProductViewModel model)
    {
        // You have the selected values here in the model.
        //model.SelectedMainCatId has value!
    }
26
Shyju

Sie müssen eine weitere Methode hinzufügen, um das Postback zu verarbeiten und die Unterkategorieoptionen zu filtern. Etwas wie das:

[HttpPost]
public ActionResult Create(TestQuestionsViewModel model)
{
    model.SubCategories = resetDB.SubCategories
            .Where(sc => sc.categoryid == model.SubCategoryId)
            .OrderBy(sc => sc.subcategoryid);
    return View(model);    
}

Bearbeiten

Übrigens, wenn Sie den Klassennamen immer noch auf das andere Dropdown-Menü setzen müssen, können Sie das nicht so machen. Am einfachsten wäre es, Ihrem Modell eine "SelectedCategoryName" -Eigenschaft hinzuzufügen und auf {@class = ModelSelectedCategoryName} zu verweisen.

0
McGarnagle