Blazor | ComponentOne
Controls / DataFilter / Filters
In This Topic
    Filters
    In This Topic

    The DataFilter control provides many types of filters, including bool, range, date range, checklist, and custom filters. These filters can be generated automatically by the control, according to the data. Let us understand about these filters in detail in the following sections.

    Filter Types

    The DataFilter control supports five different kinds of filters to filter different types of data. Corresponding to each filter, an accordion tab is added to the DataFilter control which contains the controls used to filter the data-aware control by a specific field. For example, 

    When the AutoGenerateFilters property of the C1DataFilter class is set to true, filters are automatically generated depending on the type of the fields present in the DataSource. These filters are added to the FilterCollection and can be accessed using Filters property of the C1DataFilter class.

    To add filters programmatically to the DataFilter control, follow these steps:

    1. Create an instance of one of the different filter types, namely ThreeStateFilter, RangeFilter, ChecklistFilter or DateRangeFilter. The instance accepts a parameter that is the name of the data field for which the filter is being defined.
    2. Specify the important properties related to the filter class and add the filter instance to the FilterCollection.

    The following code demonstrates how to configure RangeFilter to the DataFilter control through code:

    Razor
    Copy Code
    @using Localization
    @using C1.Blazor.DataFilter
    @using C1.Blazor.Grid
    @using C1.Blazor.Accordion
    @using System.Globalization
    
    <h3>Car List</h3>
    <br />
    
    <section class="sampleDataFilterSection">
        <div class="filtersSection">
            <C1DataFilter @ref="dataFilter"         
                FilterAutoGenerating="OnFilterAutoGenerating"        
                ItemsSource="@data"  Style="@("max-height: inherit")">        
            </C1DataFilter>
        </div>
        <div class="dataSection">
            <FlexGrid AutoGeneratingColumn="OnAutoGeneratingColumn" ItemsSource="@data" HeadersVisibility="GridHeadersVisibility.All" Style="@("max-height: inherit")">
            </FlexGrid>
        </div>
    </section>
    
    @code{
        C1DataFilter dataFilter { get; set; }
        C1.DataCollection.C1DataCollection<Car> data { get; set; }
    
    
        protected override void OnInitialized()
        {
            var carsTable = DataProvider.GetCarTable();
            data = new C1.DataCollection.C1DataCollection<Car>(DataProvider.GetCarDataCollection(carsTable));
        }
    
        void OnAutoGeneratingColumn(object sender, GridAutoGeneratingColumnEventArgs args)
        {
            if (args.Property.Name == nameof(Car.Picture))
            {
                args.Column.CellTemplate = target => builder =>
                {
                    builder.OpenElement(0, "img");
                    builder.AddAttribute(1, "style", "max-height: 35px");
                    builder.AddAttribute(2, "src", $"data:image/bmp;base64, {((Lazy<string>)target).Value}");
                    builder.CloseElement();
                };
            }
        }
    
        void OnFilterAutoGenerating(object sender, FilterAutoGeneratingEventArgs args)
        {
            if (args.Filter.PropertyName == nameof(Car.Price))
            {
                var rangeFilter = args.Filter as RangeFilter;
                rangeFilter.Maximum = 1_000_000;
                rangeFilter.Increment = 1000;
                rangeFilter.Minimum = 0;
            }
        }
    }
    

    Apply Filter

    With DataFilter, you can apply filters to the data source in two ways, either apply filters automatically after each update or apply a batch filter. By default, it applies filters automatically on data source after each change in filter values. However, you can change this behavior if you want to apply batch filter to the data source by simply setting AutoApply property of the C1DataFilter class to false and adding a button which when clicked applies filter on the data source based on the conditions set through code, as showcased in the following image and example code:

    Blazor DataFilter batch update

    Razor
    Copy Code
    @using Localization
    @using C1.Blazor.DataFilter
    @using C1.Blazor.Grid
    @using C1.Blazor.Accordion
    
    <h3>Car List</h3>
    
    <div style="margin: 4px;">
        <button @onclick="OnApplyFilterClicked" style="margin: 4px;"><img src="Content/images/filter.png"> Filter</button>
    </div>
    <br />
    
    <section class="sampleDataFilterSection">
        <div class="filtersSection">
            <C1DataFilter @ref="dataFilter" AutoApply="false" ItemsSource="@data" FilterAutoGenerating="@FilterAutoGenerating" Style="@("max-height: inherit")">
    
            </C1DataFilter>
        </div>
        <div class="dataSection">
            <FlexGrid AutoGeneratingColumn="OnAutoGeneratingColumn" ItemsSource="@data" HeadersVisibility="GridHeadersVisibility.All" Style="@("max-height: inherit")">
    
            </FlexGrid>
        </div>
    </section>
    
    @code{
        C1DataFilter dataFilter { get; set; }
        C1.DataCollection.C1DataCollection<Car> data { get; set; }
    
        protected override void OnInitialized()
        {
            var carsTable = DataProvider.GetCarTable();
            data = new C1.DataCollection.C1DataCollection<Car>(DataProvider.GetCarDataCollection(carsTable));
        }
    
        void OnAutoGeneratingColumn(object sender, GridAutoGeneratingColumnEventArgs args)
        {
            if (args.Property.Name == nameof(Car.Picture))
            {
                args.Column.CellTemplate = target => builder =>
                {
                    builder.OpenElement(0, "img");
                    builder.AddAttribute(1, "style", "max-height: 35px");
                    builder.AddAttribute(2, "src", $"data:image/bmp;base64, {((Lazy<string>)target).Value}");
                    builder.CloseElement();
                };
            }
        }
    
        void FilterAutoGenerating(object sender, FilterAutoGeneratingEventArgs e)
        {
            if (e.Property.Name == nameof(Car.Brand))
            {
                var filter = e.Filter as ChecklistFilter;
                filter.ShowSearchBox = true;
            }
            else if (e.Property.Name == nameof(Car.Price))
            {
                var priceFilter = (RangeFilter)e.Filter;
                priceFilter.Maximum = data.Max(o => ((Car)o).Price);
                priceFilter.Minimum = data.Min(o => ((Car)o).Price);
                priceFilter.Increment = 1000;
                priceFilter.Format = "F0";
            }
            else if (e.Property.Name == nameof(Car.TransmissSpeedCount))
            {
                var filter = e.Filter as ChecklistFilter;
                filter.SelectionMode = SelectionMode.Single;
            }
            else if (e.Property.Name == nameof(Car.TransmissAutomatic))
            {
                var filter = e.Filter as ChecklistFilter;
                var unset = filter.Items.FirstOrDefault(i => string.IsNullOrEmpty(i.DisplayValue));
                if (unset != null)
                {
                    unset.DisplayValue = C1.Blazor.DataFilter.Resources.Resource.Null;
                }
            }
        }
    
        void OnApplyFilterClicked()
        {
            _ = dataFilter.ApplyFilterAsync();
        }
    }