Issue
I am creating a recipe blog website. While creating post, I have option to categorize them into Veg and NonVeg posts using an Enum
dropdown. The posts are displayed as cards on index page. I want to create a dropdown filter on index page to display only the selected category.
Enum:
public enum PostCategory
{
[Display(Name = "Veg")]
Veg = 0,
[Display(Name = "NonVeg")]
NonVeg = 1
}
Model:
public class Post
{
// Post
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string? Link { get; set; }
public string? Ingredient { get; set; }
public string Recipe { get; set; }
public string Image { get; set; }
// Category
public PostCategory PostCategory { get; set; }
}
Controller:
// Index
[HttpGet]
public async Task<IActionResult> Index()
{
IEnumerable<Post> posts = await _postInterface.GetAll();
return View(posts);
}
// Search Bar
[HttpPost]
public async Task<IActionResult> Index(string searchString, PostCategory postCategory)
{
var posts = from p in _context.Posts select p;
if (!string.IsNullOrEmpty(searchString))
{
posts = posts.Where(t => t.Title!.Contains(searchString));
}
return View(await posts.ToListAsync());
}
// Category Filter goes here.
View:
<!-- Filter -->
<div class="row justify-content-between">
<!-- Search bar -->
<div class="col-4">
<form class="d-flex mb-2" role="search" asp-controller="Post" asp-action="Index">
<input class="form-control me-2" type="search" placeholder="Search Posts" aria-label="Search" name="SearchString" required oninvalid="this.setCustomValidity(' ')" />
<button class="btn btn-outline-success me-2" type="submit">Search</button>
<a class="btn btn-outline-danger" asp-area="" asp-controller="Post" asp-action="Index">Reset</a>
</form>
</div>
<!-- Dropdown -->
<div class="col-4">
<form asp-controller="Post" asp-action="Index" id="category">
<select class="form-control" asp-items="@Html.GetEnumSelectList<PostCategory>()" id="post-filter">
<option value="">All</option>
</select>
<button class="btn btn-outline-success me-2" type="submit">Search</button>
<a class="btn btn-outline-danger" asp-area="" asp-controller="Post" asp-action="Index">Reset</a>
</form>
</div>
</div>
<!-- Cards -->
<div class="album py-5 bg-light">
<div class="container">
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3" id="post-recipe">
@foreach (var item in Model)
{
<div class="col mb-4">
<div class="card shadow-sm">
<img class="bd-placeholder-img card-img-top" src="@item.Image" width="157" height="236" alt="Card image cap">
@* Card Details *@
<div class="card-body">
<a asp-controller="Post" asp-action="Detail" asp-route-id="@item.Id" class="stretched-link"></a>
<h6 class="card-text"> @item.Title </h6>
<div class="d-flex justify-content-between align-items-center">
<small class="text-body-secondary">@item.PostCategory</small>
</div>
</div>
@* Admin privlages *@
<div class="card-footer btn-group">
<a asp-controller="Post" asp-action="Edit" asp-route-id="@item.Id" type="button" class="btn btn-sm btn-outline-primary stretched-link">Edit</a>
<a asp-controller="Post" asp-action="Delete" asp-route-id="@item.Id" type="button" class="btn btn-sm btn-outline-danger stretched-link">Delete</a>
</div>
</div>
</div>
}
</div>
</div>
</div>
I have tried using adding additional [HttpPost]
action in Index for it to only crash route with searchbar action. Combining it with searchbar action helps, as there is no Route crash, but even then, the code is only half complete, not giving the expected results, only showing veg category.
Here is what I have tried:
// Enum Category
[HttpPost]
public IActionResult Index(PostCategory postCategory)
{
var posts = _context.Posts.Where(c => c.PostCategory == postCategory).ToList();
return View(posts);
}
Thank you!
Solution
the code is only half complete, not giving the expected results, only showing veg category
You failed model-binding and PostCategory enum has the default value 0(Veg)
Add the name property to your dropdownlist for model-binding,
<select class="form-control" asp-items="@Html.GetEnumSelectList<PostCategory>()" name="postCategory" id="post-filter">
<option value="">All</option>
</select>
also,modify your controller,add the codes for when you select all :
[HttpPost]
public IActionResult Index(PostCategory? postCategory)
{
List<Post> posts;
if(postCategory!=null)
{
posts = _context.Post.Where(c => c.PostCategory == postCategory).ToList();
}
else
{
//wheather you don't select or select all,postCategory would be null
//you could replace the logic here yourself
posts = _context.Post.ToList();
}
return View(posts);
}
Answered By - Ruikai Feng
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.