iCV
iCV

Reputation: 607

Select tag helper to filter index

I'm trying to use a select tag helper to filter a list of moves by difficulty and type. So far I have a working dropdown, but I have no idea how to redirect the selected value to the index method in my controller.

This is what I have

View

@model IEnumerable<Taijitan.Models.Domain.Move>
@{
    ViewData["Title"] = "Moves";
}

<h2>@ViewData["Title"]</h2>
<div class="form-group">
     //Returns filter1
    <select asp-items="@ViewData["Difficulty"] as List<SelectListItem>" class="form-control">
        <option value="">-- Select Difficulty --</option>
    </select>
     //Returns filter2
    <select asp-items="@ViewData["Type"] as List<SelectListItem>" class="form-control">
        <option value="">-- Select Type --</option>
    </select>
</div>

The dropdown list is supposed to return the selected value to the index method, which takes a string as filter.

Controller

    public IActionResult Index(string filter, string filter2)
    {
        IEnumerable<Move> Moves = null;
        if (filter == null && filter2 == null){
            Moves = _MoveRepository.GetAll();
        }
        else if (filter != null && filter2 == null)
        {
            Moves = _MoveRepository.GetByDifficulty(int.Parse(filter));
        }
        else if (filter == null && filter2 != null))
        {
            Moves = _MoveRepository.GetByType(filter);
        }
        else if (filter != null && filter2 != null))
        {
            Moves = _MoveRepository.GetByType(filter).Where(m => m.Difficulty == int.Parse(filter2);
        }
        ViewData["Type"] = GetTypesAsSelectList();
        ViewData["Difficulty"] = GetDifficultiesAsSelectList();
        return View(Moves);
    }

Method which creates the displayed selectList (almost same for DifficultyList)

private List<SelectListItem> GetTypesAsSelectList()
{
    List<SelectListItem> TypesList = new List<SelectListItem>();
    foreach (Move move in _MoveRepository.GetAll().Distinct())
    {
        TypesList.Add(new SelectListItem { Text = Move.Type, Value = Move.Type });
    }

    return TypesList;

I'm stuck at figuring out how to pass the selected value of the dropdown lists as filter and filter2 to the index.

EDIT

I've added a form element and this button:

<a asp-controller="Move" asp-action="Index" asp-route-filter="" asp-route-filter2="" class="btn btn-default">Filter</a>

I can't figure out how to get the value of the first list in asp-route-filter, and the value of the second list in asp-route-filter2.

Upvotes: 0

Views: 563

Answers (1)

PaulBinder
PaulBinder

Reputation: 2052

One core piece to a HTML form submit is the <form></form> element. Based on your question, I am assuming your form will be doing a GET instead of a POST. I assume this because the default action of a controller is a GET. Another is the SUBMIT button itself (unless you plan on submitting the form via javascript or other means).

You're also missing the asp-for="" which is a fancy way to populate the Name and Id of an element of a view. For your example, you would use filter and filter2 as the values. Though I would refactor those names in the future. The Name attribute allows the model binder to bind elements of the request to the controller's parameters.

With this in mind, your below form would look as follows (note the added FORM element, BUTTON element, and the addition of asp-for="").

@model IEnumerable<Taijitan.Models.Domain.Move>
@{
    ViewData["Title"] = "Moves";
}

<h2>@ViewData["Title"]</h2>
<form method="GET">
<div class="form-group">
     //Returns filter1
    <select asp-items="@ViewData["Difficulty"] as List<SelectListItem>" class="form-control" asp-for="filter">
        <option value="">-- Select Difficulty --</option>
    </select>
     //Returns filter2
    <select asp-items="@ViewData["Type"] as List<SelectListItem>" class="form-control" asp-for="filter2">
        <option value="">-- Select Type --</option>
    </select>
    <a asp-controller="Move" asp-action="Index" asp-route-filter="" asp-route-filter2="" class="btn btn-default">Filter</a>
</div>
</form>

You can use the @Html.Helpers for these elements as well. That's your choice. The results are the same.

Upvotes: 1

Related Questions