Tar270
Tar270

Reputation: 77

Bind the value of select component and perform search

I have trouble binding "filterItem".

I am able to populate values, but the selected value does not get binded for performing search.

Also, I would like to know if search can be performed on selection (in select component). Thank you.

@if (result!= null){

    <select class="form-control" value="filterItem"> // tried @bind="filterItem", did not work.
        <option selected disabled="true">--Filter--</option>
        @foreach (var r in result)
        {
            <option value="@r.name">@r.itemNo</option>
        }
    </select>
    <button @onclick="Filter">Filter</button>

}

@code {

    int? filterItem;
    Item[] items;
    Item[] result;


    public class Item
    {
        public string name { get; set; }
        public int itemNo{ get; set; } 
    }

   protected override async Task OnInitializedAsync()
    {
       
        items = await httpClient.GetFromJsonAsync<Item[]>("sample-data/items.json");
    }

   private async Task Filter()
    {
        result= items.Where(x=> x.itemNo== @filterItem).ToArray();
    }

Upvotes: 0

Views: 2835

Answers (2)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30046

I'm not sure what you're doing with filter so it's hard to build a working example to match your code. Instead here's a demo that shows Continent/Country filtering. There's a manual button option and an auto option. It shows the different methods of binding to the input. You can get the country json file here - https://github.com/samayo/country-json/blob/master/src/country-by-continent.json.

@page "/"
@inject HttpClient httpClient;

<div class="row">
    <div class="col-auto">
        <select class="form-select" @bind="@this.FilterItem">
            <option selected disabled>--Filter--</option>
            @foreach (var r in Continents)
            {
                <option value="@r">@r</option>
            }
        </select>
    </div>
    <div class="col-auto">
        <button class="btn btn-primary" @onclick=this.OnFilter>Filter</button>
    </div>
    <div class="col-2">
    </div>
    <div class="col-auto">

        <select class="form-select" value="@this.FilterAuto" @onchange=this.OnValueChanged>
            <option selected disabled>--Filter--</option>
            @foreach (var r in Continents)
            {
                <option value="@r">@r</option>
            }
        </select>
    </div>
</div>

<div class="mt-3">
    <h2>Filtered List of Countries</h2>
    @foreach (var item in Countries)
    {
        <div>@item.country - @item.continent</div>
    }

</div>

@code {
    private string? FilterAuto;
    private string? FilterItem;

    private IEnumerable<Country> Countries = Enumerable.Empty<Country>();

    private async Task OnValueChanged(ChangeEventArgs e)
    {
        this.FilterAuto = e.Value?.ToString() ?? string.Empty;
        await FilterOnItem(this.FilterAuto);
    }

    private async Task OnFilter()
    => await this.FilterOnItem(this.FilterItem);

    private async Task FilterOnItem(string? value)
    {
        if (value is not null)
        {
            // source country file is https://github.com/samayo/country-json/blob/master/src/country-by-continent.json
            var list = await httpClient.GetFromJsonAsync<IEnumerable<Country>>("sample-data/countries.json") ?? Enumerable.Empty<Country>();
            this.Countries = list.Where(item => item.continent == value);
        }
    }

    private IEnumerable<string> Continents = new List<string> { "Africa", "Asia", "Europe", "Oceania", "North America", "South America" };

    public class Country
    {
        public string country { get; set; } = string.Empty;
        public string continent { get; set; } = string.Empty;
    }
}

Upvotes: 0

Dimitris Maragkos
Dimitris Maragkos

Reputation: 11332

filterItem field should be of type string. If you try like this it will work.

<select class="form-control" @bind="filterItem">
    <option selected disabled="true">--Filter--</option>
    @foreach (var r in result)
    {
        <option value="@r.name">@r.itemNo</option>
    }
</select>

@code {
    string filterItem;
}

To invoke the search when selected value changes you have to bind to the onchange event callback:

<select class="form-control" value="filterItem" @onchange="OnFilterItemChanged">
    <option selected disabled="true">--Filter--</option>
    @foreach (var r in result)
    {
        <option value="@r.name">@r.itemNo</option>
    }
</select>

@code {
    string filterItem;

    private void OnFilterItemChanged(ChangeEventArgs args)
    {
        filterItem = (string)args.Value;
        
        // call your search method
        Filter();
    }
}

Upvotes: 1

Related Questions