Top 5 Features of Blazor Query Builder
Tags: blazor, webdev, productivity, csharp
Published: 2021-05-26 09:46:50

---
title: Top 5 Features of Blazor Query Builder
published: true
date: 2021-05-25 10:34:48 UTC
tags: blazor, webdev, productivity, csharp
canonical_url: https://www.syncfusion.com/blogs/post/top-5-features-of-blazor-query-builder.aspx
cover_image: https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Top-5-Features-of-Blazor-Query-Builder-672x372.png
---

Syncfusion [Blazor Query Builder](https://www.syncfusion.com/blazor-components/blazor-query-builder "Link to Blazor Query Builder") is a rich and responsive user interface for filtering large amounts of data. We can use this to create or edit queries that can be combined with data visualization controls like DataGrid and Charts to view the filtered data. It can be populated using structured JSON as well as SQL queries. In this blog, I am going to walk you through the following five major features of the Blazor Query Builder control:

- [Filtering](#filtering)
- [Data manager support](#data-manager-support)
- [Importing and exporting](#importing-and-exporting)
- [Templates](#templates)
- [Grouping and sorting](#grouping-and-sorting)

## Filtering

The Blazor Query Builder supports filtering data from a data source using the created conditions and provides the following types of outputs:

- Data manager query
- SQL query
- Predicates

**Data manager query:**  This is used in our Syncfusion components like [DataGrid](https://www.syncfusion.com/blazor-components/blazor-datagrid "Link to Blazor DataGrid"), [Tree Grid](https://www.syncfusion.com/blazor-components/blazor-tree-grid "Link to Blazor Tree Grid"), [Charts](https://www.syncfusion.com/blazor-components/blazor-charts "Link to Blazor Charts"), [ListBox](https://www.syncfusion.com/blazor-components/blazor-listbox "Link to Blazor ListBox") and other components. A user can directly communicate with the Query Builder with these components. You can get the created conditions as a data manager query using the **GetDataManagerQuery** method. We will briefly explain this in the [data manager support](#data-manager-support) section.

**SQL query:** You can use this to interact with and filter the data from databases. You can get the created conditions as a SQL query using the **GetSqlFromRules** method. You can easily replace this with the existing SQL query used in your  application.

**Predicates:**  You can use these to filter the data from entities directly without fetching all the records. You can get the created conditions as predicates using the **GetPredicates** method.

The following code example demonstrates the Predicates output. The data source referenced is a simple list.

```html
@using Syncfusion.Blazor.Grids
<div>
    <SfQueryBuilder TValue="Employee" @ref="QueryBuilder">
        <QueryBuilderColumns>
            <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.Number"></QueryBuilderColumn>
            <QueryBuilderColumn Field="FirstName" Label="First Name" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.String"></QueryBuilderColumn>
            <QueryBuilderColumn Field="LastName" Label="Last Name" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.String"></QueryBuilderColumn>
            <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.Date"></QueryBuilderColumn>
            <QueryBuilderColumn Field="Country" Label="Country" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.String"></QueryBuilderColumn>
        </QueryBuilderColumns>
    </SfQueryBuilder>
</div>
<button class="e-btn e-custom" @onclick="@FilterByPredicates">Search</button>
<div>
    <SfGrid TValue="Employee" AllowPaging="true" DataSource="FilterList">
        <GridPageSettings PageSize="5"></GridPageSettings>
        <GridColumns>
        <GridColumn Field=@nameof(Employee.EmployeeID) HeaderText="Employee ID" TextAlign="TextAlign.Right"></GridColumn>
        <GridColumn Field=@nameof(Employee.FirstName) HeaderText="First Name"></GridColumn>
        <GridColumn Field=@nameof(Employee.LastName) HeaderText="Last Name"></GridColumn>
        <GridColumn Field=@nameof(Employee.HireDate) HeaderText="Hire Date" Format="MM/dd/yyyy"></GridColumn>
        <GridColumn Field=@nameof(Employee.Country) HeaderText="Country"></GridColumn>
     </GridColumns>
    </SfGrid>
</div>

@code {
    SfQueryBuilder<Employee> QueryBuilder;
    public IEnumerable<Employee> EmployeeList { get; set; }
    public IEnumerable<Employee> FilterList { get; set; }
    public WhereFilter Predicates;
    protected override void OnInitialized()
    {
        FilterList = EmployeeList = Employee.GetAllRecords();
    }
    public void FilterByPredicates()
    {
        Predicates = QueryBuilder.GetPredicate(QueryBuilder.GetValidRules());
        string condition = "and";
        if (Predicates != null)
        {
            if (Predicates.predicates != null)
            {
                condition = Predicates.Condition;
            }
            Type type = EmployeeList.GetElementType();
            if (type == null)
            {
                type = EmployeeList.GetType().GetElementType();
            }
            var paramExpression = type.Parameter();
            List<WhereFilter> filterQuery = new List<WhereFilter>();
            filterQuery.Add(Predicates);
            var filterList = EmployeeList.AsQueryable().Where(paramExpression, EnumerableOperation.PredicateBuilder(EmployeeList, filterQuery, condition, paramExpression, type));
            FilterList = filterList.Cast<Employee>().ToList();
        } else
        {
            FilterList = EmployeeList;
        }
    }
}
```

![Filtering Data Using Predicates in Blazor Query Builder](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Filtering-Data-Using-Predicates-in-Blazor-Query-Builder.gif)<figcaption>Filtering Data Using Predicates in Blazor Query Builder</figcaption>

## Data manager support

You can integrate the data manager into the Blazor Query Builder to simplify the communication with a data source and return the desired result based on the provided conditions.

**Note:** The Blazor Query Builder supports all types of data sources supported by the data manager.

You can get the created conditions as a data manager query using the **GetDataManagerQuery** method.

In the following example, the data manager query is used in the DataGrid’s Query property to render the filtered records.

```html
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.Popups

<SfGrid TValue="Order" AllowPaging="true" Query="GridQuery">
    <SfDataManager Url="https://services.odata.org/V4/Northwind/Northwind.svc/Orders" Adaptor="Syncfusion.Blazor.Adaptors.ODataV4Adaptor"></SfDataManager>
    <SfToolbar>
        <ToolbarItems>
            <ToolbarItem Type="ItemType.Input">
                <Template>
                    <button class="e-btn" @onclick="@openQueryBuilder">Open Query Builder</button>
                </Template>
            </ToolbarItem>
        </ToolbarItems>
     </SfToolbar>
     <GridEvents Created="Created" TValue="Order"></GridEvents>
     <GridPageSettings PageSize="8"></GridPageSettings>
     <GridColumns>
        <GridColumn Field=@nameof(Order.OrderID) HeaderText="Order ID" TextAlign="TextAlign.Right"></GridColumn>
        <GridColumn Field=@nameof(Order.CustomerID) HeaderText="Customer ID"></GridColumn>
        <GridColumn Field=@nameof(Order.OrderDate) HeaderText="Order Date" Format="MM/dd/yyyy"></GridColumn>
        <GridColumn Field=@nameof(Order.ShipCity) HeaderText="Ship City"></GridColumn>
        <GridColumn Field=@nameof(Order.ShipCountry) HeaderText="Ship Country"></GridColumn>
     </GridColumns>
</SfGrid>

<SfDialog Target=".sf-grid" ShowCloseIcon="true" @bind-Visible="Visibility" Height="auto">
    <DialogTemplates>
        <Content>
            <SfQueryBuilder TValue="Order" @ref="Querybuilder">
                <QueryBuilderColumns>
                    <QueryBuilderColumn Field="OrderID" Label="Order ID" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.Number"></QueryBuilderColumn>
                    <QueryBuilderColumn Field="CustomerID" Label="Customer ID" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.String"></QueryBuilderColumn>
                    <QueryBuilderColumn Field="OrderDate" Label="Order Date" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.Date"></QueryBuilderColumn>
                    <QueryBuilderColumn Field="ShipCity" Label="Ship City" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.String"></QueryBuilderColumn>
                    <QueryBuilderColumn Field="ShipCountry" Label="Ship Country" Type="Syncfusion.Blazor.QueryBuilder.ColumnType.String"></QueryBuilderColumn>
                </QueryBuilderColumns>
            </SfQueryBuilder>
        </Content>
    </DialogTemplates>
    <DialogButtons>
        <DialogButton IsPrimary="true" Content="Reset" OnClick="@ResetClick" />
        <DialogButton IsPrimary="true" Content="Ok" OnClick="@OkClick" />
    </DialogButtons>
</SfDialog>
@code {
    SfQueryBuilder<Order> Querybuilder;
    public Query GridQuery { get; set; }
    public class Order
    {
        public int OrderID { get; set; }
        public string CustomerID { get; set; }
        public DateTime OrderDate { get; set; }
        public string ShipCity { get; set; }
        public string ShipCountry { get; set; }
    }

    private void Created()
    {
        GridQuery = Querybuilder.GetDataManagerQuery();
        StateHasChanged();
    }

    private bool Visibility { get; set; } = false;

    private void ResetClick()
    {
        Querybuilder.Reset();
    }
    private void OkClick()
    {
        GridQuery = Querybuilder.GetDataManagerQuery();
        StateHasChanged();
        this.Visibility = false;
    }

    private void openQueryBuilder()
    {
        this.Visibility = true;
    }
}

<style>
    .e-dialog {
        max-height: 500px !important;
        top: 30px !important;
        left: 0% !important;
    }
    .e-rule-filter .e-rule-filter {
        padding: 0 0 0 0 !important;
    }
</style>
```

![Integrating DataGrid with Blazor Query Builder Using Data Manager](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Integrating-DataGrid-with-Blazor-Query-Builder-Using-Data-Manager.gif)<figcaption>Integrating DataGrid with Blazor Query Builder Using Data Manager</figcaption>

## Importing and exporting

With Blazor Query Builder, you can import predefined conditions available in a list of rules or SQL query. You can also export the created conditions as a list of rules or SQL query.

**Note:** You can import the conditions either during initial rendering or after rendering.

The following code example demonstrates how to create a query builder with predefined rules.

```html
<SfQueryBuilder TValue="Employee">
    <QueryBuilderRule Condition="or" Rules="Rules"></QueryBuilderRule>
    <QueryBuilderColumns>
        <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="ColumnType.Number"></QueryBuilderColumn>
        <QueryBuilderColumn Field="FirstName" Label="First Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="LastName" Label="LastName" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="ColumnType.Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="Country" Label="Country" Type="ColumnType.String"></QueryBuilderColumn>
    </QueryBuilderColumns>
</SfQueryBuilder>

@code
{
    List<RuleModel> Rules = new List<RuleModel>()
    {
        new RuleModel {Field="Country", Label="Country", Type="String", Operator="equal", Value = "England”},
        new RuleModel {Field="EmployeeID", Label="EmployeeID", Type="Number", Operator="notequal", Value = 1001}
    };
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
        public string Country { get; set; }
    }
}
```

Users can set the conditions from the list of rules through the **SetRules** method and SQL query through the  **SetRulesFromSql**  method. In the following code example, we have explained the SetRulesFromSql method in the **Set Rules** button.

The following code example demonstrates how to set the rules from SQL in the Blazor Query Builder.

```html
<div style="width: 100%; margin-bottom: 10px;">
    <p>Enter the SQL Query</p>
    <textarea style="width: 100%;" id='ruleContent' @bind="Description"></textarea>
</div>
<div style="margin-bottom: 10px">
    <SfButton CssClass="e-primary" @onclick="setRules">Set Rules</SfButton>
</div>
<SfQueryBuilder TValue="Employee" @ref="QueryBuilderObj">
    <QueryBuilderColumns>
        <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="ColumnType.Number"></QueryBuilderColumn>
        <QueryBuilderColumn Field="FirstName" Label="First Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="LastName" Label="Last Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="ColumnType.Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="Country" Label="Country" Type="ColumnType.String"></QueryBuilderColumn>
    </QueryBuilderColumns>
</SfQueryBuilder>

@code {
    SfQueryBuilder<Employee> QueryBuilderObj;
    public string Description { get; set; } = string.Empty;
    private void setRules()
    {
        QueryBuilderObj.SetRulesFromSql(Description);
    }
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
        public string Country { get; set; }
    }
}
```

![Setting Rules from SQL Query in the Blazor Query Builder](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Setting-Rules-from-SQL-Query-into-the-Blazor-Query-Builder.gif)<figcaption>Setting Rules from SQL Query in the Blazor Query Builder</figcaption>

Also, users can get the conditions as a list of rules using the **GetRules** method and a SQL query as the  **GetRulesFromSql**  method. In the following code example, we have used the  **GetRulesFromSql** method on the button labelled **Get Query**.

The following code example demonstrates how to export the rules as SQL from the Blazor Query Builder.

```html
<SfQueryBuilder TValue="Employee" @ref="QueryBuilderObj">
    <QueryBuilderColumns>
        <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="ColumnType.Number"></QueryBuilderColumn>
        <QueryBuilderColumn Field="FirstName" Label="First Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="LastName" Label="Last Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="ColumnType.Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="Country" Label="Country" Type="ColumnType.String"></QueryBuilderColumn>
    </QueryBuilderColumns>
</SfQueryBuilder>
<div style="margin: 10px 0 10px 0">
    <SfButton CssClass="e-primary" @onclick="getQuery">Get Query</SfButton>
</div>
<div style="width: 100%; margin-bottom: 10px;">
    <p>SQL Query</p>
    <textarea style="width: 100%;" id='ruleContent' @bind="Description"></textarea>
</div>

@code {
    SfQueryBuilder<Employee> QueryBuilderObj;
    public string Description { get; set; } = string.Empty;
    private void getQuery()
    {
        Description = QueryBuilderObj.GetSqlFromRules();
    }
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
        public string Country { get; set; }
    }
}
```

![Exporting Rules as SQL Query from the Blazor Query Builder](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Exporting-Rules-as-SQL-Query-from-the-Blazor-Query-Builder.gif)<figcaption>Exporting Rules as SQL Query from the Blazor Query Builder</figcaption>

## Templates

To provide flexibility, the Blazor Query Builder offers template support. A template can include a mixture of static HTML and web controls. The Blazor Query Builder supports the following UI customizations:

- Value template: To customize the value column of a rule.
- Column template: To customize the entire rule.
- Header template: To customize the header of a group.

### Value template

You can render a custom UI to display the value column of a rule using the **template** property. In the following example, the Country field’s values are customized using the **ValueTemplate** property. A Dropdown List component is rendered for selecting the Country field value.

```html
<SfQueryBuilder TValue="Employee" @ref="QueryBuilderObj">
    <QueryBuilderColumns>
        <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="ColumnType.Number"></QueryBuilderColumn>
        <QueryBuilderColumn Field="FirstName" Label="First Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="LastName" Label="Last Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="ColumnType.Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="Country" Label="Country" Type="ColumnType.String">
            <QueryBuilderTemplates>
                <ValueTemplate>
                    <SfDropDownList TValue="string" Placeholder="Select Country" TItem="Country" DataSource="@CountriesList">
                        <DropDownListFieldSettings Text="Name"></DropDownListFieldSettings>
                        <DropDownListEvents TItem="Country" TValue="string" ValueChange="e => OnChange(e, context)"></DropDownListEvents>
                    </SfDropDownList>
                </ValueTemplate>
            </QueryBuilderTemplates>
        </QueryBuilderColumn>
    </QueryBuilderColumns>
</SfQueryBuilder>
<div style="margin: 10px 0 10px 0">
    <SfButton CssClass="e-primary" @onclick="getQuery">Get Query</SfButton>
</div>
<div style="width: 100%; margin-bottom: 10px;">
    <p>SQL Query</p>
    <textarea style="width: 100%;" id='ruleContent' @bind="Description"></textarea>
</div>

@code {
    SfQueryBuilder<Employee> QueryBuilderObj;
    public string Description { get; set; } = string.Empty;
    private void getQuery()
    {
        Description = QueryBuilderObj.GetSqlFromRules();
    }
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
        public string Country { get; set; }
    }
    public class Country
    {
        public string Name { get; set; }
    }
    public List<Country> CountriesList = new List<Country>() {
        new Country(){ Name = "England" },
        new Country(){ Name = "India" },
        new Country(){ Name = "Spain" },
        new Country(){ Name = "USA" }
    };
    public void OnChange(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, Country> args, RuleModel Rule)
    {
        Rule.Value = args.Value;
    }
}
```

![Customizing the Value Column of a Rule in Blazor Query Builder](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Customizing-the-Value-Column-of-a-Rule-in-Blazor-Query-Builder.gif)<figcaption>Customizing the Value Column of a Rule in Blazor Query Builder</figcaption>

### Column template

You can render a custom UI to display the entire rule using the **ColumnTemplate** property. In the following example, the Country field is customized using the **ColumnTemplate** property. In that, the operator is set to  **equal** by default and a Dropdown List component renders for both field and value columns.

```html
<SfQueryBuilder TValue="Employee" @ref="QueryBuilderObj">
    <QueryBuilderColumns>
        <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="ColumnType.Number"></QueryBuilderColumn>
        <QueryBuilderColumn Field="FirstName" Label="First Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="LastName" Label="Last Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="ColumnType.Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="Country" Label="Country" Type="ColumnType.String">
            <QueryBuilderTemplates>
                <ColumnTemplate>
                    <div class="e-rule-filter">
                        <SfDropDownList TItem="string" TValue="string" DataSource="QueryBuilderObj.Columns.Select(e => e.Field)" @bind-Value="context.Label">
                            <DropDownListEvents TItem="string" TValue="string" ValueChange="e => ChangeField(e, context)"></DropDownListEvents>
                        </SfDropDownList>
                    </div>
                    <div class="e-rule-value e-value">
                        <SfDropDownList TValue="string" Placeholder="Select Country" TItem="Country" DataSource="@CountriesList">
                            <DropDownListFieldSettings Text="Name"></DropDownListFieldSettings>
                            <DropDownListEvents TItem="Country" TValue="string" ValueChange="e => ChangeValue(e, context)"></DropDownListEvents>
                        </SfDropDownList>
                    </div>
                </ColumnTemplate>
            </QueryBuilderTemplates>
        </QueryBuilderColumn>
    </QueryBuilderColumns>
</SfQueryBuilder>
<div style="margin: 10px 0 10px 0">
    <SfButton CssClass="e-primary" @onclick="getQuery">Get Query</SfButton>
</div>
<div style="width: 100%; margin-bottom: 10px;">
    <p>SQL Query</p>
    <textarea style="width: 100%;" id='ruleContent' @bind="Description"></textarea>
</div>

@code 
{
    SfQueryBuilder<Employee> QueryBuilderObj;
    public string Description { get; set; } = string.Empty;
    private void getQuery()
    {
        Description = QueryBuilderObj.GetSqlFromRules();
    }
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
        public string Country { get; set; }
    }
    public class Country
    {
        public string Name { get; set; }
    }
    public List<Country> CountriesList = new List<Country>() {
        new Country(){ Name = "England" },
        new Country(){ Name = "India" },
        new Country(){ Name = "Spain" },
        new Country(){ Name = "USA" }
    };
    
    public void ChangeField(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, string> args, RuleModel Rule)
    {
        Rule.Field = args.Value;
        Rule.Label = args.Value;
        Rule.Type = "String";
    }
    public void ChangeValue(Syncfusion.Blazor.DropDowns.ChangeEventArgs<string, Country> args, RuleModel Rule)
    {
        Rule.Value = args.Value;
        Rule.Operator = "equal";
    }
}
```

![Customizing the Entire Rule in Blazor Query Builder](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Customizing-the-Entire-Rule-in-Blazor-Query-Builder.gif)<figcaption>Customizing the Entire Rule in Blazor Query Builder</figcaption>

### Header template

Users can render a custom UI to display the header of a group using the **HeaderTemplate** property.

```html
<SfQueryBuilder TValue="Employee" @ref="QueryBuilderObj">
    <QueryBuilderTemplates>
        <HeaderTemplate>
            <SfDropDownList ID="@context.ID" @bind-Value="DefaultCondition" TValue="string" TItem="Condition" CssClass="e-outline" Width="100px" DataSource="@ConditionsList">
                <DropDownListFieldSettings Text="Text" Value="Value"></DropDownListFieldSettings>
                <DropDownListEvents TValue="string" TItem="Condition" ValueChange="e => conditionChange(e, context)"></DropDownListEvents>
            </SfDropDownList>
            <div class="e-header">
                <div class="e-content">
                    <SfButton Content="Add Group" CssClass="e-custom-button" @onclick="e => addGroup(e, context)"></SfButton>
                </div>
                <div class="e-content">
                    <SfButton Content="Add Condition" CssClass="e-custom-button" @onclick="e => addCondition(e, context)"></SfButton>
                </div>
                @if (context.ID.Split("_")[1].IndexOf("0") < 0)
                {
                    <div class="e-content">
                        <SfButton Content="Delete Group" CssClass="e-custom-button e-danger" @onclick="e => deleteGroup(e, context)"></SfButton>
                    </div>
                }
            </div>
        </HeaderTemplate>
    </QueryBuilderTemplates>
    <QueryBuilderColumns>
        <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="ColumnType.Number"></QueryBuilderColumn>
        <QueryBuilderColumn Field="FirstName" Label="First Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="LastName" Label="Last Name" Type="ColumnType.String"></QueryBuilderColumn>
        <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="ColumnType.Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="Country" Label="Country" Type="ColumnType.String"></QueryBuilderColumn>
    </QueryBuilderColumns>
</SfQueryBuilder>
<div style="margin: 10px 0 10px 0">
    <SfButton CssClass="e-primary" @onclick="getQuery">Get Query</SfButton>
</div>
<div style="width: 100%; margin-bottom: 10px;">
    <p>SQL Query</p>
    <textarea style="width: 100%;" id='ruleContent' @bind="Description"></textarea>
</div>

@code {
    SfQueryBuilder<Employee> QueryBuilderObj;
    private string groupID;
    public string DefaultCondition { get; set; } = "and";
    public string Description { get; set; } = string.Empty;
    private void getQuery()
    {
        Description = QueryBuilderObj.GetSqlFromRules();
    }
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime HireDate { get; set; }
        public string Country { get; set; }
    }
    public class Condition
    {
        public string Text { get; set; }
        public string Value { get; set; }
    }
    public List<Condition> ConditionsList = new List<Condition>() {
        new Condition(){ Text = "AND", Value = "and" },
        new Condition(){ Text = "OR", Value = "or" }
    };

    private void conditionChange(ChangeEventArgs<string, Condition> args, HeaderTemplateModel model)
    {
        if (args.IsInteracted)
        {
            DefaultCondition = model.Condition = args.Value.ToLower();
        }
    }
    private void addGroup(MouseEventArgs args, HeaderTemplateModel model)
    {
        groupID = model.ID.Split("_")[1];
        QueryBuilderObj.AddGroup(new RuleModel { Condition = "or", Rules = new List<RuleModel>() { new RuleModel() } }, groupID);
    }
    private void addCondition(MouseEventArgs args, HeaderTemplateModel model)
    {
        groupID = model.ID.Split("_")[1];
        QueryBuilderObj.AddRule(new RuleModel(), groupID);
    }
    private void deleteGroup(MouseEventArgs args, HeaderTemplateModel model)
    {
        groupID = model.ID.Split("_")[1];
        QueryBuilderObj.DeleteGroup(groupID);
    }
}

<style>
    .e-custom-button {
        font-size: 13px;
    }
    .e-header {
        display: inline-block;
        float: right;
    }
    .e-content {
        display: inline-block;
        padding: 0 0 0 12px;
    }
</style>
```

![Customizing the Header of a Group in Blazor Query Builder](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Customizing-the-Header-of-a-Group-in-Blazor-Query-Builder.gif)<figcaption>Customizing the Header of a Group in Blazor Query Builder</figcaption>

## Grouping and sorting

You can sort the columns alphabetically and numerically using the **SortDirection** property. This property can be set to default, ascending, or descending.

You can group the columns using the **Category** property, which is inside the **Columns** property. The default name of the group is **Other Fields.**

The following code snippet demonstrates the grouping and sorting of columns in Blazor Query Builder.

```html
<SfQueryBuilder TValue="Employee" SortDirection="SortDirection.Descending">
    <QueryBuilderColumns>
        <QueryBuilderColumn Field="EmployeeID" Label="Employee ID" Type="ColumnType.Number"></QueryBuilderColumn>
        <QueryBuilderColumn Field="FirstName" Label="First Name" Type="ColumnType.String" Category="Name"></QueryBuilderColumn>
        <QueryBuilderColumn Field="LastName" Label="Last Name" Type="ColumnType.String" Category="Name"></QueryBuilderColumn>
        <QueryBuilderColumn Field="BirthDate" Label="Birth Date" Type="ColumnType.Date" Category="Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="HireDate" Label="Hire Date" Type="ColumnType.Date" Category="Date"></QueryBuilderColumn>
        <QueryBuilderColumn Field="Country" Label="Country" Type="ColumnType.String"></QueryBuilderColumn>
    </QueryBuilderColumns>
</SfQueryBuilder>

@code {
    public class Employee
    {
        public int EmployeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
        public DateTime HireDate { get; set; }
        public string Country { get; set; }
    }
}
```

![Grouping and Sorting of Columns in Descending Order in Blazor Query Builder](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Grouping-and-Sorting-of-Columns-in-Descending-Order-in-Blazor-Query-Builder.gif)<figcaption>Grouping and Sorting of Columns in Descending Order in Blazor Query Builder</figcaption>

## Conclusion

I hope you now have a better understanding of the major features of the [Blazor Query Builder](https://www.syncfusion.com/blazor-components/blazor-query-builder "Link to Blazor Query Builder") control. With these features, you can easily fetch large volumes of data from a database. This saves lot of time and enhances your productivity.

For more info, go through our Blazor Query Builder’s [user guide documentation](https://blazor.syncfusion.com/documentation/query-builder/getting-started/ "Link to Getting started with Blazor QueryBuilder component") and [online demos](https://blazor.syncfusion.com/demos/query-builder/default-functionalities "Link to Blazor Query Builder's online demos"). What else do you expect from this control? Please share your thoughts in the comments section.

If you’re already a Syncfusion user, you can download Essential Studio for Blazor’s [product setup](https://www.syncfusion.com/account/downloads "Link to license and download page of Essential Studio") to try out this control. Otherwise, you can download a free [30-day trial](https://www.syncfusion.com/downloads/fileformats/verify "Link to the free evaluation of the Syncfusion Essential Studio").

You can contact us through our [support forum](https://www.syncfusion.com/forums "Link to the Syncfusion support forum"), [Direct-Trac](https://www.syncfusion.com/support/directtrac/ "Link to the Syncfusion support system Direct Trac"), or [feedback portal](https://www.syncfusion.com/feedback/blazor-components "Link to Syncfusion Blazor Feedback Portal"). We are always happy to assist you!

## Related blogs

- [Exploring Blazor Hybrid App using Mobile Blazor Bindings](https://dev.to/syncfusion/exploring-blazor-hybrid-app-using-mobile-blazor-bindings-1o49 "Link to Exploring Blazor Hybrid App using Mobile Blazor Bindings blog")
- [How to Preview Images in Syncfusion Blazor File Upload Component](https://dev.to/syncfusion/how-to-preview-images-in-syncfusion-blazor-file-upload-component-3ohn "Link to How to Preview Images in Syncfusion Blazor File Upload Component blog")
- [Blazor: Live Preview Markdown Editor’s Content Using Markdig Library](https://dev.to/syncfusion/blazor-live-preview-markdown-editor-s-content-using-markdig-library-f4a "Link to Blazor: Live Preview Markdown Editor’s Content Using Markdig Library blog")
- [ASP.NET Core Blazor Component Virtualization in .NET 5 – An Overview](https://dev.to/karthickramasamy08/asp-net-core-blazor-component-virtualization-in-net-5-an-overview-1im1-temp-slug-215790 "Link to ASP.NET Core Blazor Component Virtualization in .NET 5 – An Overview blog")
- [Exploring Syncfusion Blazor Components on Cross-Platform Desktop Apps Using Electron](https://dev.to/syncfusion/exploring-syncfusion-blazor-components-on-cross-platform-desktop-apps-using-electron-1g9k "Link to Exploring Syncfusion Blazor Components on Cross-Platform Desktop Apps Using Electron blog")