Filtering in Blazor ComboBox Component

23 May 202422 minutes to read

The ComboBox has built-in support to filter data items when AllowFiltering is enabled. The filter operation starts as soon as you start typing characters in the search box. Default value of AllowFiltering is false.

Local data

The following code demonstrates the filtering functionality with local data in the ComboBox component.

  • CSHTML
  • @using Syncfusion.Blazor.DropDowns
    
    <SfComboBox TValue="string" TItem="Country" Placeholder="Select a country" AllowFiltering="true" DataSource="@Countries" Width="300px">
        <ComboBoxFieldSettings Text="Name" Value="Code"></ComboBoxFieldSettings>
    </SfComboBox>
    
    @code{
        public class Country
        {
            public string Name { get; set; }
            public string Code { get; set; }
        }
        
        private List<Country> Countries = new List<Country>
        {
            new Country() { Name = "Australia", Code = "AU" },
            new Country() { Name = "Bermuda", Code = "BM" },
            new Country() { Name = "Canada", Code = "CA" },
            new Country() { Name = "Cameroon", Code = "CM" },
            new Country() { Name = "Denmark", Code = "DK" },
            new Country() { Name = "France", Code = "FR" },
            new Country() { Name = "Finland", Code = "FI" },
            new Country() { Name = "Germany", Code = "DE" },
            new Country() { Name = "Greenland", Code = "GL" },
            new Country() { Name = "Hong Kong", Code = "HK" },
            new Country() { Name = "India", Code = "IN" },
            new Country() { Name = "Italy", Code = "IT" },
            new Country() { Name = "Japan", Code = "JP" },
            new Country() { Name = "Mexico", Code = "MX" },
            new Country() { Name = "Norway", Code = "NO" },
            new Country() { Name = "Poland", Code = "PL" },
            new Country() { Name = "Switzerland", Code = "CH" },
            new Country() { Name = "United Kingdom", Code = "GB" },
            new Country() { Name = "United States", Code = "US" },
        };
    }

    Blazor ComboBox with local data filtering

    Remote data

    For Remote data, each key press, filter action request is made at the server end.

    The below code demonstrates the filtering functionality with ODataAdaptor in the ComboBox component with help of Query property.

  • CSHTML
  • @using Syncfusion.Blazor.DropDowns
    @using Syncfusion.Blazor.Data
    
    <SfComboBox TValue="string" TItem="OrderDetails" PopupHeight="230px" Placeholder="Select a name" Query="@RemoteDataQuery" AllowFiltering=true Width="300px">
                        <SfDataManager Url="https://blazor.syncfusion.com/services/production/api/Orders" CrossDomain="true" Adaptor="Syncfusion.Blazor.Adaptors.WebApiAdaptor"/>
                        <ComboBoxFieldSettings Text="CustomerID" Value="CustomerID"/>
                    </SfComboBox>
    
    @code{
         public Query RemoteDataQuery = new Query().Select(new List<string> { "CustomerID" }).Take(6).RequiresCount();
        public class OrderDetails
        {
            public int? OrderID { get; set; }
            public string CustomerID { get; set; }
            public int? EmployeeID { get; set; }
            public double? Freight { get; set; }
            public string ShipCity { get; set; }
            public bool Verified { get; set; }
            public DateTime? OrderDate { get; set; }
            public string ShipName { get; set; }
            public string ShipCountry { get; set; }
            public DateTime? ShippedDate { get; set; }
            public string ShipAddress { get; set; }
        }
    }

    Filter type

    You can use FilterType property to specify on which filter type needed to be considered on the search action of the component. The available FilterType and its supported data types are:

    FilterType Description
    StartsWith Checks whether a value begins with the specified value.
    EndsWith Checks whether a value ends with specified value.
    Contains Checks whether a value contained with specified value.

    In the following example, EndsWith filter type has been mapped to the FilterType property.

  • CSHTML
  • @using Syncfusion.Blazor.DropDowns
    @using Syncfusion.Blazor.Inputs
    
    <SfComboBox TValue="string" TItem="Games" Width="300px" FilterType="FilterType.EndsWith" AllowFiltering=true Placeholder="Select a game" DataSource="@LocalData">
      <ComboBoxFieldSettings Value="ID" Text="Game"></ComboBoxFieldSettings>
    </SfComboBox>
    
    @code{
      public class Games
        {  
            public string ID { get; set; }
            public string Game { get; set; }
        }
        List<Games> LocalData = new List<Games> {
        new Games() { ID= "Game1", Game= "American Football" },
        new Games() { ID= "Game2", Game= "Badminton" },
        new Games() { ID= "Game3", Game= "Basketball" },
        new Games() { ID= "Game4", Game= "Cricket" },
        new Games() { ID= "Game5", Game= "Football" },
        new Games() { ID= "Game6", Game= "Golf" },
        new Games() { ID= "Game7", Game= "Hockey" },
        new Games() { ID= "Game8", Game= "Rugby"},
        new Games() { ID= "Game9", Game= "Snooker" },
      };
    }

    Blazor ComboBox with Filter Type

    Minimum filter length

    When filtering the list items, you can set the limit for character count to raise a remote request and fetch filtered data on the DropDownList. This can be done by manual validation by using the Filtering event arguments within the Filtering event handler.

    In the following example, the remote request does not fetch the search data until the search key contains three characters.

  • CSHTML
  • @using Syncfusion.Blazor.Data
    @using Syncfusion.Blazor.DropDowns
    
    <SfComboBox TValue="string" @ref="comboObj" TItem="Country" Placeholder="e.g. Australia" DataSource="country" AllowFiltering="true">
        <ComboBoxFieldSettings Text="Name" Value="Code"></ComboBoxFieldSettings>
        <ComboBoxEvents TValue="string" TItem="Country" Filtering="OnFilter"></ComboBoxEvents>
    </SfComboBox>
    
    @code {
    
        SfComboBox<string, Country> comboObj { get; set; }
    
        public class Country
        {
            public string Name { get; set; }
    
            public string Code { get; set; }
        }
    
        List<Country> country = new List<Country>
        {
            new Country() { Name = "Australia", Code = "AU" },
            new Country() { Name = "Bermuda", Code = "BM" },
            new Country() { Name = "Canada", Code = "CA" },
            new Country() { Name = "Cameroon", Code = "CM" },
            new Country() { Name = "Denmark", Code = "DK" }
        };
    
        private async Task OnFilter(FilteringEventArgs args)
        {
            args.PreventDefaultAction = true;
            // load overall data when search key empty.
            if (args.Text == "") await comboObj.FilterAsync(comboObj.DataSource);
            // restrict the remote request until search key contains 3 characters.
            else if (args.Text.Length < 3) { return; }
            else
            {
                var query = new Query().Where(new WhereFilter() { Field = "Name", value = args.Text, Operator = "contains", IgnoreAccent = true, IgnoreCase = true });
                query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
                await comboObj.FilterAsync(comboObj.DataSource, query);
            }
        }
    }

    Blazor ComboBox with Minimum filter length

    Multi column filtering

    In the built-in Syncfusion Blazor theme files, support for multi column can be enabled by adding e-multi-column class in the CssClass property.

  • CSHTML
  • @using Syncfusion.Blazor.DropDowns
    
    <SfComboBox TValue="string" Width="300px" TItem="Countries" Placeholder="e.g. Australia" PopupHeight="200px" CssClass="e-multi-column" DataSource="@Country" AllowFiltering="true">
        <ComboBoxFieldSettings Value="Code" Text="Name"></ComboBoxFieldSettings>
        <ComboBoxTemplates TItem="Countries">
            <HeaderTemplate>
                <table><tr><th>Name</th><th>Position</th></tr></table>
            </HeaderTemplate>
            <ItemTemplate>
                <table>
                    <tbody>
                        <tr>
                            <td>@((context as Countries).Name)</td>
                            <td>@((context as Countries).Job)</td>
                        </tr>
                    </tbody>
                </table>
            </ItemTemplate>
        </ComboBoxTemplates>
    </SfComboBox>
    @code {
        public class Countries
        {
            public string Name { get; set; }
            public string Code { get; set; }
            public string Job { get; set; }
    
        }
        List<Countries> Country = new List<Countries>
    {
           new Countries() { Name = "Australia", Code = "AU",Job= "Team Lead" },
            new Countries() { Name = "Bermuda", Code = "BM",Job="Developer"  },
            new Countries() { Name = "Canada", Code = "CA",Job="CEO"  },
            new Countries() { Name = "Cameroon", Code = "CM" ,Job="HR" },
            new Countries() { Name = "Denmark", Code = "DK",Job="Product Manager"  },
            new Countries() { Name = "France", Code = "FR",Job="Developer"  },
            new Countries() { Name = "Finland", Code = "FI",Job="Team Lead"  },
            new Countries() { Name = "Germany", Code = "DE",Job="Product Manager"  },
            new Countries() { Name = "Greenland", Code = "GL",Job="Developer"  },
            new Countries() { Name = "Hong Kong", Code = "HK",Job="CEO"  },
            new Countries() { Name = "India", Code = "IN",Job="HR"  },
            new Countries() { Name = "Italy", Code = "IT",Job="Team Lead"  },
            new Countries() { Name = "Japan", Code = "JP",Job="Developer"  },
            new Countries() { Name = "Mexico", Code = "MX",Job="Product Manager"  },
            new Countries() { Name = "Norway", Code = "NO",Job="HR"  },
            new Countries() { Name = "Poland", Code = "PL",Job="Team Lead"  },
            new Countries() { Name = "Switzerland", Code = "CH",Job="Product Manager"  },
            new Countries() { Name = "United Kingdom", Code = "GB",Job="CEO"  },
            new Countries() { Name = "United States", Code = "US",Job="Developer"  },
            };
    
    }

    Blazor ComboBox with Multi Column filtering

    You can achieve multiple column(field) filtering by passing the List of predicates to the And or Or methods of WhereFilters.

  • CSHTML
  • @using Syncfusion.Blazor.DropDowns
    @using Syncfusion.Blazor.Data
    @using System.IO
    
    <SfComboBox @ref="comboObj" AllowFiltering="true" TValue="Moc" TItem="Moc" DataSource="@data" CssClass="e-multi-column">
        <ComboBoxFieldSettings Text="Text" Value="ID"></ComboBoxFieldSettings>
        <ComboBoxEvents Filtering="OnFiltering" TValue="Moc" TItem="Moc"></ComboBoxEvents>
        <ComboBoxTemplates TItem="Moc">
            <HeaderTemplate>
                <table><tr><th>ID</th><th>Text</th></tr></table>
            </HeaderTemplate>
            <ItemTemplate Context="itemContext">
                <table>
                    <tbody>
                        <tr>
                            @if (!string.IsNullOrEmpty((itemContext as Moc).ID))
                            {
                                <td><span>@((itemContext as Moc).ID)</span></td>
                                <td><span>@((itemContext as Moc).Text)</span></td>
                            }
                        </tr>
                    </tbody>
                </table>
            </ItemTemplate>
        </ComboBoxTemplates>
    </SfComboBox>
    
    @code {
        SfComboBox<Moc, Moc> comboObj;
    
        public Query query { get; set; }
        public class Moc
        {
            public string ID { get; set; }
            public string Text { get; set; }
        }
        List<Moc> data = new List<Moc>
    {
          new Moc() { ID= "12H", Text= "American Football" },
          new Moc() { ID= "14G", Text= "Badminton" },
          new Moc() { ID= "17F", Text= "Basketball" }
        };
        public async Task OnFiltering(FilteringEventArgs args)
        {
            args.PreventDefaultAction = true;
            var orWhere = WhereFilter.Or(new List<WhereFilter> {
                new WhereFilter() { Field = "Text", Operator = "contains", value = args.Text, IgnoreCase = true },
                new WhereFilter() { Field = "ID", Operator = "contains", value = args.Text, IgnoreCase = true }
            });
            var query = new Query().Where(orWhere);
            query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
            await comboObj.FilterAsync(data, query);
        }
    }

    Blazor ComboBox with Multi Column filtering

    Case sensitive filtering

    The Data items can be filtered with or without case sensitivity using the DataManager. This can be done by passing the fourth optional parameter IgnoreCase of the Where clause.

    The following example shows how to perform case-sensitive filter.

  • CSHTML
  • @using Syncfusion.Blazor.Data
    @using Syncfusion.Blazor.DropDowns
    
    <SfComboBox TValue="string" @ref="comboObj" TItem="Country" Placeholder="e.g. Australia" DataSource="country" AllowFiltering="true">
        <ComboBoxFieldSettings Text="Name" Value="Code"></ComboBoxFieldSettings>
        <ComboBoxEvents TValue="string" TItem="Country" Filtering="OnFilter"></ComboBoxEvents>
    </SfComboBox>
    
    @code {
    
        SfComboBox<string, Country> comboObj { get; set; }
    
        public class Country
        {
            public string Name { get; set; }
    
            public string Code { get; set; }
        }
    
        List<Country> country = new List<Country>
        {
            new Country() { Name = "Australia", Code = "AU" },
            new Country() { Name = "Bermuda", Code = "BM" },
            new Country() { Name = "Canada", Code = "CA" },
            new Country() { Name = "Cameroon", Code = "CM" },
            new Country() { Name = "Denmark", Code = "DK" }
        };
    
        private async Task OnFilter(FilteringEventArgs args)
        {
            args.PreventDefaultAction = true;
            var query = new Query().Where(new WhereFilter() { Field = "Name", Operator = "contains", value = args.Text, IgnoreCase = true });
    
            query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
    
            await comboObj.FilterAsync(country, query);
        }
    }

    Custom filtering

    ComboBox component filter queries can be customized using Filtering event. You can also filter the text in multiple columns in the data source.

    In the below sample demonstration, filter the data using its FirstName or LastName field. Hence in the Filtering event, Predicate is used with or condition for filtering both the fields.

    For instance , the data source item consists of FirstName as Nancy and LastName as Davalio. But you can filter the data by typing the N or D character and it will showcase the Nancy(FirstName field) in the popup.

  • CSHTML
  • @using Syncfusion.Blazor.Data
    
    <SfComboBox TValue="string" @ref="comboObj" TItem="Country" Placeholder="e.g. Australia" DataSource="@Countries" AllowFiltering="true">
        <ComboBoxFieldSettings Text="Name" Value="Code"></ComboBoxFieldSettings>
        <ComboBoxEvents TValue="string" TItem="Country" Filtering="OnFilter"></ComboBoxEvents>
    </SfComboBox>
    
    @code {
    
        SfComboBox<string, Country> comboObj { get; set; }
    
        public class Country
        {
            public string Name { get; set; }
    
            public string Code { get; set; }
        }
    
        List<Country> Countries = new List<Country>
        {
            new Country() { Name = "Australia", Code = "AU" },
            new Country() { Name = "Bermuda", Code = "BM" },
            new Country() { Name = "Canada", Code = "CA" },
            new Country() { Name = "Cameroon", Code = "CM" },
            new Country() { Name = "Denmark", Code = "DK" }
        };
    
        List<Country> CountriesFiltered = new List<Country>
        {
            new Country() { Name = "France", Code = "FR" },
            new Country() { Name = "Finland", Code = "FI" },
            new Country() { Name = "Germany", Code = "DE" },
            new Country() { Name = "Greenland", Code = "GL" }
        };
    
        private async Task OnFilter(FilteringEventArgs args)
        {
            args.PreventDefaultAction = true;
            var query = new Query().Where(new WhereFilter() { Field = "Name", Operator = "contains", value = args.Text, IgnoreCase = true });
    
            query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
    
            await comboObj.FilterAsync(CountriesFiltered, query);
        }
    }

    Prevent popup opening when filtering

    To prevent the ComboBox dropdown from opening when filtering is applied, you can use the BeforeOpenEventArgs.Cancel argument in the BeforeOpenEventArgs. The BeforeOpenEventArgs.Cancel argument is a boolean value that can be set to true to cancel the dropdown opening, or false to allow the dropdown to open.

    In the following example, the isTyped flag is used to track whether the filtering action is taking place. The OnFiltering method sets the flag to true when the filtering action starts, and the OnBeforeOpen method cancels the dropdown opening if the flag is set to true. Finally, the OnBeforeOpen method resets the flag to false to prepare for the next filtering action.

    This will prevent the ComboBox dropdown from opening when filtering is applied, while still allowing the user to filter the items using the input field in the ComboBox.

  • CSHTML
  • @using Syncfusion.Blazor.DropDowns;
    
    <SfComboBox ID="combobox" TValue="string" TItem="GameFields" AllowFiltering="true" PopupHeight="230px" Placeholder="Select a game"  DataSource="@Games" Width="300px"> 
        <ComboBoxFieldSettings Text="Text" Value="ID"></ComboBoxFieldSettings> 
        <ComboBoxEvents TValue="string" TItem="GameFields" OnOpen="OnOpen" Filtering="OnFilter"></ComboBoxEvents> 
    </SfComboBox> 
     
    @code{ 
        public class GameFields 
        { 
            public string ID { get; set; } 
            public string Text { get; set; } 
        } 
        public List<GameFields> Games = new List<GameFields>() { 
            new GameFields(){ ID= "Game1", Text= "American Football" }, 
            new GameFields(){ ID= "Game2", Text= "Badminton" }, 
            new GameFields(){ ID= "Game3", Text= "Basketball" }, 
            new GameFields(){ ID= "Game4", Text= "Cricket" }, 
            new GameFields(){ ID= "Game5", Text= "Football" }, 
            new GameFields(){ ID= "Game6", Text= "Golf" }, 
            new GameFields(){ ID= "Game7", Text= "Hockey" }, 
            new GameFields(){ ID= "Game8", Text= "Rugby"}, 
            new GameFields(){ ID= "Game9", Text= "Snooker" }, 
            new GameFields(){ ID= "Game10",Text= "Tennis"} 
            }; 
        public bool isTyped { get; set; } = false; 
        public async Task OnOpen(BeforeOpenEventArgs args) 
        { 
            if (this.isTyped) 
            { 
                args.Cancel = true; 
            } else 
            { 
                args.Cancel = false; 
            } 
            this.isTyped = false; 
        } 
        public void OnFilter(FilteringEventArgs args) 
        { 
            this.isTyped = true; 
        } 
    }