diff --git a/browser/IgBlazorSamples.Client/wwwroot/index.html b/browser/IgBlazorSamples.Client/wwwroot/index.html
index 919efc3323..dfb2463b08 100644
--- a/browser/IgBlazorSamples.Client/wwwroot/index.html
+++ b/browser/IgBlazorSamples.Client/wwwroot/index.html
@@ -243,6 +243,8 @@
+
+
diff --git a/samples/grids/grid/column-selection-styles/ReadMe.md b/samples/grids/grid/column-selection-styles/ReadMe.md
index 65ca4310da..e686a67c49 100644
--- a/samples/grids/grid/column-selection-styles/ReadMe.md
+++ b/samples/grids/grid/column-selection-styles/ReadMe.md
@@ -3,10 +3,8 @@
This folder contains implementation of Blazor application with example of Column Selection Styles feature using [Grid](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
-
-
@@ -30,11 +28,11 @@ This folder contains implementation of Blazor application with example of Column
- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
-## Running App in Visual Studio 2019
+## Running App in Visual Studio 2022
-NOTE: VS 2019 has better code highlighting and error detection than VS Code does.
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
-- open **Visual Studio 2019** as an administrator
+- open **Visual Studio 2022** as an administrator
- open the **BlazorClientApp.sln** solution
diff --git a/samples/grids/grid/remote-paging-data/ReadMe.md b/samples/grids/grid/remote-paging-data/ReadMe.md
index bae218f685..c7518c21fe 100644
--- a/samples/grids/grid/remote-paging-data/ReadMe.md
+++ b/samples/grids/grid/remote-paging-data/ReadMe.md
@@ -1,23 +1,21 @@
-This folder contains implementation of Blazor application with example of Remote Paging Hgrid feature using [Hierarchical Grid](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
-
+This folder contains implementation of Blazor application with example of Remote Paging Data feature using [Grid](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
-
-
+
-
+
-
-
+
+
-
@@ -30,11 +28,11 @@ This folder contains implementation of Blazor application with example of Remote
- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
-## Running App in Visual Studio 2019
+## Running App in Visual Studio 2022
-NOTE: VS 2019 has better code highlighting and error detection than VS Code does.
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
-- open **Visual Studio 2019** as an administrator
+- open **Visual Studio 2022** as an administrator
- open the **BlazorClientApp.sln** solution
diff --git a/samples/grids/tree/styling/README.md b/samples/grids/tree/styling/README.md
index 778123feca..fcd862ba4e 100644
--- a/samples/grids/tree/styling/README.md
+++ b/samples/grids/tree/styling/README.md
@@ -1,7 +1,7 @@
-This folder contains implementation of Blazor application with example of Styling Example feature using [Tree](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
+This folder contains implementation of Blazor application with example of Styling feature using [Tree](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
diff --git a/samples/interactions/query-builder/overview/App.razor b/samples/interactions/query-builder/overview/App.razor
new file mode 100644
index 0000000000..8c8d4bf5e1
--- /dev/null
+++ b/samples/interactions/query-builder/overview/App.razor
@@ -0,0 +1,108 @@
+@using IgniteUI.Blazor.Controls
+@inject IJSRuntime JS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@code {
+ private static readonly string[] InitialReturnFields =
+ [
+ "orderId",
+ "customerId",
+ "employeeId",
+ "shipperId",
+ "orderDate",
+ "requiredDate",
+ "shipVia",
+ "freight",
+ "shipName",
+ "completed"
+ ];
+
+ private static readonly IgbFieldType[] CustomerFields =
+ [
+ new() { Field = "customerId", DataType = GridColumnDataType.String },
+ new() { Field = "companyName", DataType = GridColumnDataType.String },
+ new() { Field = "contactName", DataType = GridColumnDataType.String },
+ new() { Field = "contactTitle", DataType = GridColumnDataType.String }
+ ];
+
+ private static readonly IgbFieldType[] OrderFields =
+ [
+ new() { Field = "orderId", DataType = GridColumnDataType.Number },
+ new() { Field = "customerId", DataType = GridColumnDataType.String },
+ new() { Field = "employeeId", DataType = GridColumnDataType.Number },
+ new() { Field = "shipperId", DataType = GridColumnDataType.Number },
+ new() { Field = "orderDate", DataType = GridColumnDataType.Date },
+ new() { Field = "requiredDate", DataType = GridColumnDataType.Date },
+ new() { Field = "shipVia", DataType = GridColumnDataType.String },
+ new() { Field = "freight", DataType = GridColumnDataType.Number },
+ new() { Field = "shipName", DataType = GridColumnDataType.String },
+ new() { Field = "completed", DataType = GridColumnDataType.Boolean }
+ ];
+
+ private static readonly IgbEntityType[] Entities =
+ [
+ new() { Name = "Customers", Fields = CustomerFields },
+ new() { Name = "Orders", Fields = OrderFields }
+ ];
+
+ private static readonly IgbExpressionTree ExpressionTree = new()
+ {
+ FilteringOperands = [],
+ Operator = FilteringLogic.And,
+ Entity = "Orders",
+ ReturnFields = InitialReturnFields
+ };
+
+ private IgbQueryBuilder queryBuilder;
+ private IgbGrid grid;
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (!firstRender || queryBuilder is null || grid is null)
+ {
+ return;
+ }
+
+ await queryBuilder.EnsureReady();
+ await grid.EnsureReady();
+
+ await JS.InvokeVoidAsync("queryBuilderOverview.loadInitialData", new
+ {
+ filteringOperands = Array.Empty(),
+ @operator = 0,
+ entity = "Orders",
+ returnFields = InitialReturnFields
+ });
+ }
+}
diff --git a/samples/interactions/query-builder/overview/BlazorClientApp.csproj b/samples/interactions/query-builder/overview/BlazorClientApp.csproj
new file mode 100644
index 0000000000..0900cd9d5b
--- /dev/null
+++ b/samples/interactions/query-builder/overview/BlazorClientApp.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net10.0
+ 3.0
+ Infragistics.Samples
+ Infragistics.Samples
+
+
+
+ 1701;1702,IDE0028,BL0005,0219,CS1998
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/interactions/query-builder/overview/BlazorClientApp.sln b/samples/interactions/query-builder/overview/BlazorClientApp.sln
new file mode 100644
index 0000000000..4f55a6ee4b
--- /dev/null
+++ b/samples/interactions/query-builder/overview/BlazorClientApp.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 18
+VisualStudioVersion = 18.2.11415.280 d18.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorClientApp", "BlazorClientApp.csproj", "{F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FC52AAC8-4488-40AE-9621-75F6BA744B18}
+ EndGlobalSection
+EndGlobal
diff --git a/samples/interactions/query-builder/overview/Program.cs b/samples/interactions/query-builder/overview/Program.cs
new file mode 100644
index 0000000000..43376cb1d0
--- /dev/null
+++ b/samples/interactions/query-builder/overview/Program.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+
+// required for registering IgniteUIBlazor
+using IgniteUI.Blazor.Controls;
+
+namespace Infragistics.Samples
+{
+ public class Program
+ {
+ public static async Task Main(string[] args)
+ {
+ var builder = WebAssemblyHostBuilder.CreateDefault(args);
+ builder.RootComponents.Add("app");
+
+ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
+
+ // registering Infragistics Blazor
+ builder.Services.AddIgniteUIBlazor(
+ typeof(IgbQueryBuilderModule),
+ typeof(IgbGridModule)
+ );
+
+ await builder.Build().RunAsync();
+ }
+ }
+}
diff --git a/samples/interactions/query-builder/overview/Properties/launchSettings.json b/samples/interactions/query-builder/overview/Properties/launchSettings.json
new file mode 100644
index 0000000000..468407d277
--- /dev/null
+++ b/samples/interactions/query-builder/overview/Properties/launchSettings.json
@@ -0,0 +1,27 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:4200",
+ "sslPort": 44385
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "BlazorClientApp": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:4200"
+ }
+ }
+}
diff --git a/samples/interactions/query-builder/overview/README.md b/samples/interactions/query-builder/overview/README.md
new file mode 100644
index 0000000000..52e5b902c6
--- /dev/null
+++ b/samples/interactions/query-builder/overview/README.md
@@ -0,0 +1,68 @@
+
+
+
+This folder contains implementation of Blazor application with example of Overview feature using [Query Builder](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Branches
+
+> **_NOTE:_** You should use [master](https://github.com/IgniteUI/igniteui-blazor-examples/tree/master) branch of this repository if you want to run samples on your computer. Use the [vnext](https://github.com/IgniteUI/igniteui-blazor-examples/tree/vnext) branch only when you want to contribute new samples to this repository.
+
+## Setup
+
+- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
+
+## Running App in Visual Studio 2022
+
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
+
+- open **Visual Studio 2022** as an administrator
+
+- open the **BlazorClientApp.sln** solution
+
+- right click solution and select **Restore NuGet Packages** menu item
+
+- click **Debug** menu and select **Start Debugging** or press **F5** key
+
+
+## Running App in VS Code
+
+- open **VS Code** as an administrator
+
+- open this folder in **VS Code**
+
+- open a terminal window
+
+- to restore assemblies, run this command:
+```dotnet restore```
+
+- to run samples, run this command:
+```dotnet watch run```
+
+- wait for for message:
+**Now listening on: http://localhost:4200**
+
+- open **http://localhost:4200** in your browser
+
+
+## Resources
+
+- [Razor Component Models](https://www.codemag.com/article/1911052)
+- [Razor Syntax](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-3.1#razor-syntax)
+- [Getting reference to components](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-3.1#capture-references-to-components)
diff --git a/samples/interactions/query-builder/overview/_Imports.razor b/samples/interactions/query-builder/overview/_Imports.razor
new file mode 100644
index 0000000000..b4bad03986
--- /dev/null
+++ b/samples/interactions/query-builder/overview/_Imports.razor
@@ -0,0 +1,8 @@
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.AspNetCore.Components.WebAssembly.Http
+@using Microsoft.JSInterop
+@using Infragistics.Samples
diff --git a/samples/interactions/query-builder/overview/wwwroot/events.js b/samples/interactions/query-builder/overview/wwwroot/events.js
new file mode 100644
index 0000000000..0fbd4cb943
--- /dev/null
+++ b/samples/interactions/query-builder/overview/wwwroot/events.js
@@ -0,0 +1,115 @@
+const API_ENDPOINT = 'https://data-northwind.indigo.design';
+
+async function syncTreeOnExpressionChange(detail) {
+ const grid = await waitForGrid();
+ if (!grid) {
+ return;
+ }
+
+ const expressionTree = detail;
+ if (typeof expressionTree?.operator === 'string') {
+ const normalizedOperator = expressionTree.operator.toLowerCase();
+ if (normalizedOperator === 'and') {
+ expressionTree.operator = 0;
+ } else if (normalizedOperator === 'or') {
+ expressionTree.operator = 1;
+ }
+ }
+
+ grid.isLoading = true;
+
+ try {
+ const res = await fetch(`${API_ENDPOINT}/QueryBuilder/ExecuteQuery`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(expressionTree)
+ });
+
+ if (!res.ok) {
+ throw new Error(`ExecuteQuery failed: ${res.status} ${res.statusText}`);
+ }
+
+ const json = await res.json();
+ grid.data = Object.values(json)[0] ?? [];
+ } catch (error) {
+ console.error(error);
+ grid.data = [];
+ } finally {
+ grid.isLoading = false;
+ await nextFrame();
+ calculateColsInView(grid, expressionTree);
+ if (typeof grid.markForCheck === 'function') {
+ grid.markForCheck();
+ }
+ }
+}
+
+function calculateColsInView(grid, expressionTree) {
+ const returnFields = expressionTree?.returnFields ?? [];
+
+ if (returnFields.length === 0 || returnFields[0] === '*') {
+ const queryBuilder = document.querySelector('igc-query-builder, igx-query-builder');
+ const entities = queryBuilder?.entities ?? [];
+ const selectedEntity = entities.find(entity => entity.name === expressionTree?.entity);
+ const selectedEntityFields = (selectedEntity?.fields ?? []).map(field => field.field);
+ grid.columns.forEach(column => {
+ column.hidden = !selectedEntityFields.includes(column.field);
+ });
+ return;
+ }
+
+ grid.columns.forEach(column => {
+ column.hidden = !returnFields.includes(column.field);
+ });
+}
+
+function nextFrame() {
+ return new Promise(resolve => requestAnimationFrame(() => resolve()));
+}
+
+function waitForGrid(attempts = 120) {
+ return new Promise(resolve => {
+ const tryResolve = () => {
+ const gridById = document.getElementById('grid');
+ const directGrid = isGridReady(gridById) ? gridById : null;
+ const customElementGrid = document.querySelector('igc-grid');
+ const grid = directGrid ?? (isGridReady(customElementGrid) ? customElementGrid : null);
+
+ if (grid) {
+ resolve(grid);
+ return;
+ }
+
+ if (attempts <= 0) {
+ resolve(null);
+ return;
+ }
+
+ attempts -= 1;
+ requestAnimationFrame(tryResolve);
+ };
+
+ tryResolve();
+ });
+}
+
+function isGridReady(grid) {
+ return Boolean(grid)
+ && typeof grid === 'object'
+ && 'data' in grid
+ && 'isLoading' in grid
+ && 'columns' in grid;
+}
+
+window.queryBuilderOverview = {
+ loadInitialData: syncTreeOnExpressionChange
+};
+
+igRegisterScript("WebQueryBuilderExpressionTreeChange", async (evtArgs) => {
+ const detail = evtArgs?.detail;
+ if (!detail) {
+ return;
+ }
+
+ await syncTreeOnExpressionChange(detail);
+}, false);
diff --git a/samples/interactions/query-builder/overview/wwwroot/index.css b/samples/interactions/query-builder/overview/wwwroot/index.css
new file mode 100644
index 0000000000..cf2b80012f
--- /dev/null
+++ b/samples/interactions/query-builder/overview/wwwroot/index.css
@@ -0,0 +1,4 @@
+/*
+CSS styles are loaded from the shared CSS file located at:
+https://dl.infragistics.com/x/css/samples/shared.v6.css
+*/
diff --git a/samples/interactions/query-builder/overview/wwwroot/index.html b/samples/interactions/query-builder/overview/wwwroot/index.html
new file mode 100644
index 0000000000..9daa43125e
--- /dev/null
+++ b/samples/interactions/query-builder/overview/wwwroot/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ Samples | IgniteUI for Blazor | Infragistics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ An unhandled error has occurred.
+
Reload
+
🗙
+
+
+
+
+
+
+
diff --git a/samples/interactions/query-builder/template/App.razor b/samples/interactions/query-builder/template/App.razor
new file mode 100644
index 0000000000..0ced98bb27
--- /dev/null
+++ b/samples/interactions/query-builder/template/App.razor
@@ -0,0 +1,125 @@
+@using IgniteUI.Blazor.Controls
+@inject IJSRuntime JS
+
+
+
+@code {
+
+ private IgbQueryBuilder queryBuilder;
+ private IgbIcon RegisterIconRef { get; set; }
+
+ private static readonly IgbFieldType[] OrderFields =
+ [
+ new() { Field = "CompanyID", DataType = GridColumnDataType.String },
+ new() { Field = "OrderID", DataType = GridColumnDataType.Number },
+ new() { Field = "Freight", DataType = GridColumnDataType.Number },
+ new() { Field = "ShipCountry", DataType = GridColumnDataType.String },
+ new() { Field = "IsRushOrder", DataType = GridColumnDataType.Boolean },
+ new()
+ {
+ Field = "RequiredTime",
+ DataType = GridColumnDataType.DateTime,
+ DefaultTimeFormat = "hh:mm tt"
+ },
+ new()
+ {
+ Field = "OrderDate",
+ DataType = GridColumnDataType.Date,
+ PipeArgs = new IgbFieldPipeArgs { Format = "MMM d, y" }
+ },
+ new() { Field = "Region", DataType = GridColumnDataType.String },
+ new() { Field = "OrderStatus", DataType = GridColumnDataType.Number }
+ ];
+
+ private static readonly IgbEntityType[] Entities =
+ [
+ new()
+ {
+ Name = "Orders",
+ Fields = OrderFields
+ }
+ ];
+
+ private static readonly (string Text, string Value)[] RegionOptions =
+ [
+ new("Central North America", "CNA"),
+ new("Central Europe", "CEU"),
+ new("Mediterranean region", "MED"),
+ new("Central Asia", "CAS"),
+ new("South Asia", "SAS"),
+ new("Western Africa", "WAF"),
+ new("Amazonia", "AMZ"),
+ new("Southern Africa", "SAF"),
+ new("Northern Australia", "NAU")
+ ];
+
+ private static readonly (string Text, int Value)[] StatusOptions =
+ [
+ new("New", 1),
+ new("Shipped", 2),
+ new("Done", 3)
+ ];
+
+ private static readonly IgbExpressionTree ExpressionTree = new()
+ {
+ Operator = FilteringLogic.And,
+ Entity = "Orders",
+ ReturnFields = ["*"],
+ FilteringOperands =
+ [
+ new IgbFilteringExpression
+ {
+ FieldName = "Region",
+ ConditionName = "equals",
+ SearchVal = RegionOptions[0].Value
+ },
+ new IgbFilteringExpression
+ {
+ FieldName = "OrderStatus",
+ ConditionName = "equals",
+ SearchVal = StatusOptions[0].Value
+ }
+ ]
+ };
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (!firstRender || queryBuilder is null)
+ {
+ return;
+ }
+
+ await this.RegisterIcons();
+ await queryBuilder.EnsureReady();
+ await JS.InvokeVoidAsync("queryBuilderTemplate.init", RegionOptions, StatusOptions);
+ }
+
+ private async Task RegisterIcons()
+ {
+ if (this.RegisterIconRef is null)
+ {
+ return;
+ }
+
+ await this.RegisterIconRef.EnsureReady();
+
+ const string clockIcon = " ";
+ await this.RegisterIconRef.RegisterIconFromTextAsync("clock", clockIcon, "material");
+ }
+
+
+}
diff --git a/samples/interactions/query-builder/template/BlazorClientApp.csproj b/samples/interactions/query-builder/template/BlazorClientApp.csproj
new file mode 100644
index 0000000000..cab6aabaa3
--- /dev/null
+++ b/samples/interactions/query-builder/template/BlazorClientApp.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net10.0
+ 3.0
+ Infragistics.Samples
+ Infragistics.Samples
+
+
+
+ 1701;1702,IDE0028,BL0005,0219,CS1998
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/interactions/query-builder/template/BlazorClientApp.sln b/samples/interactions/query-builder/template/BlazorClientApp.sln
new file mode 100644
index 0000000000..4f55a6ee4b
--- /dev/null
+++ b/samples/interactions/query-builder/template/BlazorClientApp.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 18
+VisualStudioVersion = 18.2.11415.280 d18.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorClientApp", "BlazorClientApp.csproj", "{F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F69CC3F0-BCD1-4CE6-9F39-CBED14E7FA78}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FC52AAC8-4488-40AE-9621-75F6BA744B18}
+ EndGlobalSection
+EndGlobal
diff --git a/samples/interactions/query-builder/template/Program.cs b/samples/interactions/query-builder/template/Program.cs
new file mode 100644
index 0000000000..068c16482c
--- /dev/null
+++ b/samples/interactions/query-builder/template/Program.cs
@@ -0,0 +1,32 @@
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+
+// required for registering IgniteUIBlazor
+using IgniteUI.Blazor.Controls;
+
+namespace Infragistics.Samples
+{
+ public class Program
+ {
+ public static async Task Main(string[] args)
+ {
+ var builder = WebAssemblyHostBuilder.CreateDefault(args);
+ builder.RootComponents.Add("app");
+
+ // registering Infragistics Blazor
+ builder.Services.AddIgniteUIBlazor(
+ typeof(IgbQueryBuilderModule),
+ typeof(IgbDatePickerModule),
+ typeof(IgbDateTimeInputModule),
+ typeof(IgbSelectModule),
+ typeof(IgbRadioGroupModule),
+ typeof(IgbRadioModule),
+ typeof(IgbInputModule),
+ typeof(IgbIconModule)
+ );
+
+ await builder.Build().RunAsync();
+ }
+ }
+}
diff --git a/samples/interactions/query-builder/template/Properties/launchSettings.json b/samples/interactions/query-builder/template/Properties/launchSettings.json
new file mode 100644
index 0000000000..468407d277
--- /dev/null
+++ b/samples/interactions/query-builder/template/Properties/launchSettings.json
@@ -0,0 +1,27 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:4200",
+ "sslPort": 44385
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "BlazorClientApp": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:4200"
+ }
+ }
+}
diff --git a/samples/interactions/query-builder/template/README.md b/samples/interactions/query-builder/template/README.md
new file mode 100644
index 0000000000..d1b0deea20
--- /dev/null
+++ b/samples/interactions/query-builder/template/README.md
@@ -0,0 +1,68 @@
+
+
+
+This folder contains implementation of Blazor application with example of Template feature using [Query Builder](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Branches
+
+> **_NOTE:_** You should use [master](https://github.com/IgniteUI/igniteui-blazor-examples/tree/master) branch of this repository if you want to run samples on your computer. Use the [vnext](https://github.com/IgniteUI/igniteui-blazor-examples/tree/vnext) branch only when you want to contribute new samples to this repository.
+
+## Setup
+
+- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
+
+## Running App in Visual Studio 2022
+
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
+
+- open **Visual Studio 2022** as an administrator
+
+- open the **BlazorClientApp.sln** solution
+
+- right click solution and select **Restore NuGet Packages** menu item
+
+- click **Debug** menu and select **Start Debugging** or press **F5** key
+
+
+## Running App in VS Code
+
+- open **VS Code** as an administrator
+
+- open this folder in **VS Code**
+
+- open a terminal window
+
+- to restore assemblies, run this command:
+```dotnet restore```
+
+- to run samples, run this command:
+```dotnet watch run```
+
+- wait for for message:
+**Now listening on: http://localhost:4200**
+
+- open **http://localhost:4200** in your browser
+
+
+## Resources
+
+- [Razor Component Models](https://www.codemag.com/article/1911052)
+- [Razor Syntax](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-3.1#razor-syntax)
+- [Getting reference to components](https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-3.1#capture-references-to-components)
diff --git a/samples/interactions/query-builder/template/_Imports.razor b/samples/interactions/query-builder/template/_Imports.razor
new file mode 100644
index 0000000000..bcc3a5933e
--- /dev/null
+++ b/samples/interactions/query-builder/template/_Imports.razor
@@ -0,0 +1,5 @@
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.JSInterop
+@using Infragistics.Samples
diff --git a/samples/interactions/query-builder/template/wwwroot/events.js b/samples/interactions/query-builder/template/wwwroot/events.js
new file mode 100644
index 0000000000..0accae0020
--- /dev/null
+++ b/samples/interactions/query-builder/template/wwwroot/events.js
@@ -0,0 +1,258 @@
+let regionOptions = [];
+let statusOptions = [];
+
+function ensureImplicit(ctx) {
+ if (!ctx.implicit) {
+ ctx.implicit = { value: null };
+ }
+}
+
+function matchesEqualityCondition(condition) {
+ return condition === 'equals' || condition === 'doesNotEqual';
+}
+
+function normalizeTimeValue(value) {
+ if (!value) {
+ return null;
+ }
+
+ if (value instanceof Date) {
+ return value;
+ }
+
+ if (typeof value === 'string') {
+ const isoCandidate = value.includes('T') ? value : `1970-01-01T${value}`;
+ const parsed = new Date(isoCandidate);
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
+ }
+
+ if (typeof value === 'number') {
+ const parsed = new Date(value);
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
+ }
+
+ return null;
+}
+
+function buildRegionSelect(ctx) {
+ const select = document.createElement('igc-select');
+ const currentValue = ctx && ctx.implicit && ctx.implicit.value
+ ? ctx.implicit.value.value ?? ''
+ : '';
+
+ select.placeholder = 'Region';
+ if (currentValue) {
+ select.value = currentValue;
+ }
+
+ for (const option of regionOptions) {
+ const item = document.createElement('igc-select-item');
+ item.setAttribute('value', option.value);
+ item.textContent = option.text;
+ select.appendChild(item);
+ }
+
+ select.addEventListener('igcChange', (event) => {
+ const value = event && event.detail ? event.detail.value : null;
+ const currentKey = ctx && ctx.implicit && ctx.implicit.value
+ ? ctx.implicit.value.value ?? ''
+ : '';
+
+ if (!value || value === currentKey) {
+ return;
+ }
+
+ ctx.implicit.value = regionOptions.find((option) => option.value === value) ?? null;
+ });
+
+ return select;
+}
+
+function buildStatusRadios(ctx) {
+ const group = document.createElement('igc-radio-group');
+ const implicitValue = ctx && ctx.implicit ? ctx.implicit.value : null;
+ const currentValue = implicitValue == null ? '' : implicitValue.toString();
+
+ group.style.gap = '5px';
+ group.alignment = 'horizontal';
+ group.value = currentValue;
+
+ for (const option of statusOptions) {
+ const radio = document.createElement('igc-radio');
+ radio.setAttribute('name', 'status');
+ radio.setAttribute('value', option.value.toString());
+ radio.checked = option.value.toString() === currentValue;
+ radio.textContent = option.text;
+ group.appendChild(radio);
+ }
+
+ group.addEventListener('igcChange', (event) => {
+ const value = event && event.detail ? event.detail.value : undefined;
+ if (value === undefined) {
+ return;
+ }
+
+ const numericValue = Number(value);
+ if (ctx.implicit.value === numericValue) {
+ return;
+ }
+
+ ctx.implicit.value = numericValue;
+ });
+
+ return group;
+}
+
+function buildDatePicker(ctx) {
+ const picker = document.createElement('igc-date-picker');
+ const implicitValue = ctx && ctx.implicit ? ctx.implicit.value : null;
+ const currentValue = implicitValue instanceof Date
+ ? implicitValue
+ : implicitValue
+ ? new Date(implicitValue)
+ : null;
+
+ const allowedConditions = ['equals', 'doesNotEqual', 'before', 'after'];
+ const isEnabled = allowedConditions.includes(ctx.selectedCondition ?? '');
+
+ picker.disabled = !isEnabled;
+ if (currentValue) {
+ picker.value = currentValue;
+ }
+
+ picker.addEventListener('click', () => {
+ if (typeof picker.show === 'function') {
+ picker.show();
+ }
+ });
+
+ picker.addEventListener('igcChange', (event) => {
+ ctx.implicit.value = event ? event.detail : null;
+ });
+
+ return picker;
+}
+
+function buildTimeInput(ctx) {
+ const input = document.createElement('igc-date-time-input');
+ const icon = document.createElement('igc-icon');
+ const currentValue = normalizeTimeValue(ctx && ctx.implicit ? ctx.implicit.value : null);
+ const allowedConditions = ['at', 'not_at', 'at_before', 'at_after', 'before', 'after'];
+ const isDisabled = ctx.selectedField == null || !allowedConditions.includes(ctx.selectedCondition ?? '');
+
+ input.inputFormat = 'hh:mm tt';
+ input.disabled = isDisabled;
+ if (currentValue) {
+ input.value = currentValue;
+ }
+
+ icon.slot = 'prefix';
+ icon.setAttribute('name', 'clock');
+ icon.setAttribute('collection', 'material');
+ input.appendChild(icon);
+
+ input.addEventListener('igcChange', (event) => {
+ const picker = event ? event.currentTarget : null;
+ ctx.implicit.value = picker && 'value' in picker ? picker.value : null;
+ });
+
+ return input;
+}
+
+function buildDefaultInput(ctx, equalityCondition) {
+ const input = document.createElement('igc-input');
+ const selectedField = ctx.selectedField;
+ const dataType = selectedField ? selectedField.dataType : null;
+ const isNumber = dataType === 'number';
+ const isBoolean = dataType === 'boolean';
+
+ const placeholder = ctx.selectedCondition === 'inQuery' || ctx.selectedCondition === 'notInQuery'
+ ? 'Sub-query results'
+ : 'Value';
+
+ const currentImplicitValue = ctx && ctx.implicit ? ctx.implicit.value : null;
+ const currentValue = typeof currentImplicitValue === 'object' && currentImplicitValue && 'text' in currentImplicitValue
+ ? equalityCondition ? currentImplicitValue.text : ''
+ : currentImplicitValue;
+
+ const disabledConditions = ['empty', 'notEmpty', 'null', 'notNull', 'inQuery', 'notInQuery'];
+ const isDisabled = isBoolean || selectedField == null || disabledConditions.includes(ctx.selectedCondition ?? '');
+
+ input.value = currentValue == null ? '' : currentValue;
+ input.placeholder = placeholder;
+ input.disabled = isDisabled;
+ input.type = isNumber ? 'number' : 'text';
+
+ input.addEventListener('input', (event) => {
+ const target = event ? event.target : null;
+ const value = target && 'value' in target ? target.value : '';
+
+ ctx.implicit.value = isNumber
+ ? value === '' ? null : Number(value)
+ : value;
+ });
+
+ return input;
+}
+
+function renderExpressionTree(expressionTree) {
+ const expressionOutput = document.getElementById('expressionOutput');
+ if (!expressionOutput) {
+ return;
+ }
+
+ expressionOutput.textContent = expressionTree
+ ? JSON.stringify(expressionTree, null, 2)
+ : '';
+}
+
+function renderInitialExpressionTree(attempts = 60) {
+ const queryBuilder = document.querySelector('igc-query-builder');
+ const expressionTree = queryBuilder?.expressionTree;
+
+ if (expressionTree || attempts <= 0) {
+ renderExpressionTree(expressionTree);
+ return;
+ }
+
+ requestAnimationFrame(() => renderInitialExpressionTree(attempts - 1));
+}
+
+window.queryBuilderTemplate = {
+ init: (regions, statuses) => {
+ regionOptions = regions ?? [];
+ statusOptions = statuses ?? [];
+ renderInitialExpressionTree();
+ },
+ renderExpressionTree,
+};
+
+igRegisterScript('SearchValueTemplate', (ctx) => {
+ const field = ctx && ctx.selectedField ? ctx.selectedField.field : null;
+ const equalityCondition = matchesEqualityCondition(ctx ? ctx.selectedCondition : null);
+
+ ensureImplicit(ctx);
+
+ if (field === 'Region' && equalityCondition) {
+ return buildRegionSelect(ctx);
+ }
+
+ if (field === 'OrderStatus' && equalityCondition) {
+ return buildStatusRadios(ctx);
+ }
+
+ if (field === 'OrderDate') {
+ return buildDatePicker(ctx);
+ }
+
+ if (field === 'RequiredTime') {
+ return buildTimeInput(ctx);
+ }
+
+ return buildDefaultInput(ctx, equalityCondition);
+}, false);
+
+igRegisterScript('WebQueryBuilderExpressionTreeChange', (evtArgs) => {
+ const expressionTree = evtArgs?.detail;
+ renderExpressionTree(expressionTree);
+}, false);
diff --git a/samples/interactions/query-builder/template/wwwroot/index.css b/samples/interactions/query-builder/template/wwwroot/index.css
new file mode 100644
index 0000000000..56fba7521f
--- /dev/null
+++ b/samples/interactions/query-builder/template/wwwroot/index.css
@@ -0,0 +1,43 @@
+:root {
+ --sample-surface: #ffffff;
+ --sample-border: #d4dce6;
+ --sample-shadow: 0 18px 40px rgba(31, 53, 84, 0.08);
+ --sample-code-bg: #f5f7fa;
+}
+
+html,
+body {
+ margin: 0;
+ height: 100%;
+}
+
+body {
+ background:
+ radial-gradient(circle at top right, rgba(12, 166, 120, 0.12), transparent 28%),
+ linear-gradient(180deg, #f7f9fc 0%, #eef3f8 100%);
+}
+
+.output-area {
+ background: var(--sample-surface);
+ border: 1px solid var(--sample-border);
+ border-radius: 18px;
+ box-shadow: var(--sample-shadow);
+ padding: 16px;
+ overflow: auto;
+}
+
+.output-area pre {
+ height: auto;
+ box-sizing: border-box;
+ padding: 16px;
+ border-radius: 12px;
+ background: var(--sample-code-bg);
+ font-size: 13px;
+ line-height: 1.5;
+}
+
+@media (max-width: 960px) {
+ .output-area pre {
+ min-height: 260px;
+ }
+}
diff --git a/samples/interactions/query-builder/template/wwwroot/index.html b/samples/interactions/query-builder/template/wwwroot/index.html
new file mode 100644
index 0000000000..9daa43125e
--- /dev/null
+++ b/samples/interactions/query-builder/template/wwwroot/index.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ Samples | IgniteUI for Blazor | Infragistics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ An unhandled error has occurred.
+
Reload
+
🗙
+
+
+
+
+
+
+
diff --git a/samples/layouts/divider/dashed/README.md b/samples/layouts/divider/dashed/README.md
index 767447bee4..714f580f9d 100644
--- a/samples/layouts/divider/dashed/README.md
+++ b/samples/layouts/divider/dashed/README.md
@@ -3,21 +3,19 @@
This folder contains implementation of Blazor application with example of Dashed feature using [Divider](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
-
-
-
+
-
+
-
+
@@ -30,11 +28,11 @@ This folder contains implementation of Blazor application with example of Dashed
- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
-## Running App in Visual Studio 2019
+## Running App in Visual Studio 2022
-NOTE: VS 2019 has better code highlighting and error detection than VS Code does.
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
-- open **Visual Studio 2019** as an administrator
+- open **Visual Studio 2022** as an administrator
- open the **BlazorClientApp.sln** solution
diff --git a/samples/layouts/divider/middle/README.md b/samples/layouts/divider/middle/README.md
index bdb5125d7d..f8d0332224 100644
--- a/samples/layouts/divider/middle/README.md
+++ b/samples/layouts/divider/middle/README.md
@@ -3,21 +3,19 @@
This folder contains implementation of Blazor application with example of Middle feature using [Divider](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
-
-
-
+
-
+
-
+
@@ -30,11 +28,11 @@ This folder contains implementation of Blazor application with example of Middle
- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
-## Running App in Visual Studio 2019
+## Running App in Visual Studio 2022
-NOTE: VS 2019 has better code highlighting and error detection than VS Code does.
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
-- open **Visual Studio 2019** as an administrator
+- open **Visual Studio 2022** as an administrator
- open the **BlazorClientApp.sln** solution
diff --git a/samples/layouts/divider/select/README.md b/samples/layouts/divider/select/README.md
index 933b3e47e3..164a38fa23 100644
--- a/samples/layouts/divider/select/README.md
+++ b/samples/layouts/divider/select/README.md
@@ -3,21 +3,19 @@
This folder contains implementation of Blazor application with example of Select feature using [Divider](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
-
-
-
+
-
+
-
+
@@ -30,11 +28,11 @@ This folder contains implementation of Blazor application with example of Select
- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
-## Running App in Visual Studio 2019
+## Running App in Visual Studio 2022
-NOTE: VS 2019 has better code highlighting and error detection than VS Code does.
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
-- open **Visual Studio 2019** as an administrator
+- open **Visual Studio 2022** as an administrator
- open the **BlazorClientApp.sln** solution
diff --git a/samples/layouts/divider/vertical/README.md b/samples/layouts/divider/vertical/README.md
index 5399fa9144..681facf993 100644
--- a/samples/layouts/divider/vertical/README.md
+++ b/samples/layouts/divider/vertical/README.md
@@ -3,21 +3,19 @@
This folder contains implementation of Blazor application with example of Vertical feature using [Divider](https://www.infragistics.com/products/ignite-ui-blazor/blazor/components/general-getting-started.html) component.
-
-
-
+
-
+
-
+
@@ -30,11 +28,11 @@ This folder contains implementation of Blazor application with example of Vertic
- instal **.NET SDK** from this [website](https://dotnet.microsoft.com/learn/aspnet/blazor-tutorial/install)
-## Running App in Visual Studio 2019
+## Running App in Visual Studio 2022
-NOTE: VS 2019 has better code highlighting and error detection than VS Code does.
+NOTE: VS 2022 has better code highlighting and error detection than VS Code does.
-- open **Visual Studio 2019** as an administrator
+- open **Visual Studio 2022** as an administrator
- open the **BlazorClientApp.sln** solution
diff --git a/samples/layouts/tabs/styling/README.md b/samples/layouts/tabs/styling/README.md
index b1428c1817..3e7406f0dd 100644
--- a/samples/layouts/tabs/styling/README.md
+++ b/samples/layouts/tabs/styling/README.md
@@ -14,7 +14,7 @@ This folder contains implementation of Blazor application with example of Stylin
-