Search code examples
c#htmlfilterenumsasp.net-core-mvc

How to persist the selected value of Enum dropdown in ASP.NET MVC


I have created a global dropdown filter using Enum on my navbar. It works but the dropdown value goes back to default after filtering data. I want the selected value to continue persisting until changed by the user.

FilterController.cs

[HttpPost]
public IActionResult Index(PostCategory? postCategory)
{
    List<Post> post;

    if (postCategory != null)
    {
        post = _context.Posts.Where(c => c.PostCategory == postCategory).ToList();
    }
    else
    {
        post = _context.Posts.ToList();
    }

    _cache.Set("post", post);

    return View("~/Views/Home/Index.cshtml");
}

Filter.cshtml

<div class="col-4">
    <form class="w-75 ps-lg-5" asp-controller="Filter" asp-action="Index" id="category">
        <div class="input-group">
            <select class="form-control" asp-items="@Html.GetEnumSelectList<PostCategory>()" name="postCategory" id="post-filter" >
                <option value="" selected>All</option>
            </select>
            <button class="btn btn-outline-success me-2" type="submit">Filter</button>
        </div>
    </form>
</div>

Here is what I have tried-

  • TempData.Keep() doesn't meet my requirements. It only preserves the selected dropdown value for 2 page changes/refreshes.
...Code before
if (postCategory != null)
{
    TempData["selectedValue"] = postCategory;
    TempData.Keep();

    post = _context.Posts.Where(c => c.PostCategory == postCategory).ToList();
}
Code after...
  • Session gives error- CS0103:The name 'Session' doesnt exist in current context.
...Code before
if (postCategory != null)
{
    Session["selectedValue"] = postCategory;

    post = _context.Posts.Where(c => c.PostCategory == postCategory).ToList();
}
Code after...
  • HttpContext.Session gives error- CS1955: Non-invocable member 'HttpContext.Session' cannot be used like a method.
...Code before
if (postCategory != null)
{
    HttpContext.Session("selectedValue") = postCategory;

    post = _context.Posts.Where(c => c.PostCategory == postCategory).ToList();
}
Code after...

Thank you for your help.


Solution

  • I want the selected value to continue persisting until changed by the user.

    You can use viewbag to store the selected value in it, and then judge it in the page, and return its value when ViewBag.PostCategory is not null. The following code can give you a reference:

    Controller:

    public IActionResult Index(PostCategory? postCategory)
    {
         List<Post> posts;
    
         if (postCategory != null)
         {
             posts = _context.Posts.Where(c => c.PostCategory == postCategory).ToList();
         }
         else
         {
             posts = _context.Posts.ToList();
         }
         _cache.Set("post", posts);     
         ViewBag.PostCategory = postCategory;    
         return View();
    }
    

    Page:

     <div class="col-4">
        <form class="w-75 ps-lg-5" asp-controller="Post" asp-action="Index" id="category">
            <div class="input-group">
                <select class="form-control" name="postCategory" id="post-filter">
                    <option value="">All</option>
                    @foreach (var value in Enum.GetValues(typeof(PostCategory)))
                    {
                        <!option value="@value" @(value.ToString() == ViewBag.PostCategory?.ToString() ? "selected" : "")>@value</!option>
                        
                    }
                </select>
                <button class="btn btn-outline-success me-2" type="submit">Filter</button>
            </div>
        </form>
    </div>
    

    When start:

    enter image description here

    After choose data:

    enter image description here enter image description here

    Update

    If you want to maintain the selected value among non-logged-in users, sessionStorage is a good choice.When the page loads, it tries to fetch the previously saved selected value from the sessionStorage and apply it to the drop-down list. When the user changes the selection, it stores the new selected value in sessionStorage. If the user closes the browser tab or browser, the stored values are cleared.

    <div class="col-4">
        <form class="w-75 ps-lg-5" asp-controller="Post" asp-action="Index" id="category">
            <div class="input-group">
                <select class="form-control" name="postCategory" id="post-filter">
                    <option value="">All</option>
    
                    @foreach (var value in Enum.GetValues(typeof(PostCategory)))
                    {
                       
                        <!option value="@value"  @(value.ToString() == ViewBag.PostCategory?.ToString() ? "selected" : "")>@value</!option>
                    }
                </select>
                <button class="btn btn-outline-success me-2" type="submit">Filter</button>
            </div>
        </form>
    </div>
    
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    
    <script >
        $(document).ready(function () {
           
            var selectedValue = sessionStorage.getItem('selectedPostCategory');
            $('#post-filter').val(selectedValue);
    
            
            $('#post-filter').change(function () {
                var selectedValue = $(this).val();
                sessionStorage.setItem('selectedPostCategory', selectedValue);
            });
        });
    </script>
    

    enter image description here