How to filter the options of a drop down list using another drop down list asp.net core 3.0

Viewed 74

I would like to select a product category in one drop-down list and display subcategories for it. My models: ProductCategory

        public class ProductCategory
            {
                [Key]
                public int Id { get; set; }
        
                [Required(ErrorMessage ="Pole 'Nazwa kategorii' jest wymagane")]
                [Display(Name ="Nazwa kategorii")]
                public string Name { get; set; }
        
                [Display(Name = "Dodaj zdjęcie")]
                public string ImagePath { get; set; }
        
                public virtual ICollection<ProductSubCategory> ProductSubCategory { get; set; }
        
            }

ProductSubCategory

public class ProductSubCategory
    {
        [Key]
        public int Id { get; set; }
    
        [Required(ErrorMessage = "Pole 'Nazwa podkategorii' jest wymagane")]
        [Display(Name = "Nazwa kategorii")]
        public string Name { get; set; }
    
        [Display(Name = "Wybierz zdjęcie")]
        public string ImagePath { get; set; }
    
        public int ProductCategoryId { get; set; }
    
        [ForeignKey("ProductCategoryId")]
        [Display(Name = "Kategoria")]
        public ProductCategory ProductCategory { get; set; }
    
        public virtual ICollection<Product> Products { get; set; }
    }

Create Product Page

    public IActionResult OnGet()
        {
            ViewData["ProductCategoryId"] = new SelectList(_context.ProductCategory, "Id", "Name");
            ViewData["ProductSubCategoryId"] = new SelectList(_context.ProductSubCategory, "Id", "Name");
            return Page();
        }
        public JsonResult OnGetSubCategories(int category)
        {
            var subcategories = _context.ProductSubCategory.Where(c => c.ProductCategoryId == category).ToList();
            return new JsonResult(new SelectList(subcategories, "Id", "Name"));
        }

CreateProduct html

<form method="post" enctype="multipart/form-data">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Product.Name" class="control-label"></label>
                <input asp-for="Product.Name" class="form-control" />
                <span asp-validation-for="Product.Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Product.Description" class="control-label"></label>
                <input asp-for="Product.Description" class="form-control" />
                <span asp-validation-for="Product.Description" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Product.ImagePath" class="control-label"></label>
                <input type="file" asp-for="Product.ImagePath" class="form-control" name="image" onchange="readURL(this);"/>
                <span asp-validation-for="Product.ImagePath" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Product.DateOfNotification" class="control-label"></label>
                <input asp-for="Product.DateOfNotification" class="form-control" />
                <span asp-validation-for="Product.DateOfNotification" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Product.ProductCategoryId" class="control-label"></label>
                <select id="category" asp-for="Product.ProductCategoryId" class ="form-control" asp-items="ViewBag.ProductCategoryId"></select>
            </div>
            <div class="form-group">
                <label asp-for="Product.ProductSubCategoryId" class="control-label"></label>
                <select id="subCategory" asp-for="Product.ProductSubCategoryId" class ="form-control" asp-items="ViewBag.ProductSubCategoryId"></select>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
        script
            <script>
            $("#category").change(function () {
            var category = $("#category").val();
            $.ajax({
                url: "CreteProduct?handler=SubCategories",
                method: "GET",
                data: { category: category },
                success: function (data) {
                    $("#subCategory option").remove();
                    $.each(data, function (index, itemData) {       
                        $("#subCategory").append("<option value='" + itemData.Id + "'>" + itemData.Name + "</option>");
                    });
                }
            })
        });
        </script>

Result: The subcategory drop-down list is undefined. After selecting the category the number of items is good but displays 'undefined'.

enter image description here

1 Answers

You need to use itemData.value to replace itemData.Id,itemData.text to replace itemData.Name.Here is a demo worked:

cshtml.cs:

public class CreateProductModel : PageModel
    {
        [BindProperty]
        public Product Product { get; set; }
        public static List<ProductCategory> productCategories = new List<ProductCategory> { new ProductCategory { Id = 1, Name = "pc1" }, new ProductCategory { Id = 2, Name = "pc2" } };
        public static List<ProductSubCategory> productSubCategories = new List<ProductSubCategory> { new ProductSubCategory { Id = 11, Name = "psc11", ProductCategoryId = 1 }, new ProductSubCategory { Id = 12, Name = "psc12", ProductCategoryId = 1 }, new ProductSubCategory { Id = 21, Name = "psc21", ProductCategoryId = 2 }, new ProductSubCategory { Id = 22, Name = "psc22", ProductCategoryId = 2 } };
        public IActionResult OnGet()
        {
            ViewData["ProductCategoryId"] = new SelectList(productCategories, "Id", "Name");
            ViewData["ProductSubCategoryId"] = new SelectList(productSubCategories, "Id", "Name");
            return Page();
        }
        public JsonResult OnGetSubCategories(int category)
        {
            var subcategories = productSubCategories.Where(p => p.ProductCategoryId == category).ToList();
            return new JsonResult(new SelectList(subcategories, "Id", "Name"));
        }

    }

cshtml:

<form method="post" enctype="multipart/form-data">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Product.Name" class="control-label"></label>
        <input asp-for="Product.Name" class="form-control" />
        <span asp-validation-for="Product.Name" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Product.Description" class="control-label"></label>
        <input asp-for="Product.Description" class="form-control" />
        <span asp-validation-for="Product.Description" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Product.ImagePath" class="control-label"></label>
        <input type="file" asp-for="Product.ImagePath" class="form-control" name="image" onchange="readURL(this);" />
        <span asp-validation-for="Product.ImagePath" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Product.DateOfNotification" class="control-label"></label>
        <input asp-for="Product.DateOfNotification" class="form-control" />
        <span asp-validation-for="Product.DateOfNotification" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Product.ProductCategoryId" class="control-label"></label>
        <select id="category" asp-for="Product.ProductCategoryId" class="form-control" asp-items="ViewBag.ProductCategoryId"></select>
    </div>
    <div class="form-group">
        <label asp-for="Product.ProductSubCategoryId" class="control-label"></label>
        <select id="subCategory" asp-for="Product.ProductSubCategoryId" class="form-control" asp-items="ViewBag.ProductSubCategoryId"></select>
    </div>
    <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
    </div>
</form>
@section scripts{ 
    <script type="text/javascript">
            $("#category").change(function () {
                var category = $("#category").val();
                $.ajax({
                url: "CreateProduct?handler=SubCategories",
                    method: "GET",
                    data: {category: category },
                    success: function (data) {
                $("#subCategory option").remove();
                        $.each(data, function (index, itemData) {
                $("#subCategory").append("<option value='" + itemData.value + "'>" + itemData.text + "</option>");
                        });
                    }
                })
            });
</script>
}

result: enter image description here

enter image description here

Related