ASP.NET Core 9 MVC 中的类别下拉过滤器

问题描述 投票:0回答:1

任何人都可以帮助我使用此类别过滤器吗?

<div class="d-flex align-items-center">
    <label for="category-select" class="me-2">Category</label>
    <select name="categoryFilter" class="form-select" id="category-select">
        <option value="">All Categories</option>
        @foreach (var category in Model.Categories)
        {
            var isSelected = Model.CategoryFilter == category.Value ? "selected" : "";
            <option value="@category.Value" selected="" @isSelected>@category.Text</option>
        }
    </select>
</div>

我收到此错误:

错误(活动)RZ1031
标签助手“选项”在元素的属性声明区域中不得包含 C#。
C:\Users\zaida\Desktop\Clinic Management Software\ClinicManagementSystem\Views\ProductManagement\Index.cshtml 55

控制器:

[HttpGet]
public async Task<IActionResult> Index(string searchTerm, string categoryFilter, string sortBy, int page = 1)
{
    var productsQuery = _context.Products
        .Include(p => p.Category)
        .Include(p => p.Inventory)
        .Where(p => p.DeletedAt == null);

    // Filtering
    if (!string.IsNullOrEmpty(searchTerm))
        productsQuery = productsQuery.Where(p => p.Name.Contains(searchTerm) || p.SKU.Contains(searchTerm));

    if (!string.IsNullOrEmpty(categoryFilter))
        productsQuery = productsQuery.Where(p => p.Category.Name == categoryFilter);

    // Sorting
    productsQuery = sortBy switch
    {
        "price_asc" => productsQuery.OrderBy(p => p.Price),
        "price_desc" => productsQuery.OrderByDescending(p => p.Price),
        "name_asc" => productsQuery.OrderBy(p => p.Name),
        "name_desc" => productsQuery.OrderByDescending(p => p.Name),
        _ => productsQuery.OrderBy(p => p.CreatedAt)
    };

    // Pagination
    var totalItems = await productsQuery.CountAsync();
    var products = await productsQuery
        .Skip((page - 1) * PageSize)
        .Take(PageSize)
        .ToListAsync();

    var categories = await _context.Product_Category
        .Select(c => new SelectListItem { Text = c.Name, Value = c.Name })
        .ToListAsync();

    var viewModel = new ProductIndexViewModel
    {
        Products = products,
        CurrentPage = page,
        TotalPages = (int)Math.Ceiling((double)totalItems / PageSize),
        SearchTerm = searchTerm,
        CategoryFilter = categoryFilter,
        SortBy = sortBy,
        Categories = categories
    };

    return View(viewModel);
}

[HttpPost]
public async Task<IActionResult> IndexPost(string searchTerm, string categoryFilter, string sortBy, int page = 1)
{
    return await Index(searchTerm, categoryFilter, sortBy, page);
}

[HttpGet]
public async Task<IActionResult> AddProduct()
{
    ViewBag.Categories = await _context.Product_Category.ToListAsync();
    ViewBag.Discounts = await _context.Product_Discount.ToListAsync();
    return View();
}

我试过了

<option value="">All Categories</option>
@foreach (var category in Model.Categories)
{
    var isSelected = Model.CategoryFilter == category.Value ? "selected" : "";
    <option value="@category.Value" selected="@isSelected" >@category.Text</option>
}

但我必须进入搜索栏并按 Enter 才能使其工作

filter asp.net-core-mvc html-select .net-9.0
1个回答
0
投票

错误(活动)RZ1031 标签助手“选项”中不得包含 C# 元素的属性声明区域。

这个问题,你好像找到原因了(

<option value="@category.Value" selected="" @isSelected>
),问题涉及到
selected
属性,你需要把
@isSelected
放在
""
里面,修改后代码应该是这样的
 <option value="@category.Value" selected="@isSelected">

根据您的代码,似乎您想为 select 标签设置默认值,使用您的代码,您会发现它没有设置正确的默认值。如果使用F12开发者工具查看元素,可以看到每个选项都有

selected
属性,并且会选择最后一个选项作为默认值。

result1

要解决这个问题,您可以修改代码如下:使用

asp-for
asp-item
绑定选择标签并设置默认值。

<select asp-for="CategoryFilter" name="categoryFilter" class="form-select" id="category-select" asp-items="Model.Categories">
    <option value="">All Categories</option> 
</select> 

输出如下:

result2

但我必须进入搜索栏并按 Enter 才能使其工作

您的意思是要在更改所选选项后过滤数据吗?如果是这样,您可以使用 select 元素更改事件来提交表单。

尝试使用以下代码:

Index.cshtml:在form标签中,我们可以使用

method
属性来指定表单如何提交(get或post),并使用asp-action属性来指定将提交到哪个action方法。

@model Net9MVCSample.Models.ProductIndexViewModel
@{
    ViewData["Title"] = "Home Page";
}

<form id="myform" asp-action="Index" method="get">

    <div class="d-flex align-items-center">
        <label for="category-select" class="me-2">Category</label>
        <select asp-for="CategoryFilter" name="categoryFilter" class="form-select" id="category-select"
                onchange="Submitform()"
            asp-items="Model.Categories">
            <option value="">All Categories</option> 
        </select> 
    </div>

    <div>
    Output: @ViewData["selectvalue"]
    </div>
</form> 

@section Scripts {
    <script>
        function Submitform(){
            document.getElementById("myform").submit();
        }
    </script>
}

家庭控制器:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public async Task<IActionResult> Index(string searchTerm, string categoryFilter, string sortBy, int page = 1)
    {
        var categories = new List<SelectListItem>()
         {
             new SelectListItem { Text = "C1", Value="101" },
             new SelectListItem { Text = "C2", Value="102" },
             new SelectListItem { Text = "C3", Value="103" },
             new SelectListItem { Text = "C4", Value="104" },
             new SelectListItem { Text = "C5", Value="105" },
         };

        categoryFilter = categoryFilter ?? "103";
        var viewModel = new ProductIndexViewModel
        { 
            CategoryFilter = categoryFilter, 
            Categories = categories
        };

        ViewData["selectvalue"] = categoryFilter;

        return View(viewModel);
    }

型号:

public class ProductIndexViewModel
{
    public string CategoryFilter { get; set; }
    public List<SelectListItem> Categories { get; set; }
}

更多详细信息,请参阅 ASP.NET Core 中表单中的标记帮助程序

结果如下:更改所选选项后,会将表单提交给 Index action 方法,然后将过滤后的数据返回到页面。

result3

© www.soinside.com 2019 - 2024. All rights reserved.