@@ -24,10 +18,22 @@ The following example demonstrates the different highlighting options that are a
All {Platform} Charts support a variety of highlighting options. `HighlightingMode` can be set to brighten or fade when the mouse is hovering over a series/data item rendered in the plot area. `HighlightingBehavior` can be set to directly over or the nearest data item to trigger the highlighting effect. Highlighting modes and behaviors is supported by the `CategoryChart`, `FinancialChart`, and `XamDataChart` controls and they have the same API for using the highlighting feature.
+The following example demonstrates the `HighlightingMode` {Platform} chart.
+
+`sample="/charts/category-chart/highlighting-mode", height="500", alt="{Platform} Highlighting Mode Example"`
+
+The following example demonstrates the `HighlightingBehavior` {Platform} chart.
+
+`sample="/charts/category-chart/highlighting-behavior", height="500", alt="{Platform} Highlighting Mode Example"`
+
# {Platform} Chart Legend Highlighting
All {Platform} Charts support legend highlighting. `LegendHighlightingMode` can enabled so that when mouse is hovering over a legend marker item then the rendered series will highlight in the plot area. Legend highlighting is supported by the `CategoryChart`, `FinancialChart`, and `XamDataChart` controls and they have the same API for using the highlighting feature.
+The following example demonstrates the legend series highlighting {Platform} chart.
+
+`sample="/charts/category-chart/legend-highlighting", height="500", alt="{Platform} Highlighting Mode Example"`
+
## Highlight Layers
The {ProductName} `CategoryChart` can enable three types of highlighting when hovering over data items.
@@ -38,6 +44,11 @@ The {ProductName} `CategoryChart` can enable three types of highlighting when ho
3. Category Highlighting targets all category axes in the chart. They draw a shape that illuminates the area of the axis closest to the pointer position. This is enabled by setting the `IsCategoryHighlightingEnabled` property to true.
+The following example demonstrates the different highlighting layers that are available on the {Platform} chart.
+
+`sample="/charts/category-chart/column-chart-with-highlighting", height="500", alt="{Platform} Highlighting Example"`
+
+
## Additional Resources
You can find more information about related chart features in these topics:
diff --git a/doc/en/components/general-changelog-dv-blazor.md b/doc/en/components/general-changelog-dv-blazor.md
index 2646f4e36..ea19f4ec9 100644
--- a/doc/en/components/general-changelog-dv-blazor.md
+++ b/doc/en/components/general-changelog-dv-blazor.md
@@ -2,7 +2,7 @@
title: {Platform} What's New | {ProductName} | Infragistics
_description: Learn about new features in the {ProductName}.
_keywords: Changelog, What's New, {ProductName}, Infragistics
-mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend", "Infragistics.Controls.Grid", "Infragistics.Controls.GridSelectionMode", "Infragistics.Controls.DataGridCellEventArgs", "Infragistics.Controls.GridBaseDirective", "MaskInput", "Shape", "RoundShape"]
+mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend", "Infragistics.Controls.Grid", "Infragistics.Controls.GridSelectionMode", "Infragistics.Controls.DataGridCellEventArgs", "Infragistics.Controls.GridBaseDirective", "MaskInput", "Shape", "RoundShape", "XamRadialGauge, XamLinearGauge, XamBulletGraph, XamTreemap", "XamRadialChart"]
sharedComponents: ["Grid", "TreeGrid", "HierarchicalGrid"]
namespace: Infragistics.Controls.Charts
---
@@ -10,27 +10,99 @@ namespace: Infragistics.Controls.Charts
All notable changes for each version of {ProductName} are documented on this page.
+## **{PackageVerChanges-23-2-APR2}**
+
+- `XamBulletGraph`
+ - The Performance bar will now reflect a difference between the value and new `HighlightValue` when the `HighlightValueDisplayMode` is applied to the 'Overlay' setting. The highlight value will show a filtered/subset measured percentage as a filled in color while the remaining bar's appearance will appear faded to the assigned value, illustrating the performance in real-time.
+- `XamLinearGauge`
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamRadialGauge`
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamTreemap`
+ - Now exposes a `HighlightingMode` property that allows you to configure the mouse-over highlighting of the items in the tree map. This property takes two options: `Brighten` where the highlight will apply to the item that you hover the mouse over only, and `FadeOthers` where the highlight of the hovered item will remain the same, but everything else will fade out. This highlight is animated, and can be controlled using the `HighlightingTransitionDuration` property.
+
+## **{PackageVerChanges-23-2-APR}**
+
+- `Bug Fixes`
+
+## **{PackageVerChanges-23-2-MAR}**
+
+### New Components
+
+- [`HierarchicalGrid`](grids/hierarchical-grid/overview.md) component
+- `Textarea` component
+- `ButtonGroup` component
+
+### New Features
+
+- `DockManager`
+ - New `ProximityDock` property. If enabled, docking indicators are not visible and the end user can dock the dragged pane by dragging it close to the target pane edges.
+ - New `ContainedInBoundaries` property. Determines whether the floating panes are kept inside the Dock Manager boundaries. Defaults to `false`.
+ - New `ShowPaneHeaders` property. Determines whether pane headers are only shown on hover or always visible. Defaults to `always`.
+- `Tree`
+ - Added `toggleNodeOnClick` property that determines whether clicking over a node will change its expanded state or not. Defaults to `false`.
+- `Rating`
+ - `allowReset` added. When enabled selecting the same value will reset the component. **Behavioral change** - In previous releases this was the default behavior of the rating component. Make sure to set `allowReset` if you need to keep this behavior in your application.
+- `Select`, `Dropdown`
+ - exposed `selectedItem`, `items` and `groups` getters
+- `XamRadialGauge`
+ - New title/subtitle properties. `TitleText`, `SubtitleText` will appear near the bottom the gauge. In addition, the various title/subtitle font properties were added such as `TitleFontSize`, `TitleFontFamily`, `TitleFontStyle`, `TitleFontWeight` and `TitleExtent`. Finally, the new `TitleDisplaysValue` will allow the value to correspond with the needle's position.
+ - New `OpticalScalingEnabled` and `OpticalScalingSize` properties for the `XamRadialGauge`. This new feature will manage the size at which labels, titles, and subtitles of the gauge have 100% optical scaling. You can read more about this new feature [here](radial-gauge.md#optical-scaling)
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamRadialChart`
+ - New Label Mode
+ The `CategoryAngleAxis` for the now exposes a `LabelMode` property that allows you to further configure the location of the labels. This allows you to toggle between the default mode by selecting the `Center` enum, or use the new mode, `ClosestPoint`, which will bring the labels closer to the circular plot area.
+
+### General
+
+- `Input`, `MaskInput`, `DateTimeInput`, `Rating`
+ - `Readonly` has been renamed to `ReadOnly`
+- `Input`
+ - `Maxlength` has been renamed to `MaxLength`
+ - `Minlength` has been renamed to `MinLength`
+
+### Deprecations
+
+- The `size` property and attribute have been deprecated for all components. Use the `--ig-size` CSS custom property instead. The following example sets the size of the avatar component to small:
+ ```css
+ .avatar {
+ --ig-size: var(--ig-size-small);
+ }
+ ```
+- `DateTimeInput`
+ - `MinValue` and `MaxValue` properties have been deprecated. Please, use `Min` and `Max` instead.
+- `RangeSlider`
+ - `AriaLabelLower` and `AriaLabelUpper` properties have been deprecated. Please, use `ThumbLabelLower` and `ThumbLabelUpper` instead.
+
+### Removed
+
+- Removed our own `dir` attribute which shadowed the default one. This is a non-breaking change.
+- `Slider` - `ariaLabel` shadowed property. This is a non-breaking change.
+- `Checkbox` - `ariaLabelledBy` shadowed attribute. This is a non-breaking change.
+- `Switch` - `ariaLabelledBy` shadowed attribute. This is a non-breaking change.
+- `Radio` - `ariaLabelledBy` shadowed attribute. This is a non-breaking change.
+
## **{PackageVerChanges-23-2-JAN}**
### .NET 8.0 support
* 2023.2 release now support .NET 8. For more information on .NET 8 please refer to [this article on Microsoft's site](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-8) .
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
-* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `DataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
+* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `XamDataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
## **{PackageVerChanges-23-2}**
### {PackageGrids} (Toolbar - Beta)
-* A new tool has been added, as a default tool, to save the chart to an image via the clipboard.
+* Save tool action has been added to save the chart to an image via the clipboard.
* Vertical orientation has been added via the toolbar's `Orientation` property. By default the toolbar is horizontal, now the toolbar can be shown in vertical orientation where the tools will popup to the left/right respectfully.
* Custom SVG icons support was added via the toolbar's `renderImageFromText` method, further enhancing custom tool creation.
### {PackageGrids} (Grid)
-* New Features Added:
- - [State Persistence](grids/grid/state-persistence.md)
+
+* Added New Features - [State Persistence](grids/grid/state-persistence.md)
## **{PackageVerChanges-23-1}**
@@ -38,7 +110,7 @@ All notable changes for each version of {ProductName} are documented on this pag
* [Toolbar](menus/toolbar.md) - Beta. This component is a companion container for UI operations to be used primarily with our charting components. The toolbar will dynamically update with a preset of properties and tools when linked to our `XamDataChart` or `CategoryChart` components, but it also gives you the ability to create custom tools for your project.
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
* [ValueLayer](charts/features/chart-overlays.md#{PlatformLower}-value-layer) - A new series type named the `ValueLayer` is now exposed which can allow you to render an overlay for different focal points of the plotted data such as Maximum, Minimum, and Average. This is applied to the `CategoryChart` and `FinancialChart` by adding to the new `ValueLines` collection.
@@ -96,9 +168,7 @@ All notable changes for each version of {ProductName} are documented on this pag
### {PackageCharts} (Charts)
-Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use.
-
-These new chart improvements include:
+Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use. These new chart improvements include:
* Responsive layouts for horizontal label rotation based on browser / screen size.
* Enhanced rendering for rounded labels on all platforms.
@@ -140,7 +210,7 @@ These new chart improvements include:
* Added the highly-configurable [DataLegend](charts/features/chart-data-legend.md) component, which works much like the `Legend`, but it shows values of series and provides many configuration properties for filtering series rows and values columns, styling and formatting values.
* Added the highly-configurable [DataToolTip](charts/features/chart-data-tooltip.md) which displays values and titles of series as well as legend badges of series in a tooltip. This is now the default tooltip for all chart types.
* Added animation and transition-in support for Stacked Series. Animations can be enabled by setting the `IsTransitionInEnabled` property to true. From there, you can set the `TransitionInDuration` property to determine how long your animation should take to complete and the `TransitionInMode` to determine the type of animation that takes place.
-* Added `AssigningCategoryStyle` event, is now available to all series in `DataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
+* Added `AssigningCategoryStyle` event, is now available to all series in `XamDataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
* New `AllowedPositions` enumeration for CalloutLayer. Used to limit where the callouts are to be placed within the chart. By default, the callouts are intelligently placed in the best place but this used to force for example `TopLeft`, `TopRight`, `BottomLeft` or `BottomRight`.
* New corner radius properties added for Annotation Layers; used to round-out the corners of each of the callouts. Note, a corner radius has now been added by default.
- `CalloutCornerRadius` for CalloutLayer
@@ -154,10 +224,7 @@ These new chart improvements include:
### {PackageGrids} (Data Grid)
-* New Feature Added:
-- [Row Paging](grids/data-grid/row-paging.md)
-
-Pagination is used to split a large set of data into a sequence of pages that have similar content. With pagination, data can be displayed in a set number of rows, letting users “scroll” through their data, without needing a scroll bar. The UI for table pagination usually includes things like the current page, total pages, and clickable Previous and Next arrows/buttons that let users flip through the pages of data.
+Added New Feature - [Row Paging](grids/data-grid/row-paging.md) which is used to split a large set of data into a sequence of pages that have similar content. With pagination, data can be displayed in a set number of rows, letting users “scroll” through their data, without needing a scroll bar. The UI for table pagination usually includes things like the current page, total pages, and clickable Previous and Next arrows/buttons that let users flip through the pages of data.
### {PackageDockManager} (Dock Manager)
@@ -268,7 +335,7 @@ This release introduces a few improvements and simplifications to visual design
#### Charts & Maps
-This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `DataChart`, `CategoryChart`, and `FinancialChart`.
+This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `XamDataChart`, `CategoryChart`, and `FinancialChart`.
* Changed Bar/Column/Waterfall series to have square corners instead of rounded corners
* Changed Scatter High Density series’ colors for heat min property from #8a5bb1 to #000000
diff --git a/doc/en/components/general-changelog-dv-react.md b/doc/en/components/general-changelog-dv-react.md
index 51ac65c9c..e62da127a 100644
--- a/doc/en/components/general-changelog-dv-react.md
+++ b/doc/en/components/general-changelog-dv-react.md
@@ -2,32 +2,96 @@
title: {Platform} What's New | {ProductName} | Infragistics
_description: Learn about new features in the {ProductName}.
_keywords: Changelog, What's New, {ProductName}, Infragistics
-mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend", "Grid", "GridSelectionMode", DataGridCellEventArgs, DataGridSelectionMode, DataSourceSummaryOperand]
+mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend", "Grid", "GridSelectionMode", DataGridCellEventArgs, DataGridSelectionMode, DataSourceSummaryOperand, "XamRadialGauge", "XamRadialChart"]
namespace: Infragistics.Controls.Charts
---
# {ProductName} Changelog
All notable changes for each version of {ProductName} are documented on this page.
+## **{PackageVerChanges-23-2-MAR}**
+
+### {PackageCharts}
+
+- `XamRadialChart`
+ - New Label Mode
+ The `CategoryAngleAxis` for the now exposes a `LabelMode` property that allows you to further configure the location of the labels. This allows you to toggle between the default mode by selecting the `Center` enum, or use the new mode, `ClosestPoint`, which will bring the labels closer to the circular plot area.
+
+### {PackageGrids}
+
+- New [`HierarchicalGrid`](grids/hierarchical-grid/overview.md) component
+
+### {PackageGauges}
+
+- `XamRadialGauge`
+ - New title/subtitle properties. `TitleText`, `SubtitleText` will appear near the bottom the gauge. In addition, the various title/subtitle font properties were added such as `TitleFontSize`, `TitleFontFamily`, `TitleFontStyle`, `TitleFontWeight` and `TitleExtent`. Finally, the new `TitleDisplaysValue` will allow the value to correspond with the needle's position.
+ - New `OpticalScalingEnabled` and `OpticalScalingSize` properties for the `XamRadialGauge`. This new feature will manage the size at which labels, titles, and subtitles of the gauge have 100% optical scaling. You can read more about this new feature [here](radial-gauge.md#optical-scaling)
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamLinearGauge`
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamBulletGraph`
+ - The Performance bar will now reflect a difference between the value and new `HighlightValue` when the `HighlightValueDisplayMode` is applied to the 'Overlay' setting. The highlight value will show a filtered/subset completed measured percentage as a filled in color while the remaining bar's appearance will appear faded to the assigned value, illustrating the performance in real-time.
+
+### {PackageCommon}
+
+- New `Textarea` component
+- New `ButtonGroup` component
+- `DockManager`
+ - New `ProximityDock` property. If enabled, docking indicators are not visible and the end user can dock the dragged pane by dragging it close to the target pane edges.
+ - New `ContainedInBoundaries` property. Determines whether the floating panes are kept inside the Dock Manager boundaries. Defaults to `false`.
+ - New `ShowPaneHeaders` property. Determines whether pane headers are only shown on hover or always visible. Defaults to `always`.
+- `Input`, `MaskInput`, `DateTimeInput`, `Rating`
+ - `Readonly` has been renamed to `ReadOnly`
+- `Input`
+ - `Maxlength` has been renamed to `MaxLength`
+ - `Minlength` has been renamed to `MinLength`
+- `Tree`
+ - Added `toggleNodeOnClick` property that determines whether clicking over a node will change its expanded state or not. Defaults to `false`.
+- `Rating`
+ - `allowReset` added. When enabled selecting the same value will reset the component. **Behavioral change** - In previous releases this was the default behavior of the rating component. Make sure to set `allowReset` if you need to keep this behavior in your application.
+- `Select`, `Dropdown`
+ - exposed `selectedItem`, `items` and `groups` getters
+
+
+#### Deprecations
+
+- The `Form` component has been deprecated. Please, use the native form element instead.
+- The `size` property and attribute have been deprecated for all components. Use the `--ig-size` CSS custom property instead. The following example sets the size of the avatar component to small:
+ ```css
+ .avatar {
+ --ig-size: var(--ig-size-small);
+ }
+ ```
+- `DateTimeInput`
+ - `MinValue` and `MaxValue` properties have been deprecated. Please, use `Min` and `Max` instead.
+- `RangeSlider`
+ - `AriaLabelLower` and `AriaLabelUpper` properties have been deprecated. Please, use `ThumbLabelLower` and `ThumbLabelUpper` instead.
+
+#### Removed
+
+- Removed our own `dir` attribute which shadowed the default one. This is a non-breaking change.
+- `Slider` - `ariaLabel` shadowed property. This is a non-breaking change.
+- `Checkbox` - `ariaLabelledBy` shadowed attribute. This is a non-breaking change.
+- `Switch` - `ariaLabelledBy` shadowed attribute. This is a non-breaking change.
+- `Radio` - `ariaLabelledBy` shadowed attribute. This is a non-breaking change.
+
## **{PackageVerChanges-23-2-JAN}**
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
-* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `DataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
+* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `XamDataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
## **{PackageVerChanges-23-2-DEC}**
### {PackageGrids} (Grid)
-* New Features Added:
- - [State Persistence](grids/grid/state-persistence.md)
-## **{PackageVerChanges-23-2}**
+* Added New Features - [State Persistence](grids/grid/state-persistence.md)
-### New Components
+## **{PackageVerChanges-23-2}**
### {PackageGrids} (Toolbar - Beta)
-* A new tool has been added, as a default tool, to save the chart to an image via the clipboard.
+* Save tool action has been added to save the chart to an image via the clipboard.
* Vertical orientation has been added via the toolbar's `Orientation` property. By default the toolbar is horizontal, now the toolbar can be shown in vertical orientation where the tools will popup to the left/right respectfully.
* Custom SVG icons support was added via the toolbar's `renderImageFromText` method, further enhancing custom tool creation.
@@ -35,7 +99,7 @@ All notable changes for each version of {ProductName} are documented on this pag
### Deprecated Components
-> [DataGrid](grids/data-grid/overview.md) - The DataGrid is deprecated, please refer to [Grid](grids/data-grid.md)
+> [DataGrid](grids/data-grid/overview.md) - The DataGrid is deprecated, please use [Grid](grids/data-grid.md)
## **{PackageVerChanges-23-1}**
@@ -43,7 +107,7 @@ All notable changes for each version of {ProductName} are documented on this pag
* [Toolbar](menus/toolbar.md) - Beta. This component is a companion container for UI operations to be used primarily with our charting components. The toolbar will dynamically update with a preset of properties and tool items when linked to our `XamDataChart` or `CategoryChart` components. You'll be able to create custom tools for your project allowing end users to provide changes, offering an endless amount of customization.
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
* [ValueLayer](charts/features/chart-overlays.md#{PlatformLower}-value-layer) - A new series type named the `ValueLayer` is now exposed which can allow you to render an overlay for different focal points of the plotted data such as Maximum, Minimum, and Average. This is applied to the `CategoryChart` and `FinancialChart` by adding to the new `ValueLines` collection.
@@ -51,9 +115,7 @@ All notable changes for each version of {ProductName} are documented on this pag
## **{PackageVerChanges-22-2}**
-Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use.
-
-These new chart improvements include:
+Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use. These new chart improvements include:
* Responsive layouts for horizontal label rotation based on browser / screen size.
* Enhanced rendering for rounded labels on all platforms.
@@ -94,7 +156,7 @@ These new chart improvements include:
* Added the highly-configurable [DataLegend](charts/features/chart-data-legend.md) component, which works much like the `Legend`, but it shows values of series and provides many configuration properties for filtering series rows and values columns, styling and formatting values.
* Added the highly-configurable [DataToolTip](charts/features/chart-data-tooltip.md) which displays values and titles of series as well as legend badges of series in a tooltip. This is now the default tooltip for all chart types.
* Added animation and transition-in support for Stacked Series. Animations can be enabled by setting the `IsTransitionInEnabled` property to true. From there, you can set the `TransitionInDuration` property to determine how long your animation should take to complete and the `TransitionInMode` to determine the type of animation that takes place.
-* Added `AssigningCategoryStyle` event, is now available to all series in `DataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
+* Added `AssigningCategoryStyle` event, is now available to all series in `XamDataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
* New `AllowedPositions` enumeration for CalloutLayer. Used to limit where the callouts are to be placed within the chart. By default, the callouts are intelligently placed in the best place but this used to force for example `TopLeft`, `TopRight`, `BottomLeft` or `BottomRight`.
* New corner radius properties added for Annotation Layers; used to round-out the corners of each of the callouts. Note, a corner radius has now been added by default.
- `CalloutCornerRadius` for CalloutLayer
@@ -108,10 +170,7 @@ These new chart improvements include:
### {PackageGrids} (Data Grid)
-* New Feature Added:
-- [Row Paging](grids/data-grid/row-paging.md)
-
-Pagination is used to split a large set of data into a sequence of pages that have similar content. With pagination, data can be displayed in a set number of rows, letting users “scroll” through their data, without needing a scroll bar. The UI for table pagination usually includes things like the current page, total pages, and clickable Previous and Next arrows/buttons that let users flip through the pages of data.
+Added New Feature - [Row Paging](grids/data-grid/row-paging.md) which is used to split a large set of data into a sequence of pages that have similar content. With pagination, data can be displayed in a set number of rows, letting users “scroll” through their data, without needing a scroll bar. The UI for table pagination usually includes things like the current page, total pages, and clickable Previous and Next arrows/buttons that let users flip through the pages of data.
## **{PackageVerChanges-21-2.1}**
@@ -195,7 +254,7 @@ This release introduces a few improvements and simplifications to visual design
## **{PackageVerChanges-21-1}**
### {PackageCharts} (Charts)
-This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `DataChart`, `CategoryChart`, and `FinancialChart`.
+This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `XamDataChart`, `CategoryChart`, and `FinancialChart`.
* Changed Bar/Column/Waterfall series to have square corners instead of rounded corners
* Changed Scatter High Density series’ colors for heat min property from #8a5bb1 to #000000
diff --git a/doc/en/components/general-changelog-dv-wc.md b/doc/en/components/general-changelog-dv-wc.md
index 70d51caa6..01cbf1b8c 100644
--- a/doc/en/components/general-changelog-dv-wc.md
+++ b/doc/en/components/general-changelog-dv-wc.md
@@ -2,30 +2,53 @@
title: {Platform} What's New | {ProductName} | Infragistics
_description: Learn about new features in the {ProductName}.
_keywords: Changelog, What's New, {ProductName}, Infragistics
-mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend", "Infragistics.Controls.Grid", "Infragistics.Controls.GridSelectionMode"]
+mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend", "Infragistics.Controls.Grid", "Infragistics.Controls.GridSelectionMode", "XamRadialGauge", "XamRadialChart"]
namespace: Infragistics.Controls.Charts
---
# {ProductName} Changelog
All notable changes for each version of {ProductName} are documented on this page.
+## **{PackageVerChanges-23-2-MAR}**
+
+### {PackageCharts}
+
+- `XamRadialChart`
+ - New Label Mode
+ The `CategoryAngleAxis` for the now exposes a `LabelMode` property that allows you to further configure the location of the labels. This allows you to toggle between the default mode by selecting the `Center` enum, or use the new mode, `ClosestPoint`, which will bring the labels closer to the circular plot area.
+
+### {PackageGauges}
+
+- `XamRadialGauge`
+ - New title/subtitle properties. `TitleText`, `SubtitleText` will appear near the bottom the gauge. In addition, the various title/subtitle font properties were added such as `TitleFontSize`, `TitleFontFamily`, `TitleFontStyle`, `TitleFontWeight` and `TitleExtent`. Finally, the new `TitleDisplaysValue` will allow the value to correspond with the needle's position.
+ - New `OpticalScalingEnabled` and `OpticalScalingSize` properties for the `XamRadialGauge`. This new feature will manage the size at which labels, titles, and subtitles of the gauge have 100% optical scaling. You can read more about this new feature [here](radial-gauge.md#optical-scaling)
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamLinearGauge`
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamBulletGraph`
+ - The Performance bar will now reflect a difference between the value and new `HighlightValue` when the `HighlightValueDisplayMode` is applied to the 'Overlay' setting. The highlight value will show a filtered/subset completed measured percentage as a filled in color while the remaining bar's appearance will appear faded to the assigned value, illustrating the performance in real-time.
+
+### {PackageGrids}
+
+- New [`HierarchicalGrid`](grids/hierarchical-grid/overview.md) component
+
## **{PackageVerChanges-23-2-JAN}**
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
-* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `DataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
+* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `XamDataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
## **{PackageVerChanges-23-2-DEC}**
### {PackageGrids} (Grid)
-* New Features Added:
- - [State Persistence](grids/grid/state-persistence.md)
+
+* Added New Features - [State Persistence](grids/grid/state-persistence.md)
## **{PackageVerChanges-23-2}**
### {PackageGrids} (Toolbar - Beta)
-* A new tool has been added, as a default tool, to save the chart to an image via the clipboard.
+* Save tool action has been added to save the chart to an image via the clipboard.
* Vertical orientation has been added via the toolbar's `Orientation` property. By default the toolbar is horizontal, now the toolbar can be shown in vertical orientation where the tools will popup to the left/right respectfully.
* Custom SVG icons support was added via the toolbar's `renderImageFromText` method, further enhancing custom tool creation.
@@ -35,7 +58,7 @@ All notable changes for each version of {ProductName} are documented on this pag
* [Toolbar](menus/toolbar.md) - Beta. This component is a companion container for UI operations to be used primarily with our charting components. The toolbar will dynamically update with a preset of properties and tool items when linked to our `XamDataChart` or `CategoryChart` components. You'll be able to create custom tools for your project allowing end users to provide changes, offering an endless amount of customization.
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
* [ValueLayer](charts/features/chart-overlays.md#{PlatformLower}-value-layer) - A new series type named the `ValueLayer` is now exposed which can allow you to render an overlay for different focal points of the plotted data such as Maximum, Minimum, and Average. This is applied to the `CategoryChart` and `FinancialChart` by adding to the new `ValueLines` collection.
@@ -93,9 +116,7 @@ All notable changes for each version of {ProductName} are documented on this pag
### {PackageCharts}
-Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use.
-
-These new chart improvements include:
+Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use. These new chart improvements include:
* Responsive layouts for horizontal label rotation based on browser / screen size.
* Enhanced rendering for rounded labels on all platforms.
@@ -136,7 +157,7 @@ These new chart improvements include:
* Added the highly-configurable [DataLegend](charts/features/chart-data-legend.md) component, which works much like the `Legend`, but it shows values of series and provides many configuration properties for filtering series rows and values columns, styling and formatting values.
* Added the highly-configurable [DataToolTip](charts/features/chart-data-tooltip.md) which displays values and titles of series as well as legend badges of series in a tooltip. This is now the default tooltip for all chart types.
* Added animation and transition-in support for Stacked Series. Animations can be enabled by setting the `IsTransitionInEnabled` property to true. From there, you can set the `TransitionInDuration` property to determine how long your animation should take to complete and the `TransitionInMode` to determine the type of animation that takes place.
-* Added `AssigningCategoryStyle` event, is now available to all series in `DataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
+* Added `AssigningCategoryStyle` event, is now available to all series in `XamDataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
* New `AllowedPositions` enumeration for CalloutLayer. Used to limit where the callouts are to be placed within the chart. By default, the callouts are intelligently placed in the best place but this used to force for example `TopLeft`, `TopRight`, `BottomLeft` or `BottomRight`.
* New corner radius properties added for Annotation Layers; used to round-out the corners of each of the callouts. Note, a corner radius has now been added by default.
- `CalloutCornerRadius` for CalloutLayer
@@ -150,10 +171,7 @@ These new chart improvements include:
### {PackageGrids} (Data Grid)
-* New Feature Added:
-- [Row Paging](grids/data-grid/row-paging.md)
-
-Pagination is used to split a large set of data into a sequence of pages that have similar content. With pagination, data can be displayed in a set number of rows, letting users “scroll” through their data, without needing a scroll bar. The UI for table pagination usually includes things like the current page, total pages, and clickable Previous and Next arrows/buttons that let users flip through the pages of data.
+Added New Feature - [Row Paging](grids/data-grid/row-paging.md) which is used to split a large set of data into a sequence of pages that have similar content. With pagination, data can be displayed in a set number of rows, letting users “scroll” through their data, without needing a scroll bar. The UI for table pagination usually includes things like the current page, total pages, and clickable Previous and Next arrows/buttons that let users flip through the pages of data.
### New Components
@@ -300,7 +318,7 @@ This release introduces a few improvements and simplifications to visual design
## **{PackageVerChanges-21-1}**
### {PackageCharts} (Charts)
-This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `DataChart`, `CategoryChart`, and `FinancialChart`.
+This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `XamDataChart`, `CategoryChart`, and `FinancialChart`.
* Changed Bar/Column/Waterfall series to have square corners instead of rounded corners
* Changed Scatter High Density series’ colors for heat min property from #8a5bb1 to #000000
diff --git a/doc/en/components/general-changelog-dv.md b/doc/en/components/general-changelog-dv.md
index bf4dce057..efa8200c1 100644
--- a/doc/en/components/general-changelog-dv.md
+++ b/doc/en/components/general-changelog-dv.md
@@ -2,7 +2,7 @@
title: {Platform} What's New | {ProductName} | Infragistics
_description: Learn about new features in the {ProductName}.
_keywords: Changelog, What's New, {ProductName}, Infragistics
-mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend"]
+mentionedTypes: ["SeriesViewer", "XYChart", "DomainChart", "XamDataChart", "Toolbar", "XamGeographicMap", "DatePicker", "MultiColumnComboBox", "CategoryChart", "CrosshairLayer", "FinalValueLayer", "CalloutLayer", "DataLegend", "XamRadialGauge", "XamRadialChart"]
namespace: Infragistics.Controls.Charts
---
# {ProductName} Changelog
@@ -15,17 +15,36 @@ All notable changes for each version of {ProductName} are documented on this pag
* [Ignite UI for Angular Changelog at Github](https://github.com/IgniteUI/igniteui-angular/blob/master/CHANGELOG.md)
+## **{PackageVerChanges-23-2-MAR}**
+
+### {PackageCharts}
+
+- `XamRadialChart`
+ - New Label Mode
+ The `CategoryAngleAxis` for the now exposes a `LabelMode` property that allows you to further configure the location of the labels. This allows you to toggle between the default mode by selecting the `Center` enum, or use the new mode, `ClosestPoint`, which will bring the labels closer to the circular plot area.
+
+### {PackageGauges}
+
+- `XamRadialGauge`
+ - New title/subtitle properties. `TitleText`, `SubtitleText` will appear near the bottom the gauge. In addition, the various title/subtitle font properties were added such as `TitleFontSize`, `TitleFontFamily`, `TitleFontStyle`, `TitleFontWeight` and `TitleExtent`. Finally, the new `TitleDisplaysValue` will allow the value to correspond with the needle's position.
+ - New `OpticalScalingEnabled` and `OpticalScalingSize` properties for the `XamRadialGauge`. This new feature will manage the size at which labels, titles, and subtitles of the gauge have 100% optical scaling. You can read more about this new feature [here](radial-gauge.md#optical-scaling)
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamLinearGauge`
+ - New highlight needle was added. `HighlightValue` and `HighlightValueDisplayMode` when both are provided a value and 'Overlay' setting, this will make the main needle to appear faded and a new needle will appear.
+- `XamBulletGraph`
+ - The Performance bar will now reflect a difference between the value and new `HighlightValue` when the `HighlightValueDisplayMode` is applied to the 'Overlay' setting. The highlight value will show a filtered/subset completed measured percentage as a filled in color while the remaining bar's appearance will appear faded to the assigned value, illustrating the performance in real-time.
+
## **{PackageVerChanges-23-2-JAN}**
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
-* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `DataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
+* [Chart Highlight Filter](charts/features/chart-highlight-filter.md) - The `CategoryChart` and `XamDataChart` now expose a way to highlight and animate in and out of a subset of data. The display of this highlight depends on the series type. For column and area series, the subset will be shown on top of the total set of data where the subset will be colored by the actual brush of the series, and the total set will have a reduced opacity. For line series, the subset will be shown as a dotted line.
## **{PackageVerChanges-23-2}**
### {PackageGrids} (Toolbar - Beta)
-* A new tool has been added, as a default tool, to save the chart to an image via the clipboard.
+* Save tool action has been added to save the chart to an image via the clipboard.
* Vertical orientation has been added via the toolbar's `Orientation` property. By default the toolbar is horizontal, now the toolbar can be shown in vertical orientation where the tools will popup to the left/right respectfully.
* Custom SVG icons support was added via the toolbar's `renderImageFromText` method, further enhancing custom tool creation.
@@ -35,7 +54,7 @@ All notable changes for each version of {ProductName} are documented on this pag
* [Toolbar](menus/toolbar.md) - Beta. This component is a companion container for UI operations to be used primarily with our charting components. The toolbar will dynamically update with a preset of properties and tool items when linked to our `XamDataChart` or `CategoryChart` components. You'll be able to create custom tools for your project allowing end users to provide changes, offering an endless amount of customization.
-### {PackageCharts} Charts
+### {PackageCharts} (Charts)
* [ValueLayer](charts/features/chart-overlays.md#{PlatformLower}-value-layer) - A new series type named the `ValueLayer` is now exposed which can allow you to render an overlay for different focal points of the plotted data such as Maximum, Minimum, and Average. This is applied to the `CategoryChart` and `FinancialChart` by adding to the new `ValueLines` collection.
@@ -49,9 +68,7 @@ All notable changes for each version of {ProductName} are documented on this pag
## **{PackageVerChanges-22-2}**
-Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use.
-
-These new chart improvements include:
+Added significant improvements to default behaviors, and refined the Category Chart API to make it easier to use. These new chart improvements include:
* Responsive layouts for horizontal label rotation based on browser / screen size.
* Enhanced rendering for rounded labels on all platforms.
@@ -85,7 +102,7 @@ The Chart's [Aggregation](charts/features/chart-data-aggregations.md) will not w
* Added the highly-configurable [DataLegend](charts/features/chart-data-legend.md) component, which works much like the `Legend`, but it shows values of series and provides many configuration properties for filtering series rows and values columns, styling and formatting values.
* Added the highly-configurable [DataToolTip](charts/features/chart-data-tooltip.md) which displays values and titles of series as well as legend badges of series in a tooltip. This is now the default tooltip for all chart types.
* Added animation and transition-in support for Stacked Series. Animations can be enabled by setting the `IsTransitionInEnabled` property to true. From there, you can set the `TransitionInDuration` property to determine how long your animation should take to complete and the `TransitionInMode` to determine the type of animation that takes place.
-* Added `AssigningCategoryStyle` event, is now available to all series in `DataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
+* Added `AssigningCategoryStyle` event, is now available to all series in `XamDataChart`. This event is handled when you want to conditionally configure aspects of the series items such as `Fill` background-color and highlighting.
* New `AllowedPositions` enumeration for CalloutLayer. Used to limit where the callouts are to be placed within the chart. By default, the callouts are intelligently placed in the best place but this used to force for example `TopLeft`, `TopRight`, `BottomLeft` or `BottomRight`.
* New corner radius properties added for Annotation Layers; used to round-out the corners of each of the callouts. Note, a corner radius has now been added by default.
- `CalloutCornerRadius` for CalloutLayer
@@ -142,7 +159,7 @@ This release introduces a few improvements and simplifications to visual design
## **{PackageVerChanges-21-1}**
### {PackageCharts} (Charts)
-This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `DataChart`, `CategoryChart`, and `FinancialChart`.
+This release introduces several new and improved visual design and configuration options for all of the chart components, e.g. `XamDataChart`, `CategoryChart`, and `FinancialChart`.
* Changed Bar/Column/Waterfall series to have square corners instead of rounded corners
* Changed Scatter High Density series’ colors for heat min property from #8a5bb1 to #000000
diff --git a/doc/en/components/general-getting-started.md b/doc/en/components/general-getting-started.md
index ddb1fa1b3..cdfaf0c35 100644
--- a/doc/en/components/general-getting-started.md
+++ b/doc/en/components/general-getting-started.md
@@ -43,16 +43,16 @@ With above prerequisites installed, we can create a new React application.
2 - Type one of these commands in terminal window:
```cmd
-npx create-react-app my-app-name --typescript
+npx create-react-app MyAppName --typescript
```
```cmd
-yarn create react-app my-app-name --typescript
+yarn create react-app MyAppName --typescript
```
Depending on the approach `npx` or `yarn` will be required. Refer to this website for more information on above commands.
```cmd
-cd my-app-name
+cd MyAppName
```
@@ -63,37 +63,24 @@ cd my-app-name
{ProductName} is a complete set of UI widgets, components, UI kits for design tools and supporting services for Web Components. Designed to enable developers to build the most modern, high-performance HTML5 & JavaScript apps for modern desktop browsers, mobile experiences and progressive web apps (PWA’s) targeting the browsers web components APIs.
## Charts & Graphs
-{ProductName} Charts & Graphs is a library that lets you visualize any type of data through its 65+ types of series and combinations into stunning and interactive charts and dashboards. Built for speed and beauty, designed to work on every modern browser and with complete touch and interactivity, you can quickly build responsive visuals on any device.
+{ProductName} contains a library of [Charts & Graphs](charts/chart-overview.md) that lets you visualize any type of data through its 65+ types of chart series and combinations into stunning and interactive charts and dashboards. Built for speed and beauty, designed to work on every modern browser and with complete touch and interactivity, you can quickly build responsive visuals on any device.
## Gauges
-{ProductName} Gauges provides a radial and a linear gauge components used to illustrate data in an easy and intuitive way.
-The radial gauge has a variety of customization options in order to create a predefined shape and scale.
-The linear gauge provides a simple view of a value compared against a scale and one or more ranges. It supports one scale, one set of tick marks and one set of labels.
-
-{ProductName} Gauges also includes a `XamBulletGraph` component that lets you create data visualizations, replacing meters and gauges that are used on dashboards with simple bar charts.
+{ProductName} provides [Radial Gauge](radial-gauge.md), [Linear Gauge](linear-gauge.md), and [Bullet Graph](bullet-graph.md) components used to illustrate data in an easy and intuitive way. The [Radial Gauge](radial-gauge.md) has a variety of customization options in order to create a predefined shape and scale. The [Linear Gauge](linear-gauge.md) provides a simple view of a value compared against a scale and one or more ranges. It supports one scale, one set of tick marks and one set of labels. The [Bullet Graph](bullet-graph.md) component that lets you create data visualizations, replacing meters and gauges that are used on dashboards with simple bar charts.
## Maps
-{ProductName} Maps brings the ability to visualize geographic data in your application. It can render data sets consisting of many geographic locations in shapes of markers, lines, polygons, or even interactive bitmaps. It allows you to overlay multiple map layers with geographic data, mark specific geographic locations and display information using custom markers and colors.
+{ProductName} [Geographic Maps](geo-map.md) brings the ability to visualize geographic data in your application. It can render data sets consisting of many geographic locations in shapes of markers, lines, polygons, or even interactive bitmaps. It allows you to overlay multiple map layers with geographic data, mark specific geographic locations and display information using custom markers and colors.
## Grids & Inputs
-{ProductName} Grid is a grid component that allows you to bind and display data with little configuration. It also provides features such as filtering, sorting, grouping, pinning and more.
-
-## IgniteUI Web Components
-{ProductName} is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach. See the [Storybook Here](https://igniteui.github.io/igniteui-webcomponents)!
-
-All components are based on the [Indigo.Design Design System](https://www.infragistics.com/products/appbuilder/ui-toolkit), are fully supported by [App Builder](https://appbuilder.indigo.design/) and are backed by ready-to-use UI kits for Sketch, Adobe XD and Figma.
+{ProductName} provides several [Grids](grids/grids-header.md) components that allows you to bind and display data with little configuration in form of [Data Grid](grids/data-grid.md), [List](grids/list.md), [Tree](grids/tree.md), and even [Spreadsheet](spreadsheet-overview.md). It also provides features such as filtering, sorting, grouping, pinning and more.
+
+## Buttons, Inputs, Layouts & Menus
+{ProductName} provides various types of [Buttons](inputs/button.md), [Inputs](inputs/input.md), [Menus](menus/navbar.md), and [Layouts](layouts/tabs.md) that give you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach. See the [Storybook Here](https://igniteui.github.io/igniteui-webcomponents). These components are based on the [Indigo Design System](https://www.infragistics.com/products/appbuilder/ui-toolkit), are fully supported by [App Builder](https://appbuilder.indigo.design/) and are backed by ready-to-use UI kits for Sketch, Adobe XD and Figma.
# Getting Started With {ProductName}
-This topic provides step-by-step instructions for creating Web Components application with Ignite UI for Web Components.
-
-## Ignite UI Web Components Example
-
-`sample="/maps/geo-map/display-osm-imagery", height="750", alt="{Platform} Overview Example"`
-
-
+This section provides step-by-step instructions for creating Web Components application with Ignite UI for Web Components.
-# Configuration
## Install IgniteUI CLI
@@ -166,8 +153,9 @@ After the components are imported you can use them in your html:
```
-# Install Charts and Map Web Component packages
-## Step 1 - Create the Web Component Project
+## Install Charts and Map Packages
+
+### Step 1 - Create the Web Component Project
1 - Open a command line and create a directory named **wc-html**
```cmd
@@ -233,7 +221,7 @@ code .
},
```
-## Step 2 - Install Polyfills
+### Step 2 - Install Polyfills
1 - Open a terminal in **VS Code** (**View** -> **Terminal** menu or press CTRL + ` keys)
@@ -249,7 +237,7 @@ import '@webcomponents/custom-elements/custom-elements.min';
import '@webcomponents/custom-elements/src/native-shim.js';
```
-## Step 3 - Install Ignite UI for Web Components and lit-html
+### Step 3 - Install Ignite UI for Web Components and lit-html
1 - Install the Ignite UI for Web Component using **npm**. In this example, we will install the Map web component:
@@ -287,7 +275,7 @@ ModuleManager.register(
```
-## Step 4 - Build and Run the Web Component Project
+### Step 4 - Build and Run the Web Component Project
1 - Open a terminal in **VS Code** and execute the **build** script
@@ -316,9 +304,13 @@ npm run build
> [!Note]
> Live Server is an extension to Visual Studio Code that allows you to launch a local development server with live reload feature for static & dynamic pages. This extension can be installed via the Visual Studio Code Extensions tab, or by downloading it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer).
-4 - Navigate to the **index.html** using a web browser on your local server, and the Ignite UI for Web Components map should now be rendered with shape of the world.
+4 - Navigate to the **index.html** using a web browser on your local server. The final result should show interactive map of the world:
+
+
+
+`sample="/maps/geo-map/display-osm-imagery", height="750", alt="{Platform} Overview Example"`
+
-
@@ -418,11 +410,12 @@ Finally, we can run our new application by using one of the following commands:
npm run-script start
```
-After executing this command, your project will be built and served locally on your computer. It will automatically open in your default browser and you will be able to use {ProductName} components in your project.
+After executing this command, your project will be built and served locally on your computer. It will automatically open in your default browser and you will be able to use {ProductName} components in your project. The final result should show interactive map of the world:
+
+
-The final result should look something like this screenshot:
+`sample="/maps/geo-map/display-osm-imagery", height="750", alt="{Platform} Overview Example"`
-
@@ -477,7 +470,7 @@ var app = builder.Build();
@using IgniteUI.Blazor.Controls
```
-3 - Add the Style Sheet in the **
** element of the **Pages/_Layout.cshtml** file:
+3a - Add the Style Sheet in the **
** element of the **Pages/_Layout.cshtml** or **Pages/_Host.cshtml** file:
```razor
@@ -485,7 +478,7 @@ var app = builder.Build();
```
-4 - Add Script Reference to the **Pages/_Host.cshtml** file:
+3b - Add Script References:
```razor
@@ -510,7 +503,7 @@ public void ConfigureServices(IServiceCollection services)
@using IgniteUI.Blazor.Controls
```
-3 - Add the Style Sheet in the **
** element of the **Pages/_Host.cshtml** file:
+3a - Add the Style Sheet in the **
** element of the **Pages/_Host.cshtml** file:
```razor
@@ -518,7 +511,7 @@ public void ConfigureServices(IServiceCollection services)
```
-4 - Add Script Reference to the **Pages/_Host.cshtml** file:
+3b - Add Script Reference to the **Pages/_Host.cshtml** file:
```razor
diff --git a/doc/en/components/geo-map-display-heat-imagery.md b/doc/en/components/geo-map-display-heat-imagery.md
index a4c3105f3..22c626b44 100644
--- a/doc/en/components/geo-map-display-heat-imagery.md
+++ b/doc/en/components/geo-map-display-heat-imagery.md
@@ -2,11 +2,11 @@
title: {Platform} Map | Data Visualization Tools | Infragistics
_description: Use Infragistics' {Platform} JavaScript map to display heat map imagery. Check out {ProductName} map demos!
_keywords: {Platform} map, heat map imagery, {ProductName}, Infragistics
-mentionedTypes: ['XamGeographicMap', 'ShapefileConverter']
+mentionedTypes: ['XamGeographicMap', 'ShapefileConverter', 'HeatTileGenerator', 'GeographicTileSeries']
---
# {Platform} Displaying Heat Imagery
-The {ProductName} map control has the ability to show heat-map imagery through the use of the `ShapeFileRecords` that are generated by a `ShapefileConverter` by loading geo-spatial data by loading shape files to a tile series.
+The {ProductName} map control has the ability to show heat-map imagery through the use of the `ShapeFileRecord` that are generated by a `ShapefileConverter` by loading geo-spatial data by loading shape files to a tile series.
It is highly recommended that you review the [Binding Shape Files with Geo-Spatial Data](geo-map-binding-shp-file.md) topic as a pre-requisite to this topic.
@@ -18,7 +18,7 @@ It is highly recommended that you review the [Binding Shape Files with Geo-Spati
-When a `ShapefileConverter` loads its shape files, it converts that data into `ShapeFileRecord` objects. These objects can be retrieved from the `GetPointData()` method of the `ShapefileConverter` and can then be used to create a heat-map through usage of a `TileGeneratorMapImagery` object with a `HeatTileGenerator` assigned to its `TileGenerator` property. This `TileGeneratorMapImagery` can then be used in a geographic tile series as its `TileImagery` source.
+When a `ShapefileConverter` loads its shape files, it converts that data into `ShapefileRecord` objects. These objects can be retrieved from the `GetPointData()` method of the `ShapefileConverter` and can then be used to create a heat-map through usage of a `TileGeneratorMapImagery` object with a `HeatTileGenerator` assigned to its `TileGenerator` property. This `TileGeneratorMapImagery` can then be used in a `GeographicTileSeries` as its `TileImagery` source.
The `HeatTileGenerator` object works such that it has three value paths, `XValues`, `YValues` and `Values`. As an example of how these could be used, in the case of a shape file that has information about population, you could consider the `XValues` to be longitude, `YValues` to be latitude, and `Values` to be the population data. Each of these properties takes a `number[]`.
@@ -343,12 +343,11 @@ public onDataLoaded(csvData: string) {
## API References
- - `HeatTileGenerator`
+ - `GeographicTileSeries`
- `HeatTileGenerator`
- `MaximumColor`
- `MinimumColor`
- - `ShapeFileRecord`
- - `ShapeFileRecords`
+ - `ShapefileRecord`
- `ShapefileConverter`
- `TileGeneratorMapImagery`
- `TileGenerator`
diff --git a/doc/en/components/grids/_shared/advanced-filtering.md b/doc/en/components/grids/_shared/advanced-filtering.md
index 671f1df66..f33291016 100644
--- a/doc/en/components/grids/_shared/advanced-filtering.md
+++ b/doc/en/components/grids/_shared/advanced-filtering.md
@@ -39,68 +39,91 @@ To enable the advanced filtering, the `AllowAdvancedFiltering` input property sh
{ComponentSelector}>
```
+
+
+```html
+
+
+
+```
+```ts
+constructor() {
+ let grid = document.getElementById("grid") as IgcGridComponent;
+ grid.data = this.data
+}
+```
+
+```tsx
+
+
+
+```
+
```razor
<{ComponentSelector} Data=data AutoGenerate="true" AllowAdvancedFiltering="true">
{ComponentSelector}>
```
+
-```razor
-
-
-
-```
-
-
-
```html
-<{ComponentSelector} id="grid" auto-generate="true" allow-advanced-filtering="true">
+
-{ComponentSelector}>
+
```
```ts
constructor() {
- let grid = (document.getElementById("grid") as IgcGridComponent);
- grid.data = this.data
+ let treeGrid = document.getElementById("treeGrid") as IgcTreeGridComponent;
+ treeGrid.data = this.data
}
```
-
-```html
-
-
-
+```tsx
+
+
+
```
+```razor
+
+
+
+```
+
+
+```html
+
+
+
+```
```ts
constructor() {
- let grid = document.getElementById("grid") as IgcTreeGridComponent;
- grid.data = this.data
+ let hierarchicalGrid = document.getElementById("hierarchicalGrid") as IgcHierarchicalGridComponent;
+ hierarchicalGrid.data = this.data
}
```
-
+
-
-
-```html
-<{ComponentSelector} data={this.nwindData} autoGenerate="false" ref={this.gridRef} allowAdvancedFiltering="true">
-
-
-
-
-
-{ComponentSelector}>
+
+
+```razor
+
+
+
```
-
+
+
+
```tsx
-<{ComponentSelector} data={nwindData} autoGenerate="false" ref={gridRef} allowAdvancedFiltering="true">
+
-{ComponentSelector}>
+
```
+
The advanced filtering generates a `FilteringExpressionsTree` which is stored in the `AdvancedFilteringExpressionsTree` input property. You could use the `AdvancedFilteringExpressionsTree` property to set an initial state of the advanced filtering.
@@ -543,27 +566,22 @@ Don't forget to include the themes in the same way as it was demonstrated above.
In addition to the predefined themes, the grid could be further customized by setting some of the available [CSS properties](../theming.md).
In case you would like to change some of the colors, you need to set a class for the grid first:
+
```html
-
-```
-
-```razor
-
+<{ComponentSelector} class="grid">{ComponentSelector}>
```
+
-
-
-
-```html
-
+
+```tsx
+<{ComponentSelector} className="grid">{ComponentSelector}>
```
+
```razor
-
+<{ComponentSelector} class="grid">{ComponentSelector}>
```
-
-
Then set the related CSS properties to this class:
```css
diff --git a/doc/en/components/grids/_shared/cell-editing.md b/doc/en/components/grids/_shared/cell-editing.md
index e9fbe6b23..5e16e8c52 100644
--- a/doc/en/components/grids/_shared/cell-editing.md
+++ b/doc/en/components/grids/_shared/cell-editing.md
@@ -84,7 +84,9 @@ public updateCell() {
```
```razor
-this.treeGrid.UpdateCell(newValue, rowID, 'ReorderLevel')
+@code {
+ this.treeGrid.UpdateCell(newValue, rowID, 'ReorderLevel');
+}
```
@@ -96,7 +98,9 @@ public updateCell() {
```
```razor
-this.hierarchicalGrid.UpdateCell(newValue, rowID, 'ReorderLevel')
+@code {
+ this.hierarchicalGrid.UpdateCell(newValue, rowID, 'ReorderLevel');
+}
```
@@ -116,9 +120,11 @@ public updateCell() {
```razor
-private UpdateCell() {
- IgbCell cell = this.grid1.GetCellByColumn(rowIndex, "ReorderLevel");
- cell.Update(70);
+@code {
+ private UpdateCell() {
+ IgbCell cell = this.grid1.GetCellByColumn(rowIndex, "ReorderLevel");
+ cell.Update(70);
+ }
}
```
@@ -145,9 +151,11 @@ public updateCell() {
```
```razor
-private UpdateCell() {
- IgbCell cell = this.treeGrid.GetCellByColumn(rowIndex, "Age");
- cell.Update(9999);
+@code {
+ private UpdateCell() {
+ IgbCell cell = this.treeGrid.GetCellByColumn(rowIndex, "Age");
+ cell.Update(9999);
+ }
}
```
@@ -163,9 +171,11 @@ public updateCell() {
```
```razor
-private UpdateCell() {
- IgbCell cell = this.hierarchicalGrid.GetCellByColumn(rowIndex, "ReorderLevel");
- cell.Update(70);
+@code {
+ private UpdateCell() {
+ IgbCell cell = this.hierarchicalGrid.GetCellByColumn(rowIndex, "ReorderLevel");
+ cell.Update(70);
+ }
}
```
@@ -232,6 +242,8 @@ This code is used in the sample below which implements an [SelectComponent](../s
If you want to provide a custom template which will be applied to a cell, you can pass such template either to the cell itself, or to its header. First create the column as you usually would:
+
+
@@ -252,7 +264,7 @@ If you want to provide a custom template which will be applied to a cell, you ca
@@ -260,6 +272,19 @@ If you want to provide a custom template which will be applied to a cell, you ca
```
+
+```razor
+
+
+```
+
+
and pass the template:
```razor
@@ -294,7 +319,6 @@ igRegisterScript("WebGridCellEditCellTemplate", (ctx) => {
field="Race"
data-type="string"
editable="true"
- name="column1"
id="column1">
```
@@ -342,73 +366,88 @@ public webGridCellEditCellTemplate = (ctx: IgcCellTemplateContext) => {
field="Category"
data-type="string"
editable="true"
- name="column1"
id="column1">
```
and pass the templates to this column in the index.ts file:
-```typescript
+```ts
+
constructor() {
- var treeGrid = document.getElementById('treeGrid') as {ComponentName}Component;
+ var treeGrid = document.getElementById('treeGrid') as IgcTreeGridComponent;
var column1 = document.getElementById('column1') as IgcColumnComponent;
- treeGrid.data = this.ordersTreeData;
- column1.inlineEditorTemplate = this.webTreeGridCellEditCellTemplate;
+ treeGrid.data = this.webGridCellEditSampleRoleplay;
+ column1.inlineEditorTemplate = this.webGridCellEditCellTemplate;
+ column2.inlineEditorTemplate = this.webGridCellEditCellTemplate;
+ column3.inlineEditorTemplate = this.webGridCellEditCellTemplate;
}
+public webGridCellEditCellTemplate = (ctx: IgcCellTemplateContext) => {
+ let cellValues: any = [];
+ let uniqueValues: any = [];
+ for(const i of (this.webGridCellEditSampleRoleplay as any)){
+ const field: string = ctx.cell.column.field;
+ if(uniqueValues.indexOf(i[field]) === -1 )
+ {
+ cellValues.push(html`${(i[field])}`);
+ uniqueValues.push(i[field]);
+ }
+ }
+ return html`
+ ctx.cell.editValue = e.detail.value}>
+ ${cellValues}
+
+ `;
+}
```
+
+
+
+```html
+
+
+```
+
+and pass the templates to this column in the index.ts file:
-
```ts
constructor() {
- var treeGrid = document.getElementById('treeGrid') as IgcTreeGridComponent;
- var column1 = document.getElementById('column1') as IgcColumnComponent;
- var column2 = document.getElementById('column2') as IgcColumnComponent;
- var column3 = document.getElementById('column3') as IgcColumnComponent;
-
- treeGrid.data = this.webGridCellEditSampleRoleplay;
- column1.inlineEditorTemplate = this.webGridCellEditCellTemplate;
- column2.inlineEditorTemplate = this.webGridCellEditCellTemplate;
- column3.inlineEditorTemplate = this.webGridCellEditCellTemplate;
-}
-
-private _webGridCellEditSampleRoleplay: WebGridCellEditSampleRoleplay = null;
-public get webGridCellEditSampleRoleplay(): WebGridCellEditSampleRoleplay {
- if (this._webGridCellEditSampleRoleplay == null)
- {
- this._webGridCellEditSampleRoleplay = new WebGridCellEditSampleRoleplay();
- }
+ var hierarchicalGrid = document.getElementById('hierarchicalGrid') as IgcHierarchicalGridComponent;
+ var column1 = document.getElementById('column1') as IgcColumnComponent;
- return this._webGridCellEditSampleRoleplay;
+ hierarchicalGrid.data = this.singersData;
+ column1.inlineEditorTemplate = this.webGridCellEditCellTemplate;
}
public webGridCellEditCellTemplate = (ctx: IgcCellTemplateContext) => {
- let cellValues: any = [];
- let uniqueValues: any = [];
- for(const i of (this.webGridCellEditSampleRoleplay as any)){
- const field: string = ctx.cell.column.field;
- if(uniqueValues.indexOf(i[field]) === -1 )
- {
- cellValues.push(html`${(i[field])}`);
- uniqueValues.push(i[field]);
- }
+ let cellValues: any = [];
+ let uniqueValues: any = [];
+ for(const i of (this.singersData as any)){
+ const field: string = ctx.cell.column.field;
+ if(uniqueValues.indexOf(i[field]) === -1 )
+ {
+ cellValues.push(html`${(i[field])}`);
+ uniqueValues.push(i[field]);
}
- return html`
- ctx.cell.editValue = e.detail.value}>
- ${cellValues}
-
- `;
+ }
+ return html`
+ ctx.cell.editValue = e.detail.value}>
+ ${cellValues}
+
+ `;
}
```
-
+
-
-
If you want to provide a custom template which will be applied to a cell, you can pass such template either to the cell itself, or to its header. First create the column as you usually would:
@@ -448,13 +487,9 @@ const webGridCellEditCellTemplate = useCallback((ctx: IgrCellTemplateContext) =>
useEffect(() => {
const column1 = grid1Ref.current.getColumnByName('column1');
- const column2 = grid1Ref.current.getColumnByName('column2');
- const column3 = grid1Ref.current.getColumnByName('column3');
grid1Ref.current.data = webGridCellEditSampleRoleplay;
column1.inlineEditorTemplate = webGridCellEditCellTemplate;
- column2.inlineEditorTemplate = webGridCellEditCellTemplate;
- column3.inlineEditorTemplate = webGridCellEditCellTemplate;
}, [webGridCellEditSampleRoleplay, webGridCellEditCellTemplate]);
@@ -621,9 +656,11 @@ this.grid.addRow(record);
```razor
-//Assuming we have a `GetNewRecord` method returning the new row data.
-const record = this.GetNewRecord();
-this.GridRef.AddRow(record);
+@code {
+ //Assuming we have a `GetNewRecord` method returning the new row data.
+ const record = this.GetNewRecord();
+ this.GridRef.AddRow(record);
+}
```
@@ -661,7 +698,14 @@ public addRow() {
// Adding a new record
// Assuming we have a `getNewRecord` method returning the new row data
const record = this.getNewRecord();
- this.hierarchicalGrid.addRow(record, 1);
+ this.hierarchicalGrid.addRow(record);
+}
+```
+```razor
+@code {
+ //Assuming we have a `GetNewRecord` method returning the new row data.
+ const record = this.GetNewRecord();
+ this.HierarchicalGridRef.AddRow(record);
}
```
@@ -708,18 +752,20 @@ row.update(newData);
```razor
-// Updating the whole row
-this.grid.UpdateRow(newData, this.selectedCell.cellID.rowID);
+@code {
+ // Updating the whole row
+ this.grid.UpdateRow(newData, this.selectedCell.cellID.rowID);
-// Just a particular cell through the Grid API
-this.grid.UpdateCell(newData, this.selectedCell.cellID.rowID, this.selectedCell.column.field);
+ // Just a particular cell through the Grid API
+ this.grid.UpdateCell(newData, this.selectedCell.cellID.rowID, this.selectedCell.column.field);
-// Directly using the cell `update` method
-this.selectedCell.Update(newData);
+ // Directly using the cell `update` method
+ this.selectedCell.Update(newData);
-// Directly using the row `update` method
-const row = this.grid.GetRowByKey(rowID);
-row.Update(newData);
+ // Directly using the row `update` method
+ IgbRowType row = this.grid.GetRowByKey(rowID);
+ row.Update(newData);
+}
```
@@ -740,18 +786,20 @@ row.update(newData);
```
```razor
-// Updating the whole row
-this.treeGrid.UpdateRow(newData, this.selectedCell.cellID.rowID);
+@code {
+ // Updating the whole row
+ this.treeGrid.UpdateRow(newData, this.selectedCell.cellID.rowID);
-// Just a particular cell through the Tree Grid API
-this.treeGrid.UpdateCell(newData, this.selectedCell.cellID.rowID, this.selectedCell.column.field);
+ // Just a particular cell through the Tree Grid API
+ this.treeGrid.UpdateCell(newData, this.selectedCell.cellID.rowID, this.selectedCell.column.field);
-// Directly using the cell `update` method
-this.selectedCell.Update(newData);
+ // Directly using the cell `update` method
+ this.selectedCell.Update(newData);
-// Directly using the row `update` method
-const row = this.treeGrid.GetRowByKey(rowID);
-row.Update(newData);
+ // Directly using the row `update` method
+ IgbRowType row = this.treeGrid.GetRowByKey(rowID);
+ row.Update(newData);
+}
```
@@ -771,6 +819,23 @@ this.selectedCell.update(newData);
const row = this.hierarchicalGrid.getRowByKey(rowID);
row.update(newData);
```
+
+```razor
+@code {
+ // Updating the whole row
+ this.hierarchicalGrid.UpdateRow(newData, this.selectedCell.cellID.rowID);
+
+ // Just a particular cell through the Tree Grid API
+ this.hierarchicalGrid.UpdateCell(newData, this.selectedCell.cellID.rowID, this.selectedCell.column.field);
+
+ // Directly using the cell `update` method
+ this.selectedCell.Update(newData);
+
+ // Directly using the row `update` method
+ IgbRowType row = this.hierarchicalGrid.GetRowByKey(rowID);
+ row.Update(newData);
+}
+```
### Deleting data from the {ComponentTitle}
@@ -795,16 +860,18 @@ row.delete();
grid1Ref.current.deleteRow(selectedCell.cellID.rowID);
// Delete row through row object
const row = grid1Ref.current.getRowByIndex(rowIndex);
-row.delete();
+row.del();
```
```razor
-// Delete row through Grid API
-this.grid.DeleteRow(this.selectedCell.cellID.rowID);
-// Delete row through row object
-const row = this.grid.GetRowByIndex(rowIndex);
-row.Delete();
+@code {
+ // Delete row through Grid API
+ this.grid.DeleteRow(this.selectedCell.cellID.rowID);
+ // Delete row through row object
+ IgbRowType row = this.grid.GetRowByIndex(rowIndex);
+ row.Del();
+}
```
@@ -819,15 +886,18 @@ row.delete();
```
```razor
-// Delete row through Tree Grid API
-this.treeGrid.DeleteRow(this.selectedCell.cellID.rowID);
-// Delete row through row object
-const row = this.treeGrid.GetRowByIndex(rowIndex);
-row.Delete();
+@code {
+ // Delete row through Tree Grid API
+ this.treeGrid.DeleteRow(this.selectedCell.cellID.rowID);
+ // Delete row through row object
+ IgbRowType row = this.treeGrid.GetRowByIndex(rowIndex);
+ row.Del();
+}
```
+
```typescript
// Delete row through Grid API
this.hierarchicalGrid.deleteRow(this.selectedCell.cellID.rowID);
@@ -835,6 +905,27 @@ this.hierarchicalGrid.deleteRow(this.selectedCell.cellID.rowID);
const row = this.hierarchicalGrid.getRowByIndex(rowIndex);
row.delete();
```
+
+
+
+```typescript
+// Delete row through Grid API
+this.hierarchicalGrid.deleteRow(this.selectedCell.cellID.rowID);
+// Delete row through row object
+const row = this.hierarchicalGrid.getRowByIndex(rowIndex);
+row.del();
+```
+
+
+```razor
+@code {
+ // Delete row through Grid API
+ this.hierarchicalGrid.DeleteRow(this.selectedCell.cellID.rowID);
+ // Delete row through row object
+ IgbRowType row = this.hierarchicalGrid.GetRowByIndex(rowIndex);
+ row.Del();
+}
+```
These can be wired to user interactions, not necessarily related to the `{ComponentName}` for example, a button click:
@@ -902,6 +993,7 @@ constructor() {
```ts
constructor() {
var hGrid = document.getElementById('hGrid') as IgcHierarchicalGridComponent;
+ this.webHierarchicalGridCellEdit = this.webHierarchicalGridCellEdit.bind(this);
hGrid.addEventListener("cellEdit", this.webHierarchicalGridCellEdit);
}
```
@@ -1039,31 +1131,68 @@ Here, we are validating two columns. If the user tries to set an invalid value f
```typescript
-export class MyHGridEventsComponent {
- public handleCellEdit(event: IGridEditEventArgs) {
- const today = new Date();
- const column = event.column;
- if (column.field === 'Debut') {
- if (event.newValue > today.getFullYear()) {
- this.toast.message = 'The debut date must be in the past!';
- this.toast.open();
- event.cancel = true;
- }
- } else if (column.field === 'LaunchDate') {
- if (event.newValue > new Date()) {
- this.toast.message = 'The launch date must be in the past!';
- this.toast.open();
- event.cancel = true;
- }
+public webHierarchicalGridCellEdit(event: CustomEvent): void {
+ const today = new Date();
+ const column = event.detail.column;
+ if (column.field === 'Debut') {
+ if (event.detail.newValue > today.getFullYear()) {
+ event.detail.cancel = true;
+ alert('The debut date must be in the past!');
+ }
+ } else if (column.field === 'LaunchDate') {
+ if (event.detail.newValue > today) {
+ event.detail.cancel = true;
+ alert('The launch date must be in the past!');
}
}
}
```
+```razor
+*** In JavaScript ***
+igRegisterScript("HandleCellEdit", (ev) => {
+ const today = new Date();
+ const column = event.detail.column;
+ if (column.field === 'Debut') {
+ if (event.detail.newValue > today.getFullYear()) {
+ event.detail.cancel = true;
+ alert('The debut date must be in the past!');
+ }
+ } else if (column.field === 'LaunchDate') {
+ if (event.detail.newValue > today) {
+ event.detail.cancel = true;
+ alert('The launch date must be in the past!');
+ }
+ }
+}, false);
+```
+
Here, we are validating two columns. If the user tries to change an artist's **Debut** year or an album's **Launch Date**, the grid will not allow any dates that are greater than today.
+
+
+```tsx
+public handleCellEdit(sender: IgrHierarchicalGrid, event: IgrGridEditEventArgs): void {
+ const today = new Date();
+ const column = event.detail.column;
+ if (column.field === 'Debut') {
+ if (event.detail.newValue > today.getFullYear()) {
+ event.detail.cancel = true;
+ alert('The debut date must be in the past!');
+ }
+ } else if (column.field === 'LaunchDate') {
+ if (event.detail.newValue > today) {
+ event.detail.cancel = true;
+ alert('The launch date must be in the past!');
+ }
+ }
+}
+```
+
+
+
The result of the above validation being applied to our `{ComponentName}` can be seen in the below demo:
`sample="/{ComponentSample}/editing-events", height="650", alt="{Platform} {ComponentTitle} Editing Event Example"`
@@ -1107,6 +1236,10 @@ Then set the related CSS properties for that class:
```
+```tsx
+
+```
+
Then set the related CSS properties for that class:
```css
@@ -1117,6 +1250,29 @@ Then set the related CSS properties for that class:
```
+
+```html
+
+```
+
+```razor
+
+```
+
+```tsx
+
+```
+
+Then set the related CSS properties for that class:
+
+```css
+.hierarchicalGrid {
+ --ig-grid-edit-mode-color: orange;
+ --ig-grid-cell-editing-background: lightblue;
+}
+```
+
+
### Styling Example
`sample="/{ComponentSample}/cell-editing-styling", height="650", alt="{Platform} {ComponentTitle} Cell Editing Styling Example"`
diff --git a/doc/en/components/grids/_shared/cell-selection.md b/doc/en/components/grids/_shared/cell-selection.md
index 35ce4c5e4..c9b55c2f6 100644
--- a/doc/en/components/grids/_shared/cell-selection.md
+++ b/doc/en/components/grids/_shared/cell-selection.md
@@ -7,7 +7,7 @@ sharedComponents: ["Grid", "TreeGrid", "HierarchicalGrid"]
namespace: Infragistics.Controls
---
-# {Platform} Cell Selection
+# {Platform} {ComponentTitle} Cell Selection
The {ProductName} Cell Selection in {Platform} {ComponentTitle} enables rich data select capabilities and offers powerful API in the `{ComponentName}` component. The {Platform} {ComponentTitle} supports three selection modes:
@@ -21,7 +21,7 @@ In the `{ComponentName}` you can specify the cell selection mode on grid level.
Let's dive deeper into each of these options.
-## {Platform} Cell Selection Example
+## {Platform} {ComponentTitle} Cell Selection Example
The sample below demonstrates the three types of `{ComponentName}`'s **cell selection** behavior. Use the buttons below to enable each of the available selection modes. A brief description will be provided on each button interaction through a snackbar message box.
@@ -93,7 +93,7 @@ If you want to disable cell selection you can just set `CellSelection` to **none
Below are the methods that you can use in order to select ranges, clear selection or get selected cells data.
-
+
### Select range
@@ -111,7 +111,29 @@ const range = { rowStart: 2, rowEnd: 2, columnStart: 1, columnEnd: 1 };
gridRef.current.selectRange(range);
```
-
+
+
+```razor
+<{ComponentSelector} @ref=grid CellSelection="GridSelectionMode.Multiple" AutoGenerate=true><{ComponentSelector}>
+
+@code {
+ private {ComponentSelector} grid;
+
+ private async void SetSelection()
+ {
+ IgbGridSelectionRange selectionRange = new IgbGridSelectionRange();
+ selectionRange.ColumnStart = 1;
+ selectionRange.ColumnEnd = 1;
+ selectionRange.RowStart = 2;
+ selectionRange.RowEnd = 2;
+
+ this.grid.SelectRange(new IgbGridSelectionRange[] {});
+ }
+}
+```
+
+
+
### Clear cell selection
@@ -144,10 +166,10 @@ gridRef.current.clearCellSelection();
`GetSelectedData` will return array of the selected data in Dictionary format. Examples below:
```razor
-
+<{ComponentSelector} @ref=grid CellSelection="GridSelectionMode.Multiple" AutoGenerate=true><{ComponentSelector}>
@code {
- private IgbGrid grid;
+ private {ComponentSelector} grid;
private async void GetSelectedData()
{
@@ -300,6 +322,35 @@ Then set the related CSS properties for that class:
+
+
+
+```ts
+
+```
+
+
+```tsx
+
+```
+
+```razor
+
+```
+
+Then set the related CSS properties for that class:
+
+```css
+.hGrid {
+ --ig-grid-cell-selected-text-color: #fff;
+ --ig-grid-cell-active-border-color: #f2c43c;
+ --ig-grid-cell-selected-background: #0062a3;
+ --ig-grid-cell-editing-background: #0062a3;
+}
+```
+
+
+
### Demo
`sample="/{ComponentSample}/cell-selection-style", height="620", alt="{Platform} {ComponentTitle} Cell Selection Styling Example"`
@@ -384,7 +435,7 @@ With the custom theme applied, the selected grid cells are highlighted with our
## Additional Resources
-
+
* [Selection](selection.md)
* [Row Selection](row-selection.md)
* [Filtering](filtering.md)
diff --git a/doc/en/components/grids/_shared/collapsible-column-groups.md b/doc/en/components/grids/_shared/collapsible-column-groups.md
index 49dce41e5..7209d1ddc 100644
--- a/doc/en/components/grids/_shared/collapsible-column-groups.md
+++ b/doc/en/components/grids/_shared/collapsible-column-groups.md
@@ -214,12 +214,21 @@ public indTemplate = (ctx: IgcColumnTemplateContext) => {
```
```tsx
- function collapsibleIndicatorTemplate(e: { dataContext: IgrColumnTemplateContext }) {
+
+
+
+
+
+
+
+
+
+function indicatorTemplate(e: { dataContext: IgrColumnTemplateContext }) {
return (
-
+
)
- }
+}
```
diff --git a/doc/en/components/grids/_shared/column-hiding.md b/doc/en/components/grids/_shared/column-hiding.md
index 90fb6256f..932d991a0 100644
--- a/doc/en/components/grids/_shared/column-hiding.md
+++ b/doc/en/components/grids/_shared/column-hiding.md
@@ -25,6 +25,7 @@ The {ProductName} has a built-in column hiding UI, which can be used through the
Let's start by creating our `{ComponentName}` and binding it to our data. We will also enable both filtering and sorting for the columns.
+
```html
@@ -84,6 +85,53 @@ Let's start by creating our `{ComponentName}` and binding it to our data. We wil
```
+
+
+
+```html
+
+
+
+
+
+
+
+```
+
+```html
+
+
+
+
+
+
+
+```
+
+```tsx
+
+
+
+
+
+
+
+```
+
+
+
+
+```razor
+<{ComponentSelector} AutoGenerate="false" Data="SingersData" PrimaryKey="ID" AllowFiltering="true" Name="hierarchicalGrid1" @ref="hierarchicalGrid1">
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
## Toolbar's Column Hiding UI
@@ -91,6 +139,7 @@ The built-in Column Hiding UI is placed inside an `DropDown` in the `{ComponentN
For this purpose all we have to do is set both the `GridToolbarActions` and the `GridToolbarHiding` inside of the `{ComponentName}`. We will also add a title to our toolbar by using the `GridToolbarTitle` and a custom style for our {ComponentTitle}'s wrapper.
+
```html
@@ -130,11 +179,70 @@ For this purpose all we have to do is set both the `GridToolbarActions` and the
```
+
+
+
+
+```html
+
+
+
+
+
+
+
+```
+
+
+
+
+
+```html
+
+
+
+
+
+
+
+```
+
+
+
+
+
+```razor
+<{ComponentSelector} Data="SingersData">
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+
+
+
+```tsx
+
+
+
+
+
+
+
+```
+
+
The `{ComponentName}` provides us with some useful properties when it comes to using the toolbar's column hiding UI.
By using the `Title` property, we will set the title that is displayed inside the dropdown button in the toolbar.
+
```html
@@ -174,6 +282,63 @@ By using the `Title` property, we will set the title that is displayed inside th
```
+
+
+
+
+```html
+
+
+
+
+
+
+
+```
+
+
+
+
+
+```razor
+<{ComponentSelector} Data=SingersData>
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+
+
+
+```html
+
+
+
+
+
+
+
+```
+
+
+
+
+
+```tsx
+
+
+
+
+
+
+
+```
+
+
@@ -331,9 +496,11 @@ Now all we have to do is bind the `Checked` property of both radio buttons respe
```
+
### Disable hiding of a column
We can easily prevent the user from being able to hide columns through the column hiding UI by simply setting their `DisableHiding` property to true.
+
```html
@@ -361,6 +528,53 @@ We can easily prevent the user from being able to hide columns through the colum
{ComponentSelector}>
```
+
+
+
+```html
+
+
+
+
+
+
+
+
+```
+
+```html
+
+
+
+
+
+
+
+
+```
+
+```tsx
+
+
+
+
+
+
+
+
+```
+
+```razor
+<{ComponentSelector}>
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
If all went well, this is how our column hiding UI component should look like:
@@ -518,6 +732,7 @@ Don't forget to include the themes in the same way as it was demonstrated above.
The grid could be further customized by setting some of the available [CSS variables](../theming.md).
In order to achieve that, we will use a class that we will first assign to the grid:
+
```html
<{ComponentSelector} class="grid">{ComponentSelector}>
```
@@ -529,9 +744,25 @@ In order to achieve that, we will use a class that we will first assign to the g
```tsx
<{ComponentSelector} className="grid">{ComponentSelector}>
```
+
+
+
+```html
+<{ComponentSelector} class="hierarchical-grid">{ComponentSelector}>
+```
+
+```razor
+<{ComponentSelector} class="hierarchical-grid">{ComponentSelector}>
+```
+
+```tsx
+<{ComponentSelector} className="hierarchical-grid">{ComponentSelector}>
+```
+
Then set the related CSS variables for the related components. We will apply the styles also only on the `igx-column-actions`, so the rest of the grid is unaffected:
+
```css
.grid igx-column-actions {
/* Main Column Actions styles */
@@ -563,6 +794,41 @@ Then set the related CSS variables for the related components. We will apply the
--ig-button-disabled-foreground: #ffcd0f;
}
```
+
+
+
+```css
+#hierarchicalGrid {
+ /* Main Column Actions styles */
+ --ig-column-actions-background-color: #292826;
+ --ig-column-actions-title-color: #ffcd0f;
+
+ /* Checkbox styles */
+ --ig-checkbox-tick-color: #292826;
+ --ig-checkbox-label-color: #ffcd0f;
+ --ig-checkbox-empty-color: #ffcd0f;
+ --ig-checkbox-fill-color: #ffcd0f;
+
+ /* Input styles */
+ --ig-input-group-idle-text-color: white;
+ --ig-input-group-filled-text-color: #ffcd0f;
+ --ig-input-group-focused-text-color: #ffcd0f;
+ --ig-input-group-focused-border-color: #ffcd0f;
+ --ig-input-group-focused-secondary-color: #ffcd0f;
+
+ /* Buttons styles */
+ --ig-button-foreground: #292826;
+ --ig-button-background: #ffcd0f;
+ --ig-button-hover-background: #404040;
+ --ig-button-hover-foreground: #ffcd0f;
+ --ig-button-focus-background: #ffcd0f;
+ --ig-button-focus-foreground: black;
+ --ig-button-focus-visible-background: #ffcd0f;
+ --ig-button-focus-visible-foreground: black;
+ --ig-button-disabled-foreground: #ffcd0f;
+}
+```
+
### Demo
@@ -580,14 +846,14 @@ Additional components and/or directives with relative APIs that were used:
* `ColumnActionsComponent`
-
+
In this article we learned how to use the built-in column hiding UI in the `{ComponentName}`'s toolbar. The column hiding UI has a few more APIs to explore, which are listed below.
* `ColumnActionsComponent`
Additional components with relative APIs that were used:
-
+
`Column` properties:
* `DisableHiding`
diff --git a/doc/en/components/grids/_shared/column-moving.md b/doc/en/components/grids/_shared/column-moving.md
index ea635f32e..2ef1f02c1 100644
--- a/doc/en/components/grids/_shared/column-moving.md
+++ b/doc/en/components/grids/_shared/column-moving.md
@@ -64,6 +64,7 @@ function headerTemplate(ctx: IgrCellTemplateContext) {
## Overview
**Column moving** feature is enabled on a per-grid level, meaning that the `{ComponentName}` could have either movable or immovable columns. This is done via the `Moving` input of the `{ComponentName}`.
+
```html
@@ -87,6 +88,45 @@ function headerTemplate(ctx: IgrCellTemplateContext) {
```
+
+
+
+
+
+```html
+<{ComponentSelector} [moving]="true">
+ ...
+ <{RowIslandSelector} [moving]="true">{RowIslandSelector}>
+{ComponentSelector}>
+```
+
+
+```razor
+<{ComponentSelector} Moving=true>
+ ...
+ <{RowIslandSelector} Moving=true>{RowIslandSelector}>
+{ComponentSelector}>
+```
+
+
+```html
+<{ComponentSelector} moving="true">
+ ...
+ <{RowIslandSelector} moving="true">{RowIslandSelector}>
+{ComponentSelector}>
+```
+
+
+
+```tsx
+<{ComponentSelector} moving="true">
+ ...
+ <{RowIslandSelector} moving="true">{RowIslandSelector}>
+{ComponentSelector}>
+```
+
+
+
## API
In addition to the drag and drop functionality, the Column Moving feature also provides API methods to allow moving a column/reordering columns programmatically:
@@ -169,6 +209,7 @@ public onColumnMovingEnd(event) {
```
+
```tsx
function onColumnMovingEnd(grid: IgrGridBaseDirective, event: IgrColumnMovingEventArgs) {
if (event.detail.source.field === "Category" && event.detail.target.field === "Change On Year(%)") {
@@ -181,6 +222,8 @@ function onColumnMovingEnd(grid: IgrGridBaseDirective, event: IgrColumnMovingEve
{ComponentSelector}>
```
+
+
```razor
<{ComponentSelector} ShowGroupArea="true" @ref='Grid' Width="100%" Height="100%"
AllowFiltering=true
diff --git a/doc/en/components/grids/_shared/column-resizing.md b/doc/en/components/grids/_shared/column-resizing.md
index bb8fe94bd..7d6da03a5 100644
--- a/doc/en/components/grids/_shared/column-resizing.md
+++ b/doc/en/components/grids/_shared/column-resizing.md
@@ -181,18 +181,21 @@ public onResize(event) {
+
```html
-
-
+{ComponentSelector}>
```
+
+
```html
-
-
+{ComponentSelector}>
```
```ts
@@ -201,18 +204,40 @@ constructor() {
hierarchicalGrid.data = this.data;
hierarchicalGrid.columnResized = this.onResize;
}
-```
-```typescript
public onResize(event) {
this.col = event.column;
this.pWidth = event.prevWidth;
this.nWidth = event.newWidth;
}
```
+
+
+```tsx
+function onResize(grid: IgrGridBaseDirective, event: IgrColumnMovingEventArgs) {
+ IgrColumn col = event.detail.column;
+ string pWidth = event.detail.prevWidth;
+ string nWidth = event.detail.newWidth;
+}
+
+<{ComponentSelector} id="hierarchicalGrid" autoGenerate="false" columnResized={onResize}>
+
+{ComponentSelector}>
+```
```razor
-TO DO!
+<{ComponentSelector} Data=data AutoGenerate=false ColumnResized="onResize">
+
+{ComponentSelector}>
+
+@code {
+ private void onResize(IgbColumnResizeEventArgs args)
+ {
+ IgbColumnType col = args.Detail.Column;
+ string pWidth = args.Detail.PrevWidth;
+ string nWidth = args.Detail.NewWidth;
+ }
+}
```
@@ -250,7 +275,7 @@ This means that the following configuration is possible:
```
```tsx
-
+
@@ -306,7 +331,20 @@ This means that the following configuration is possible:
```
```razor
-TO DO!
+<{ComponentSelector} Data=data ColumnResized="onResize" AutoGenerate=false Height="600px" Width="100%">
+
+
+
+{ComponentSelector}>
+```
+
+```tsx
+<{ComponentSelector} id="hierarchicalGrid" columnResized={onResize} autoGenerate="false"
+ height="600px" width="100%">
+
+
+
+{ComponentSelector}>
```
@@ -326,6 +364,8 @@ When resizing columns with width in percentages, the horizontal amount of the mo
You can also configure the minimum and maximum allowable column widths. This is done via the `MinWidth` and `MaxWidth` inputs of the `Column`. In this case the resize indicator drag operation is restricted to notify the user that the column cannot be resized outside the boundaries defined by `MinWidth` and `MaxWidth`.
+
+
```html
@@ -337,17 +377,43 @@ You can also configure the minimum and maximum allowable column widths. This is
```tsx
+ minWidth="60px" maxWidth="230px">
```
```razor
```
+
+
+
+```html
+
+```
+
+```html
+
+```
+
+```tsx
+
+```
+
+```razor
+
+```
+
+
+
Mixing the minimum and maximum column width value types (pixels or percentages) is allowed. If the values set for minimum and maximum are set to percentages, the respective column size will be limited to those exact sizes similar to pixels.
This means the following configurations are possible:
+
+
```html
@@ -359,15 +425,41 @@ This means the following configurations are possible:
```tsx
+ minWidth="60px" maxWidth="230px">
```
```razor
```
+
+
+
+```html
+
+```
+
+```html
+
+```
+
+```tsx
+
+```
+
+```razor
+
+```
+
+
+
or
+
+
```html
@@ -379,19 +471,45 @@ or
```tsx
+ minWidth="5%" maxWidth="15%">
```
```razor
```
+
+
+
+```html
+
+```
+
+```html
+
+```
+
+```tsx
+
+```
+
+```razor
+
+```
+
+
+
## Auto-Size Columns on Double Click
Each column can be **auto sized** by double clicking the right side of the header - the column will be sized to the longest currently visible cell value, including the header itself. This behavior is enabled by default, no additional configuration is needed. However, the column will not be auto-sized in case `MaxWidth` is set on that column and the new width exceeds that `MaxWidth` value. In this case the column will be sized according to preset `MaxWidth` value.
You can also auto-size a column dynamically using the exposed `Autosize` method on `Column`.
+
+
```typescript
@ViewChild('@@igObjectRef') @@igObjectRef: {ComponentName};
@@ -417,7 +535,7 @@ constructor() {
@code {
private {ComponentSelector} gridRef;
- protected void OnInitialize()
+ private void AutosizeColumn()
{
IgbColumn column = gridRef.Columns.Where((col) => { return col.Field == "ID"; }).FirstOrDefault();
column.Autosize(false);
@@ -425,6 +543,44 @@ constructor() {
}
```
+
+
+
+
+```typescript
+@ViewChild('@@igObjectRef') @@igObjectRef: {ComponentName};
+
+let column = this.@@igObjectRef.columnList.filter(c => c.field === 'Artist')[0];
+column.autosize();
+```
+
+
+```typescript
+constructor() {
+ var column = this.column = document.getElementById('Artist') as IgcColumnComponent;
+ column.autosize();
+}
+```
+
+```tsx
+const column = grid.getColumnByName('Artist');
+column.autosize();
+```
+
+```razor
+@code {
+ private {ComponentSelector} gridRef;
+
+ private void AutosizeColumn()
+ {
+ IgbColumn column = gridRef.Columns.Where((col) => { return col.Field == "Artist"; }).FirstOrDefault();
+ column.Autosize(false);
+ }
+}
+```
+
+
+
## Auto-Size Columns on Initialization
Each column can be set to auto-size on initialization by setting `Width` to 'auto':
diff --git a/doc/en/components/grids/_shared/column-types.md b/doc/en/components/grids/_shared/column-types.md
index 685823913..5fae37101 100644
--- a/doc/en/components/grids/_shared/column-types.md
+++ b/doc/en/components/grids/_shared/column-types.md
@@ -67,15 +67,10 @@ public formatOptions = this.options;
```
```ts
-private _formatOptions: any | null = null;
public get formatOptions(): any {
- if (this._formatOptions == null)
- {
- var columnPipeArgs: any = {};
- columnPipeArgs.digitsInfo = "1.4-4";
- this._formatOptions = columnPipeArgs;
- }
- return this._formatOptions;
+ return {
+ digitsInfo: "1.4-4"
+ };
}
constructor() {
@@ -138,16 +133,11 @@ public formatOptions = this.options;
```
```ts
-private _formatDateOptions: any | null = null;
public get formatDateOptions(): any {
- if (this._formatDateOptions == null)
- {
- var columnPipeArgs: any = {};
- columnPipeArgs2.format = "long";
- columnPipeArgs2.timezone = "UTC+0";
- this._formatDateOptions = columnPipeArgs;
- }
- return this._formatDateOptions;
+ return {
+ format: "long",
+ timezone: "UTC+0"
+ };
}
constructor() {
@@ -286,9 +276,7 @@ Default template is using the value coming from the data as an image source to a
```
```tsx
-
-
-
+
```
When `AutoGenerate` is used for the columns, the grid analyses the values in the first data record. If a value is of type string and matches the pattern of a url ending in an image extension (gif, jpg, jpeg, tiff, png, webp, bmp) then the column will automatically be marked as `dataType === GridColumnDataType.Image` and a default image template will be rendered.
@@ -367,17 +355,12 @@ public formatOptions = this.options;
```
```ts
-private _formatOptions: any | null = null;
- public get formatOptions(): any {
- if (this._formatOptions == null)
- {
- var columnPipeArgs: any = {};
- columnPipeArgs.digitsInfo = "1.4-4";
- columnPipeArgs.display = "symbol-narrow";
- this._formatOptions = columnPipeArgs;
- }
- return this._formatOptions;
- }
+public get formatOptions(): any {
+ return {
+ digitsInfo: '3.4-4',
+ display: 'symbol-narrow'
+ };
+}
constructor() {
var column = document.getElementById('column') as IgcColumnComponent;
@@ -465,16 +448,18 @@ public formatPercentOptions = this.options;
```
```ts
-private _formatPercentOptions: any | null = null;
- public get formatPercentOptions(): any {
- if (this._formatPercentOptions == null)
- {
- var columnPipeArgs: any = {};
- columnPipeArgs.digitsInfo = "2.2-3";
- this._formatPercentOptions = columnPipeArgs;
- }
- return this._formatPercentOptions;
- }
+public get formatPercentOptions(): any {
+ return {
+ /**
+ * Decimal representation options, specified by a string in the following format:
+ * `{minIntegerDigits}`.`{minFractionDigits}`-`{maxFractionDigits}`.
+ * `minIntegerDigits`: The minimum number of integer digits before the decimal point. Default is 1.
+ * `minFractionDigits`: The minimum number of digits after the decimal point. Default is 0.
+ * `maxFractionDigits`: The maximum number of digits after the decimal point. Default is 3.
+ */
+ digitsInfo: '2.2-3'
+ };
+}
constructor() {
var column = document.getElementById('column') as IgcColumnComponent;
@@ -483,6 +468,13 @@ constructor() {
```
```tsx
+/**
+* Decimal representation options, specified by a string in the following format:
+* `{minIntegerDigits}`.`{minFractionDigits}`-`{maxFractionDigits}`.
+* `minIntegerDigits`: The minimum number of integer digits before the decimal point. Default is 1.
+* `minFractionDigits`: The minimum number of digits after the decimal point. Default is 0.
+* `maxFractionDigits`: The maximum number of digits after the decimal point. Default is 3.
+*/
const formatOptions = new IgrColumnPipeArgs();
formatOptions.digitsInfo = "2.2-3";
@@ -501,22 +493,23 @@ See the editing templates part of [{ComponentTitle} Editing topic](editing.md#ed
Custom template and column formatter definition will always take precedence over the column data type set:
### Custom Template
-
+
```html
-
+<{ComponentSelector} #grid1 [data]="data | async" [autoGenerate]="false">
{{ value | currency:'USD':'symbol':'1.0-0'}}
-
+{ComponentSelector}>
```
+
```html
-
+<{ComponentSelector} id="grid1" auto-generate="false">
-
+{ComponentSelector}>
```
```ts
@@ -539,9 +532,9 @@ function editCellTemplate(ctx: IgrCellTemplateContext) {
);
}
-
+<{ComponentSelector} autoGenerate="false">
-
+{ComponentSelector}>
```
```razor
@@ -560,10 +553,10 @@ function editCellTemplate(ctx: IgrCellTemplateContext) {
### Column Formatter
```html
-
+<{ComponentSelector} id="grid1" auto-generate="false">
-
+{ComponentSelector}>
```
```ts
@@ -582,9 +575,9 @@ function formatCurrency(value: number) {
return `$ ${value.toFixed(0)}`;
}
-
+<{ComponentSelector} autoGenerate="false">
-
+{ComponentSelector}>
```
```razor
diff --git a/doc/en/components/grids/_shared/conditional-cell-styling.md b/doc/en/components/grids/_shared/conditional-cell-styling.md
index dc9f71d08..115e3fd17 100644
--- a/doc/en/components/grids/_shared/conditional-cell-styling.md
+++ b/doc/en/components/grids/_shared/conditional-cell-styling.md
@@ -32,8 +32,8 @@ You can conditionally style the `{ComponentName}` rows by setting the `RowClasse
```razor
-
-
+<{ComponentSelector} AutoGenerate="true" Id="grid" Data="CustomersData" Name="grid" RowClassesScript="RowClassesHandler" @ref="grid">
+{ComponentSelector}>
```
@@ -44,7 +44,7 @@ You can conditionally style the `{ComponentName}` rows by setting the `RowClasse
```ts
constructor() {
- var grid = this.grid = document.getElementById('grid') as IgcGridComponent;
+ var grid = this.grid = document.getElementById('grid') as {ComponentName};
grid.rowClasses = this.rowClasses;
}
```
@@ -252,7 +252,18 @@ public childRowStyles = {
```
```razor
-Add Hierarchical styles
+igRegisterScript("WebGridRowStylesHandler", () => {
+ return {
+ background:(row: RowType) => row.data['HasGrammyAward'] ? '#eeddd3' : '#f0efeb',
+ 'border-left': (row: RowType) => row.data['HasGrammyAward'] ? '2px solid #dda15e' : null
+ };
+}, true);
+
+igRegisterScript("WebGridChildRowStylesHandler", () => {
+ return {
+ 'border-left': (row: RowType) => row.data['BillboardReview'] > 70 ? '3.5px solid #dda15e' : null
+ };
+}, true);
```
```html
@@ -264,13 +275,17 @@ Add Hierarchical styles
```
```razor
-Add Hierarchical markup
+
+
+
+
```
```html
-
-
+ >
```
@@ -282,6 +297,14 @@ constructor() {
rowIsland1.rowStyles = this.childRowStyles;
}
```
+
+```tsx
+
+
+
+
+```
@@ -327,6 +350,27 @@ constructor() {
+
+```html
+
+```
+```ts
+constructor() {
+ var grammyNominations = document.getElementById('grammyNominations') as IgcColumnComponent;
+ grammyNominations.cellClasses = this.grammyNominationsCellClassesHandler;
+}
+```
+
+```razor
+
+```
+
+```tsx
+
+```
+
+
+
@@ -364,12 +408,6 @@ Add tree grid example
-
-```razor
-add example
-```
-
-
The `CellClasses` input accepts an object literal, containing key-value pairs, where the key is the name of the CSS class, while the value is either a callback function that returns a boolean, or boolean value.
@@ -444,6 +482,43 @@ igRegisterScript("CellClassesHandler", () => {
+
+
+```typescript
+public grammyNominationsCellClassesHandler = {
+ downFont: (rowData: any, columnKey: any): boolean => rowData[columnKey] < 5,
+ upFont: (rowData: any, columnKey: any): boolean => rowData[columnKey] >= 6
+};
+```
+
+
+```tsx
+public grammyNominationsCellClassesHandler = {
+ downFont: (rowData: any, columnKey: any): boolean => rowData[columnKey] < 5,
+ upFont: (rowData: any, columnKey: any): boolean => rowData[columnKey] >= 6
+};
+```
+
+```razor
+igRegisterScript("GrammyNominationsCellClassesHandler", () => {
+ return {
+ downFont: (rowData, columnKey) => rowData[columnKey] < 5,
+ upFont: (rowData, columnKey) => rowData[columnKey] >= 6
+ };
+}, true);
+```
+```css
+.upFont {
+ color: green !important;
+}
+
+.downFont {
+ color: red !important;
+}
+```
+
+
+
```typescript
@@ -479,13 +554,6 @@ Add treegrid example
-
-
-```razor
-Add hierarchical grid example
-```
-
-
Use **::ng-deep** or **ViewEncapsulation.None** to force the custom styles down through the current component and its children.
@@ -511,10 +579,6 @@ Use **::ng-deep** or **ViewEncapsulation.None** to force the custom styles down
Columns expose the `CellStyles` property which allows conditional styling of the column cells. Similar to `CellClasses` it accepts an object literal where the keys are style properties and the values are expressions for evaluation. Also, you can apply regular styling with ease (without any conditions).
-In the [sample above](#demo) we've created:
-- Two different styles that will be applied based on the column index.
-- You will also change the **text color** based on even/odd rows.
-
Let's define our styles:
@@ -537,6 +601,7 @@ public evenColStyles = {
+
```razor
igRegisterScript("WebGridCellStylesHandler", () => {
return {
@@ -553,6 +618,7 @@ igRegisterScript("WebGridCellStylesHandler", () => {
};
}, true);
```
+
```ts
public webGridCellStylesHandler = {
@@ -676,6 +742,142 @@ constructor() {
```tsx
```
+
+
+
+```razor
+igRegisterScript("CellStylesHandler", () => {
+ return {
+ background: (rowData, columnKey, cellValue, rowIndex) => rowIndex % 2 === 0 ? "#EFF4FD" : null,
+ color: (rowData, columnKey, cellValue, rowIndex) => {
+ if (columnKey === "Debut") {
+ return cellValue > 2000 ? "#28a745" : "#dc3545";
+ }
+ return undefined;
+ }
+ };
+}, true);
+```
+
+
+```ts
+public cellStylesHandler = {
+ background: (rowData, columnKey, cellValue, rowIndex) => rowIndex % 2 === 0 ? "#EFF4FD" : null,
+ color: (rowData, columnKey, cellValue, rowIndex) => {
+ if (columnKey === "Debut") {
+ return cellValue > 2000 ? "#28a745" : "#dc3545";
+ }
+ return undefined;
+ }
+}
+```
+
+
+```tsx
+const cellStylesHandler = {
+ background: (rowData, columnKey, cellValue, rowIndex) => rowIndex % 2 === 0 ? "#EFF4FD" : null,
+ color: (rowData, columnKey, cellValue, rowIndex) => {
+ if (columnKey === "Debut") {
+ return cellValue > 2000 ? "#28a745" : "#dc3545";
+ }
+ return undefined;
+ }
+}
+```
+
+
+On `ngOnInit` we will add the `CellStyles` configuration for each column of the predefined `Columns` collection, which is used to create the `{ComponentName}` columns dynamically.
+
+```ts
+public ngOnInit() {
+ this.data = athletesData;
+ this.columns = [
+ { field: 'Id' },
+ { field: 'Position' },
+ { field: 'Name' },
+ { field: 'AthleteNumber' },
+ { field: 'CountryName' }
+ ];
+
+ this.applyCSS();
+}
+
+public applyCSS() {
+ this.columns.forEach((column, index) => {
+ column.cellStyles = (index % 2 === 0 ? this.evenColStyles : this.oddColStyles);
+ });
+}
+
+public updateCSS(css: string) {
+ this.oddColStyles = {...this.oddColStyles, ...JSON.parse(css)};
+ this.evenColStyles = {...this.evenColStyles, ...JSON.parse(css)};
+ this.applyCSS();
+}
+```
+
+```html
+
+
+
+
+```
+
+Define a `popin` animation
+
+```scss
+// component.scss
+@keyframes popin {
+ 0% {
+ opacity: 0.1;
+ transform: scale(.75, .75);
+ filter: blur(3px) invert(1);
+ }
+
+ 50% {
+ opacity: .5;
+ filter: blur(1px);
+ }
+
+ 100% {
+ transform: scale(1, 1);
+ opacity: 1;
+ filter: none;
+ }
+}
+```
+
+
+
+```razor
+
+
+```
+
+```html
+
+
+```
+
+```ts
+constructor() {
+ var col1 = document.getElementById('col1') as IgcColumnComponent;
+ col1.cellStyles = this.cellStylesHandler;
+}
+```
+
+
+```tsx
+
+```
+
+
### Demo
@@ -711,16 +913,16 @@ public editDone(evt) {
```
```html
-
+<{ComponentSelector} id="grid1" height="500px" width="100%" >
-
+<{ComponentSelector}>
```
```ts
constructor() {
- var grid = this.grid = document.getElementById('grid1') as IgcGridComponent;
+ var grid = this.grid = document.getElementById('grid1') as {ComponentName};
var Col1 = this.Col1 = document.getElementById('Col1') as IgcColumnComponent;
var Col2 = this.Col2 = document.getElementById('Col2') as IgcColumnComponent;
var Col3 = this.Col3 = document.getElementById('Col3') as IgcColumnComponent;
@@ -746,11 +948,11 @@ function editDone(grid, evt) {
backgroundClasses = {...backgroundClasses};
}
-
+<{ComponentSelector} id="grid1" height="500px" width="100%" onCellEdit={editDone}>
-
+{ComponentSelector}>
```
## API References
diff --git a/doc/en/components/grids/_shared/display-density.md b/doc/en/components/grids/_shared/display-density.md
index c920e36ab..55143d930 100644
--- a/doc/en/components/grids/_shared/display-density.md
+++ b/doc/en/components/grids/_shared/display-density.md
@@ -49,7 +49,6 @@ As you can see in the demo above, the `{ComponentName}` provides three density o
{ComponentSelector}>
```
-
or
@@ -84,6 +83,7 @@ Let's now continue with our sample and see in action how the `DisplayDensity` is
```
+
```razor
```
+
```typescript
@ViewChild(IgxButtonGroupComponent) public buttonGroup: IgxButtonGroupComponent;
@@ -159,6 +160,57 @@ public ngOnInit() {
}
```
+
+```razor
+
+
+
+
+
+
+```
+
+```html
+
+
+
+
+
+
+```
+
+```tsx
+
+
+
+
+```
+
+
Now we can add the markup.
@@ -494,27 +546,6 @@ Now we can add the markup.
```
-
-```ts
-constructor() {
- var propertyEditor = this.propertyEditor = document.getElementById('PropertyEditor') as IgcPropertyEditorPanelComponent;
- var grid = this.grid = document.getElementById('grid') as IgcGridComponent;
- propertyEditor.componentRenderer = this.renderer;
- propertyEditor.target = this.grid;
- grid.data = this.data;
-}
-
-private _componentRenderer: ComponentRenderer = null;
-public get renderer(): ComponentRenderer {
- if (this._componentRenderer == null) {
- this._componentRenderer = new ComponentRenderer();
- var context = this._componentRenderer.context;
- PropertyEditorPanelDescriptionModule.register(context);
- WebGridDescriptionModule.register(context);
- }
- return this._componentRenderer;
-}
-```
@@ -656,26 +687,6 @@ public get renderer(): ComponentRenderer {
```
-```ts
-constructor() {
- var propertyEditor = this.propertyEditor = document.getElementById('PropertyEditor') as IgcPropertyEditorPanelComponent;
- var grid = this.grid = document.getElementById('grid') as IgcTreeGridComponent;
- propertyEditor.componentRenderer = this.renderer;
- propertyEditor.target = this.grid;
- grid.data = this.data;
-}
-
-private _componentRenderer: ComponentRenderer = null;
-public get renderer(): ComponentRenderer {
- if (this._componentRenderer == null) {
- this._componentRenderer = new ComponentRenderer();
- var context = this._componentRenderer.context;
- PropertyEditorPanelDescriptionModule.register(context);
- WebGridDescriptionModule.register(context);
- }
- return this._componentRenderer;
-}
-```
@@ -709,6 +720,7 @@ public get renderer(): ComponentRenderer {
+
@@ -721,6 +733,123 @@ public get renderer(): ComponentRenderer {
```
```razor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
```
```html
@@ -763,6 +892,7 @@ public get renderer(): ComponentRenderer {
+
@@ -773,10 +903,68 @@ public get renderer(): ComponentRenderer {
```
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+Finally, let's provide the necessary logic in order to actually apply the density:
+
+
+
+```typescript
+@ViewChild('grid', { read: {ComponentName} })
+public grid: {ComponentName};
+
+public selectDensity(event) {
+ this.density = this.displayDensities[event.index].label;
+}
+```
+
+
+
```ts
constructor() {
var propertyEditor = this.propertyEditor = document.getElementById('PropertyEditor') as IgcPropertyEditorPanelComponent;
- var grid = this.grid = document.getElementById('grid') as IgcHierarchicalGridComponent;
+ var grid = this.grid = document.getElementById('grid') as {ComponentName};
propertyEditor.componentRenderer = this.renderer;
propertyEditor.target = this.grid;
grid.data = this.data;
@@ -793,20 +981,7 @@ public get renderer(): ComponentRenderer {
return this._componentRenderer;
}
```
-
-
-Finally, let's provide the necessary logic in order to actually apply the density:
-
-
-```typescript
-@ViewChild('grid', { read: {ComponentName} })
-public grid: {ComponentName};
-
-public selectDensity(event) {
- this.density = this.displayDensities[event.index].label;
-}
-```
-
+
```razor
@code {
@@ -822,7 +997,39 @@ public selectDensity(event) {
private IgbPropertyEditorPanel propertyEditor;
private IgbPropertyEditorPropertyDescription displayDensityEditor;
- private IgbGrid grid;
+ private {ComponentSelector} grid;
+}
+```
+
+```tsx
+private propertyEditor: IgrPropertyEditorPanel
+private propertyEditorRef(r: IgrPropertyEditorPanel) {
+ this.propertyEditor = r;
+ this.setState({});
+}
+private displayDensityEditor: IgrPropertyEditorPropertyDescription
+private grid: {ComponentName}
+private gridRef(r: {ComponentName}) {
+ this.grid = r;
+ this.setState({});
+}
+
+constructor(props: any) {
+ super(props);
+
+ this.propertyEditorRef = this.propertyEditorRef.bind(this);
+ this.gridRef = this.gridRef.bind(this);
+}
+
+private _componentRenderer: ComponentRenderer = null;
+ public get renderer(): ComponentRenderer {
+ if (this._componentRenderer == null) {
+ this._componentRenderer = new ComponentRenderer();
+ var context = this._componentRenderer.context;
+ PropertyEditorPanelDescriptionModule.register(context);
+ WebHierarchicalGridDescriptionModule.register(context);
+ }
+ return this._componentRenderer;
}
```
diff --git a/doc/en/components/grids/_shared/editing.md b/doc/en/components/grids/_shared/editing.md
index d8d095b51..089e8d2a5 100644
--- a/doc/en/components/grids/_shared/editing.md
+++ b/doc/en/components/grids/_shared/editing.md
@@ -61,14 +61,14 @@ In the `{ComponentName}`, if you set `RowEditable` property to true, and the `Ed
- For custom templates you can see [Cell Editing topic](cell-editing.md#{PlatformLower}-grid-cell-editing-and-edit-templates-example)
-
+
All available column data types could be found in the official [Column types topic](column-types.md#default-template).
-
+
### Event Arguments and Sequence
-
+
The grid exposes a wide array of events that provide greater control over the editing experience. These events are fired during the [**Row Editing**](row-editing.md) and [**Cell Editing**](cell-editing.md) lifecycle - when starting, committing or canceling the editing action.
-
+
| Event | Description | Arguments | Cancellable |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ----------- |
@@ -107,6 +107,7 @@ As seen from the table, all interactions, except resizing a column, will end the
Example how to commit new values, if user tries to sort the column while a cell/row is in edit mode:
+
```html
@@ -178,6 +179,76 @@ function onSorting(grid: IgrGridBaseDirective, event: IgrSortingEventArgs) {
```
+
+
+
+
+```html
+
+
+```
+
+
+
+```html
+<{ComponentSelector} id="hierarchicalGrid" primary-key="ProductID" >
+{ComponentSelector}>
+```
+
+```ts
+constructor() {
+ var hierarchicalGrid = document.getElementById('hierarchicalGrid') as {ComponentName}Component;
+ hierarchicalGrid.data = this.data;
+ hierarchicalGrid.addEventListener("sorting", this.onSorting);
+}
+
+public onSorting(event: IgcSortingEventArgs) {
+ var hierarchicalGrid = document.getElementById('hierarchicalGrid') as {ComponentName}Component;
+ hierarchicalGrid.endEdit(true);
+}
+```
+
+
+
+```typescript
+public onSorting(event: ISortingEventArgs) {
+ this.hierarchicalGrid.endEdit(true);
+}
+```
+
+
+```razor
+<{ComponentSelector}
+ Id="hierarchicalGrid"
+ SortingScript="SortingHandler"
+ RowEditable="true">
+{ComponentSelector}>
+
+//In JavaScript
+function SortingHandler() {
+ hierarchicalGrid.endEdit(true);
+}
+igRegisterScript("SortingHandler", SortingHandler, false);
+```
+
+
+
+```tsx
+
+
+```
+
+
+
+
+```tsx
+public onSorting(grid: IgrGridBaseDirective, event: IgrSortingEventArgs) {
+ hierarchicalGrid.endEdit(true);
+}
+```
+
+
+
## API References
diff --git a/doc/en/components/grids/_shared/excel-style-filtering.md b/doc/en/components/grids/_shared/excel-style-filtering.md
index add0cb724..717265882 100644
--- a/doc/en/components/grids/_shared/excel-style-filtering.md
+++ b/doc/en/components/grids/_shared/excel-style-filtering.md
@@ -41,8 +41,8 @@ To turn on the `{ComponentName}` component's Excel-style filtering, two inputs s
```tsx
-
-
+<{ComponentSelector} data={nwindData} autoGenerate="true" allowFiltering="true" filterMode={FilterMode.ExcelStyleFilter}>
+{ComponentSelector}>
```
@@ -81,16 +81,13 @@ Sorting, pinning and hiding features can be removed from the filter menu using t
```
```razor
-
-
-
-
-
-
-
+
+
+
+
+
+
+
```
```html
@@ -109,7 +106,7 @@ Sorting, pinning and hiding features can be removed from the filter menu using t
```
```tsx
-
+
@@ -155,7 +152,7 @@ In the sample below **Product Name** and **Discontinued** columns have all four
```
```razor
-
+
@@ -192,7 +189,7 @@ In the sample below 'Product Name' and 'Discontinued' columns have all three fea
```html
-
@@ -203,67 +200,48 @@ In the sample below 'Product Name' and 'Discontinued' columns have all three fea
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
```
-```razor
-Add blazor snippets here
-```
-
```html
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
```
+```tsx
+
+
+
+
+
+
+ {/* ... */}
+
+```
+
+```razor
+
+
+
+
+
+
+ @* ... *@
+
+```
+
In the sample below 'Artist' column have all three features enabled, 'Debut' have all three disabled, 'Grammy Nominations' has only pinning and hiding.
@@ -292,9 +270,7 @@ If you want to further customize the Excel style filter menu, you can use the `E
The following code demonstrates how to customize the Excel style filter menu using the `ExcelStyleHeaderIconTemplate`:
```razor
-<{ComponentSelector}
- Name="grid"
- @ref="grid"
+<{ComponentSelector}
Data="Data"
AllowFiltering="true"
FilterMode="FilterMode.ExcelStyleFilter"
@@ -308,6 +284,7 @@ igRegisterScript("WebGridFilterAltIconTemplate", (ctx) => {
}, false);
```
+
```ts
constructor() {
var grid = this.grid = document.getElementById('grid') as {ComponentName}Component;
@@ -318,6 +295,7 @@ public webGridFilterAltIconTemplate = (ctx: IgcCellTemplateContext) => {
return html``
}
```
+
```tsx
const webGridFilterAltIconTemplate = ({dataContext: IgrCellTemplateContext}) => {
@@ -332,15 +310,9 @@ const webGridFilterAltIconTemplate = ({dataContext: IgrCellTemplateContext}) =>
);
}
-function App() {
- return (
- <>
-
-
- <>
- )
-}
+<{ComponentSelector} autoGenerate="true" allowFiltering="true" filterMode="excelStyleFilter"
+ excelStyleHeaderIconTemplate={webGridFilterAltIconTemplate}>
+{ComponentSelector}>
```
@@ -1054,7 +1026,7 @@ In case you would like to change some of the colors, you need to set a class for
```
```tsx
-
+<{ComponentSelector} className="grid">{ComponentSelector}>
```
```razor
diff --git a/doc/en/components/grids/_shared/export-excel.md b/doc/en/components/grids/_shared/export-excel.md
index 9fad113af..24ad2297d 100644
--- a/doc/en/components/grids/_shared/export-excel.md
+++ b/doc/en/components/grids/_shared/export-excel.md
@@ -123,6 +123,7 @@ public exportButtonHandler() {
+
```ts
constructor() {
var gridToolbarExporter1 = document.getElementById('gridToolbarExporter1') as IgcGridToolbarExporterComponent;
@@ -133,6 +134,22 @@ public webGridExportEventFreezeHeaders(args: any): void {
args.detail.options.freezeHeaders = true;
}
```
+
+
+
+
+
+```ts
+constructor() {
+ var hGridToolbarExporter = document.getElementById('hGridToolbarExporter') as IgcGridToolbarExporterComponent;
+ hGridToolbarExporter.addEventListener("exportStarted", this.webGridExportEventFreezeHeaders);
+}
+
+public webGridExportEventFreezeHeaders(args: CustomEvent): void {
+ args.detail.options.freezeHeaders = true;
+}
+```
+
```tsx
@@ -147,21 +164,56 @@ function exportEventFreezeHeaders(grid: IgrGridBaseDirective, args: IgrExporterE
```
+
+
+```tsx
+function exportEventFreezeHeaders(sender: IgrGridToolbarExporter, args: IgrExporterEventEventArgs) {
+ args.detail.options.freezeHeaders = true;
+}
+
+
+
+
+
+
+```
+
+
+
```razor
<{ComponentSelector}>
+ ExportExcel="true" ExportStartedScript="WebGridExportEventFreezeHeaders">
{ComponentSelector}>
-igRegisterScript("WebGridExportEventMultiColumnHeaders", (ev) => {
- ev.detail.options.ignoreMultiColumnHeaders = false;
+igRegisterScript("WebGridExportEventFreezeHeaders", (ev) => {
+ ev.detail.options.freezeHeaders = false;
}, false);
```
+
+
+```razor
+ <{ComponentSelector}>
+
+
+
+
+
+
+ {ComponentSelector}>
+
+igRegisterScript("WebHierarchicalGridExportEventFreezeHeaders", (ev) => {
+ ev.detail.options.freezeHeaders = false;
+}, false);
+```
+
+
```razor
diff --git a/doc/en/components/grids/_shared/filtering.md b/doc/en/components/grids/_shared/filtering.md
index b9deacb4b..d87077daf 100644
--- a/doc/en/components/grids/_shared/filtering.md
+++ b/doc/en/components/grids/_shared/filtering.md
@@ -59,23 +59,19 @@ Property `Filterable` enables you to specify the following options:
{ComponentSelector}>
```
-
```html
<{ComponentSelector} id="grid1" auto-generate="false" allow-filtering="true">
-<{ComponentSelector}>
+{ComponentSelector}>
```
-
-
```tsx
<{ComponentSelector} data={this.nwindData} autoGenerate="false" ref={this.gridRef} allowFiltering="true">
{ComponentSelector}>
```
-
To enable the [Advanced filtering](advanced-filtering.md) however, you need to set the `AllowAdvancedFiltering` input property to **true**.
@@ -580,20 +576,16 @@ constructor() {
-
-
+
+
```
```ts
constructor() {
- var artist = this.artist = document.getElementById('Artist') as IgcColumnComponent;
- var hasGrammyAward = this.hasGrammyAward = document.getElementById('HasGrammyAward') as IgcColumnComponent;
-
- this._bind = () => {
- artist.bodyTemplate = this.caseSensitiveFilteringOperand;
- hasGrammyAward.bodyTemplate = this.booleanFilteringOperand;
- }
- this._bind();
+ var artist = document.getElementById('Artist') as IgcColumnComponent;
+ var hasGrammyAward = document.getElementById('HasGrammyAward') as IgcColumnComponent;
+ artist.filters = this.caseSensitiveFilteringOperand;
+ hasGrammyAward.filters = this.booleanFilteringOperand;
}
```
@@ -651,18 +643,18 @@ In addition to the predefined themes, the grid could be further customized by se
In case you would like to change some of the colors, you need to set a class for the grid first:
-```ts
+```html
<{ComponentSelector} class="grid">{ComponentSelector}>
```
```razor
-<{ComponentSelector} Class="grid">
+<{ComponentSelector} Class="grid">{ComponentSelector}>
```
```tsx
-
+<{ComponentSelector} className="grid">{ComponentSelector}>
```
diff --git a/doc/en/components/grids/_shared/multi-column-headers.md b/doc/en/components/grids/_shared/multi-column-headers.md
index ebcffb740..ed6ba7353 100644
--- a/doc/en/components/grids/_shared/multi-column-headers.md
+++ b/doc/en/components/grids/_shared/multi-column-headers.md
@@ -117,24 +117,76 @@ The declaration of multi-column headers is achieved by wrapping a set of columns
```html
-
+
-
-
-
-
+
+
+
+
-
-
+
+
```
```razor
-TO-DO H-GRID CODE SNIPPET
+<{ComponentSelector} Data="HierarchicalCustomers" Name="hierarchicalGrid" @ref="hierarchicalGrid" Id="hierarchicalGrid" PrimaryKey="ID" Moving="true" AllowFiltering="true">
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
```
@@ -259,7 +311,7 @@ For achieving `n-th` level of nested headers, the declaration above should be fo
```html
-
+
@@ -270,7 +322,44 @@ For achieving `n-th` level of nested headers, the declaration above should be fo
```
```razor
-TO-DO H-GRID CODE SNIPPET
+<{ComponentSelector} Data="HierarchicalCustomers" Name="hierarchicalGrid" @ref="hierarchicalGrid" Id="hierarchicalGrid" PrimaryKey="ID" Moving="true" AllowFiltering="true">
+
+
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+```
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
```
@@ -285,7 +374,7 @@ Every `ColumnGroup` supports [moving](column-moving.md), [pinning](column-pinnin
```html
<{ComponentSelector} [data]="data" height="600px" [allowFiltering]="true">
-
+
@@ -397,7 +486,44 @@ Every `ColumnGroup` supports [moving](column-moving.md), [pinning](column-pinnin
```
```razor
-TO-DO H-GRID CODE SNIPPET
+<{ComponentSelector} Data="HierarchicalCustomers" Name="hierarchicalGrid" @ref="hierarchicalGrid" Id="hierarchicalGrid" PrimaryKey="ID" Moving="true" AllowFiltering="true">
+
+
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+```
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
```
diff --git a/doc/en/components/grids/_shared/row-actions.md b/doc/en/components/grids/_shared/row-actions.md
index 81572bdba..e0ea835d1 100644
--- a/doc/en/components/grids/_shared/row-actions.md
+++ b/doc/en/components/grids/_shared/row-actions.md
@@ -78,6 +78,22 @@ They are added inside the `{ComponentName}` and this is all needed to have an `A
```
+
+```razor
+
+ @foreach (var c in columns)
+ {
+
+
+ }
+
+
+
+
+
+```
+
+
```html
@@ -99,9 +115,22 @@ They are added inside the `{ComponentName}` and this is all needed to have an `A
```
+
+
+```html
+
+
+
+
+
+
+
+```
+
+
```tsx
<{ComponentSelector} id="grid" rowEditable="true" primaryKey="ID">
@@ -112,12 +141,26 @@ They are added inside the `{ComponentName}` and this is all needed to have an `A
{ComponentSelector}>
```
+
+
+
+```tsx
+
+
+
+
+
+
+
+
+```
+
> [!Note]
> When `ActionStripComponent` is a child component of the `{ComponentName}`, hovering a row will automatically show the UI.
-
+
## Custom Implementation
@@ -138,6 +181,7 @@ These components expose templates giving flexibility for customization. For inst
{ComponentSelector}>
```
+
```razor
<{ComponentSelector} Data=northwindEmployees>
@@ -156,11 +200,33 @@ These components expose templates giving flexibility for customization. For inst
{ComponentSelector}>
+```
+
+
+
```html
<{ComponentSelector}>
@@ -169,17 +235,42 @@ These components expose templates giving flexibility for customization. For inst
{ComponentSelector}>
```
+
+
+
+```html
+
+
+
+
+
+
+```
+
+
```tsx
<{ComponentSelector}>
-
+
{ComponentSelector}>
```
+
+
+
+```tsx
+
+
+
+
+
+
+```
+
`sample="/{ComponentSample}/action-strip", height="600", alt="{Platform} {ComponentTitle} Action Strip Example"`
diff --git a/doc/en/components/grids/_shared/row-adding.md b/doc/en/components/grids/_shared/row-adding.md
index 7073307c0..4311e9e8a 100644
--- a/doc/en/components/grids/_shared/row-adding.md
+++ b/doc/en/components/grids/_shared/row-adding.md
@@ -185,9 +185,8 @@ Then define a `{ComponentName}` with bound data source, `RowEditable` set to tru
-
-
+
```html
<{ComponentSelector} igxPreventDocumentScroll [data]="localdata"
[autoGenerate]="false" [primaryKey]="'Debut'" [rowEditable]="true">
@@ -225,9 +224,11 @@ Then define a `{ComponentName}` with bound data source, `RowEditable` set to tru
{ComponentSelector}>
```
+
+
```html
<{ComponentSelector} id="hGrid" auto-generate="false" primary-key="Debut" row-editable="true">
@@ -264,8 +265,11 @@ Then define a `{ComponentName}` with bound data source, `RowEditable` set to tru
{ComponentSelector}>
```
+
+
+
```razor
<{ComponentSelector} AutoGenerate="false" Id="hGrid" PrimaryKey="Debut" RowEditable="true">
@@ -302,8 +306,148 @@ Then define a `{ComponentName}` with bound data source, `RowEditable` set to tru
{ComponentSelector}>
```
+
+
+
+
+```tsx
+<{ComponentSelector}
+ autoGenerate="false"
+ data={this.singersData}
+ id="hGrid"
+ primaryKey="ID"
+ rowEditable="true"
+ ref={this.hierarchicalGrid1Ref}>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
> **Note**:
> Setting primary key is mandatory for row adding operations.
@@ -459,6 +603,7 @@ After a new row is added through the row adding UI, its position and/or visibili
Customizing the text of the row adding overlay is possible using the `RowAddTextDirective`.
+
```html
<{ComponentSelector} [data]="data" [primaryKey]="'ProductID'" [autoGenerate]="false" [rowEditable]="true">
@@ -466,24 +611,41 @@ Customizing the text of the row adding overlay is possible using the `RowAddText
{ComponentSelector}>
```
+
+
```ts
this.grid.rowAddTextTemplate = (ctx: IgcGridEmptyTemplateContext) => {
return html`Adding Row`;
}
```
+
+
```tsx
gridRef.current.rowAddTextTemplate = (ctx: IgrGridEmptyTemplateContext) => {
return ('Adding Row');
}
-```
+```
+
+
+
+```tsx
+gridRef.current.rowAddTextTemplate = (ctx: IgrGridEmptyTemplateContext) => {
+ return ('Adding Row');
+}
+```
+
+
+
+
+
```razor
<{ComponentSelector} Data="data" PrimaryKey="ProductID" AutoGenerate="false" RowEditable="true" RowAddTextTemplate="addTextTemplate">
{ComponentSelector}>
@@ -494,7 +656,9 @@ gridRef.current.rowAddTextTemplate = (ctx: IgrGridEmptyTemplateContext) => {
return @Adding Row;
};
}
-```
+```
+
+
### Customizing Buttons
diff --git a/doc/en/components/grids/_shared/row-drag.md b/doc/en/components/grids/_shared/row-drag.md
index 4a1201d9a..aecebb766 100644
--- a/doc/en/components/grids/_shared/row-drag.md
+++ b/doc/en/components/grids/_shared/row-drag.md
@@ -316,6 +316,58 @@ The drag handle icon can be templated using the grid's `DragIndicatorIconTemplat
To do so, we can use the `DragIndicatorIcon` to pass a template inside of the `{ComponentSelector}`'s body:
+
+
+```tsx
+ function dragIndicatorIconTemplate(ctx: IgrGridEmptyTemplateContext) {
+ return (
+ <>
+
+ >
+ );
+ }
+
+
+
+```
+
+
+```razor
+
+
+
+private RenderFragment dragIndicatorIconTemplate = (context) =>
+{
+ return @
+
+
;
+};
+```
+
+
+
+
+
+```html
+<{ComponentSelector} row-draggable="true" id="grid">
+{ComponentSelector}>
+```
+
+```ts
+constructor() {
+ var grid = this.grid = document.getElementById('grid') as IgcHierarchicalGridComponent;
+ grid.dragIndicatorIconTemplate = this.dragIndicatorIconTemplate;
+}
+
+public dragIndicatorIconTemplate = (ctx: IgcGridEmptyTemplateContext) => {
+ return html``;
+}
+```
+
+
+
+
+
```html
<{ComponentSelector}>
@@ -326,6 +378,8 @@ To do so, we can use the `DragIndicatorIcon` to pass a template inside of the `{
```
+
+
```html
@@ -370,6 +424,7 @@ private RenderFragment dragIndicatorIconTemplate =
;
};
```
+
Once we've set the new icon template, we also need to adjust the **DEFAULT** icon in our **DragIcon enum**, so it's properly change by the `ChangeIcon` method:
@@ -471,6 +526,62 @@ Since all of the actions will be happening _inside_ of the grid's body, that's w
With the help of the grid's row drag events you can create a grid that allows you to reorder rows by dragging them.
+
+
+
+
+```html
+
+
+```
+
+```ts
+constructor() {
+ var hGrid = this.grihGridd = document.getElementById('hGrid') as IgcHierarchicalGridComponent;
+ hGrid.addEventListener("rowDragEnd", this.webHierarchicalGridReorderRowHandler)
+}
+```
+
+
+```tsx
+
+
+```
+
+```razor
+
+
+// In JavaScript
+igRegisterScript("WebHierarchicalGridReorderRowHandler", (args) => {
+ const ghostElement = args.detail.dragDirective.ghostElement;
+ const dragElementPos = ghostElement.getBoundingClientRect();
+ const grid = document.getElementsByTagName("igc-hierarchical-grid")[0];
+ const rows = Array.prototype.slice.call(document.getElementsByTagName("igx-hierarchical-grid-row"));
+ const currRowIndex = this.getCurrentRowIndex(rows,
+ { x: dragElementPos.x, y: dragElementPos.y });
+ if (currRowIndex === -1) { return; }
+ // remove the row that was dragged and place it onto its new location
+ grid.deleteRow(args.detail.dragData.key);
+ grid.data.splice(currRowIndex, 0, args.detail.dragData.data);
+}, false);
+
+function getCurrentRowIndex(rowList, cursorPosition) {
+ for (const row of rowList) {
+ const rowRect = row.getBoundingClientRect();
+ if (cursorPosition.y > rowRect.top + window.scrollY && cursorPosition.y < rowRect.bottom + window.scrollY &&
+ cursorPosition.x > rowRect.left + window.scrollX && cursorPosition.x < rowRect.right + window.scrollX) {
+ // return the index of the targeted row
+ return parseInt(row.attributes["data-rowindex"].value);
+ }
+ }
+ return -1;
+}
+```
+
+
+
+
+
```html
@@ -486,11 +597,16 @@ constructor() {
```
+
+
```tsx
```
+
+
+
```razor
@@ -520,6 +636,9 @@ function getCurrentRowIndex(rowList, cursorPosition) {
return -1;
}
```
+
+
+
@@ -691,6 +810,8 @@ export class TreeGridRowReorderComponent {
+
+
```typescript
export class HGridRowReorderComponent {
public rowDragStart(args: any): void {
@@ -742,6 +863,98 @@ export class HGridRowReorderComponent {
}
```
+
+
+
+```tsx
+ public webHierarchicalGridReorderRowHandler(sender: IgrHierarchicalGrid, args: IgrRowDragEndEventArgs): void {
+ const ghostElement = args.detail.dragDirective.ghostElement;
+ const dragElementPos = ghostElement.getBoundingClientRect();
+ const grid = this.hierarchicalGrid;
+ grid.collapseAll();
+ const rows = Array.prototype.slice.call(document.getElementsByTagName("igx-hierarchical-grid-row"));
+ const currRowIndex = this.getCurrentRowIndex(rows,
+ { x: dragElementPos.x, y: dragElementPos.y });
+ if (currRowIndex === -1) { return; }
+ // remove the row that was dragged and place it onto its new location
+ grid.deleteRow(args.detail.dragData.key);
+ grid.data.splice(currRowIndex, 0, args.detail.dragData.data);
+ }
+
+ public getCurrentRowIndex(rowList: any[], cursorPosition: any) {
+ for (const row of rowList) {
+ const rowRect = row.getBoundingClientRect();
+ if (cursorPosition.y > rowRect.top + window.scrollY && cursorPosition.y < rowRect.bottom + window.scrollY &&
+ cursorPosition.x > rowRect.left + window.scrollX && cursorPosition.x < rowRect.right + window.scrollX) {
+ // return the index of the targeted row
+ return parseInt(row.attributes["data-rowindex"].value);
+ }
+ }
+ return -1;
+ }
+```
+
+
+
+```typescript
+public webGridReorderRowHandler(args: CustomEvent): void {
+ const ghostElement = args.detail.dragDirective.ghostElement;
+ const dragElementPos = ghostElement.getBoundingClientRect();
+ const grid = document.getElementsByTagName("igc-hierarchical-grid")[0] as any;
+ const rows = Array.prototype.slice.call(document.getElementsByTagName("igx-grid-row"));
+ const currRowIndex = this.getCurrentRowIndex(rows,
+ { x: dragElementPos.x, y: dragElementPos.y });
+ if (currRowIndex === -1) { return; }
+ // remove the row that was dragged and place it onto its new location
+ grid.deleteRow(args.detail.dragData.key);
+ grid.data.splice(currRowIndex, 0, args.detail.dragData.data);
+}
+public getCurrentRowIndex(rowList: any[], cursorPosition) {
+ for (const row of rowList) {
+ const rowRect = row.getBoundingClientRect();
+ if (cursorPosition.y > rowRect.top + window.scrollY && cursorPosition.y < rowRect.bottom + window.scrollY &&
+ cursorPosition.x > rowRect.left + window.scrollX && cursorPosition.x < rowRect.right + window.scrollX) {
+ // return the index of the targeted row
+ return parseInt(row.attributes["data-rowindex"].value);
+ }
+ }
+ return -1;
+}
+```
+
+
+
+```razor
+
+
+//In JavaScript
+igRegisterScript("WebGridReorderRowHandler", (args) => {
+ const ghostElement = args.detail.dragDirective.ghostElement;
+ const dragElementPos = ghostElement.getBoundingClientRect();
+ const grid = document.getElementsByTagName("igc-hierarchical-grid")[0];
+ const rows = Array.prototype.slice.call(document.getElementsByTagName("igx-hierarchical-grid-row"));
+ const currRowIndex = this.getCurrentRowIndex(rows,
+ { x: dragElementPos.x, y: dragElementPos.y });
+ if (currRowIndex === -1) { return; }
+ // remove the row that was dragged and place it onto its new location
+ grid.deleteRow(args.detail.dragData.key);
+ grid.data.splice(currRowIndex, 0, args.detail.dragData.data);
+}, false);
+
+function getCurrentRowIndex(rowList, cursorPosition) {
+ for (const row of rowList) {
+ const rowRect = row.getBoundingClientRect();
+ if (cursorPosition.y > rowRect.top + window.scrollY && cursorPosition.y < rowRect.bottom + window.scrollY &&
+ cursorPosition.x > rowRect.left + window.scrollX && cursorPosition.x < rowRect.right + window.scrollX) {
+ // return the index of the targeted row
+ return parseInt(row.attributes["data-rowindex"].value);
+ }
+ }
+ return -1;
+}
+```
+
+
With these few easy steps, you've configured a grid that allows reordering rows via drag/drop! You can see the above code in action in the following demo.
diff --git a/doc/en/components/grids/_shared/row-editing.md b/doc/en/components/grids/_shared/row-editing.md
index f3935c8be..0ebe01688 100644
--- a/doc/en/components/grids/_shared/row-editing.md
+++ b/doc/en/components/grids/_shared/row-editing.md
@@ -42,6 +42,8 @@ export class AppModule {}
Define a `{ComponentName}` with bound data source and `RowEditable` set to true:
+
+
```html
<{ComponentSelector} [data]="data" [primaryKey]="'ProductID'" width="100%" height="500px" [rowEditable]="true">
@@ -105,8 +107,6 @@ function unitsInStockCellTemplate(ctx: IgrCellTemplateContext) {
{ComponentSelector}>
```
-
-
```razor
<{ComponentSelector} Width="100%"
Height="100%"
@@ -136,6 +136,306 @@ function unitsInStockCellTemplate(ctx: IgrCellTemplateContext) {
}
}
```
+
+
+
+
+```html
+<{ComponentSelector} [data]="data" [primaryKey]="'ProductID'" width="100%" height="500px" [rowEditable]="true">
+
+
+
+
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```ts
+constructor() {
+ var grid = document.getElementById('hierarchicalGrid') as {ComponentName}Component;
+ grid.data = this.data;
+}
+```
+
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+```razor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
> [!Note]
> Setting primary key is mandatory for row editing operations.
@@ -232,14 +532,14 @@ The `RowChangesCount` property is exposed and it holds the count of the changed
```
- ```razor
+```razor
igRegisterScript("RowEditTextTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`
Changes: ${ctx.implicit}
`;
}, false);
- ```
+```
```ts
public rowEditTextTemplate = (ctx: IgcGridRowEditTextTemplateContext) => {
@@ -247,6 +547,8 @@ public rowEditTextTemplate = (ctx: IgcGridRowEditTextTemplateContext) => {
}
```
+
+
```tsx
function rowEditTextTemplate(ctx: IgrGridRowEditTextTemplateContext) {
return (
@@ -256,6 +558,8 @@ function rowEditTextTemplate(ctx: IgrGridRowEditTextTemplateContext) {
);
}
```
+
+
### Customizing Buttons
@@ -265,14 +569,14 @@ Customizing the buttons of the row editing overlay also possible via templating.
If you want the buttons to be part of the keyboard navigation, then each on of them should have the `RowEditTabStopDirective`.
- ```html
+```html
- ```
+```
- ```razor
+```razor
igRegisterScript("RowEditActionsTemplate", (ctx) => {
var html = window.igTemplating.html;
window.endRowEdit = ctx.implicit;
@@ -281,7 +585,7 @@ If you want the buttons to be part of the keyboard navigation, then each on of t
`;
}, false);
- ```
+```
```ts
public rowEditActionsTemplate = (ctx: IgcGridRowEditActionsTemplateContext) => {
@@ -293,6 +597,8 @@ public rowEditActionsTemplate = (ctx: IgcGridRowEditActionsTemplateContext) => {
}
```
+
+
```tsx
function rowEditActionsTemplate(ctx: IgrGridRowEditActionsTemplateContext) {
const endRowEdit = ctx.dataContext.implicit;
@@ -304,6 +610,8 @@ function rowEditActionsTemplate(ctx: IgrGridRowEditActionsTemplateContext) {
);
}
```
+
+
diff --git a/doc/en/components/grids/_shared/row-pinning.md b/doc/en/components/grids/_shared/row-pinning.md
index 197fe650b..cfd9c1e55 100644
--- a/doc/en/components/grids/_shared/row-pinning.md
+++ b/doc/en/components/grids/_shared/row-pinning.md
@@ -31,7 +31,7 @@ The built-in row pinning UI is enabled by adding an `ActionStrip` component with
{ComponentSelector}>
```
-
+
```razor
<{ComponentSelector} Width="100%"
Height="100%"
@@ -55,8 +55,10 @@ The built-in row pinning UI is enabled by adding an `ActionStrip` component with
{ComponentSelector}>
```
+
+
```html
<{ComponentSelector} auto-generate="false">
@@ -66,8 +68,10 @@ The built-in row pinning UI is enabled by adding an `ActionStrip` component with
{ComponentSelector}>
```
+
+
```tsx
<{ComponentSelector}>
@@ -77,6 +81,7 @@ The built-in row pinning UI is enabled by adding an `ActionStrip` component with
{ComponentSelector}>
```
+
## Row Pinning API
@@ -146,6 +151,7 @@ public rowPinning(event) {
```
+
```tsx
function rowPinning(grid: IgrGridBaseDirective, event: IgrPinRowEventArgs ) {
event.detail.insertAtIndex = 0;
@@ -154,6 +160,7 @@ function rowPinning(grid: IgrGridBaseDirective, event: IgrPinRowEventArgs ) {
<{ComponentSelector} autoGenerate="true" rowPinning={rowPinning}>
{ComponentSelector}>
```
+
```razor
<{ComponentSelector} Width="100%"
@@ -175,7 +182,6 @@ function rowPinningHandler(event) {
igRegisterScript("rowPinningHandler", rowPinningHandler, false);
```
-
## Pinning Position
@@ -225,7 +231,16 @@ grid.pinning = { rows: RowPinningPosition.Bottom };
}
}
```
-
+
+
+```tsx
+ <{ComponentSelector} id="dataGrid" autoGenerate="true">
+ {ComponentSelector}>
+
+ var hierarchicalGrid = document.getElementById("dataGrid") as IgrGrid;
+ hierarchicalGrid.pinning = { rows: RowPinningPosition.Bottom };
+```
+
## Custom Row Pinning UI
@@ -236,6 +251,7 @@ You can define your custom UI and change the pin state of the rows via the relat
Let's say that instead of an action strip you would like to show a pin icon in every row allowing the end-user to click and change a particular row's pin state.
This can be done by adding an extra column with a cell template containing the custom icon.
+
```razor
@@ -270,7 +286,6 @@ igRegisterScript("WebGridRowPinCellTemplate", (ctx) => {
```
-On click of the custom icon the pin state of the related row can be changed using the row's API methods.
```typescript
public togglePinning(row: IgxGridRow, event) {
@@ -305,7 +320,9 @@ public pinCellTemplate = (ctx: IgcCellTemplateContext) => {
return html` this.togglePinning(index)}>📌`;
}
```
+
+
```tsx
function cellPinCellTemplate(ctx: IgrCellTemplateContext) {
const index = ctx.dataContext.cell.id.rowIndex;
@@ -321,9 +338,106 @@ function cellPinCellTemplate(ctx: IgrCellTemplateContext) {
{ComponentSelector}>
```
+
-On click of the custom icon the pin state of the related row can be changed using the row's API methods.
+
+
+
+```razor
+
+
+// In Javascript
+
+igRegisterScript("WebHierarchicalGridRowPinCellTemplate", (ctx) => {
+ var html = window.igTemplating.html;
+ window.toggleRowPin = function toggleRowPin(row) {
+ row.pinned = !row.pinned;
+ }
+ const row = ctx.cell.row;
+ return html`
+ 📌
+
`;
+}, false);
+```
+
+
+```html
+<{ComponentSelector} [data]="data" [primaryKey]="'ID'" [autoGenerate]="false">
+
+
+
+ {{cell.row.pinned ? 'lock' : 'lock_open'}}
+
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+```typescript
+public togglePinning(row: IgxGridRow, event) {
+ event.preventDefault();
+ if (row.pinned) {
+ row.unpin();
+ } else {
+ row.pin();
+ }
+}
+```
+
+
+```html
+<{ComponentSelector} id="grid" primary-key="ID" auto-generate="false">
+
+
+
+{ComponentSelector}>
+```
+
+```typescript
+constructor() {
+ var grid = document.getElementById('grid') as {ComponentName}Component;
+ var column = document.getElementById('column1') as IgcColumnComponent;
+
+ grid.data = this.data;
+ column.bodyTemplate = this.pinCellTemplate;
+}
+
+public pinCellTemplate = (ctx: IgcCellTemplateContext) => {
+ const row = ctx.cell.row;
+ return html` this.togglePinning(row)}>📌`;
+}
+```
+
+
+
+```tsx
+function cellPinCellTemplate(ctx: IgrCellTemplateContext) {
+ const row = ctx.dataContext.cell.row;
+ return (
+ <>
+ toggleRowPin(row)}>📌
+ >
+ );
+}
+
+<{ComponentSelector} primaryKey="ID" autoGenerate="false">
+
+
+
+{ComponentSelector}>
+```
+
+
+
+
+
+On click of the custom icon the pin state of the related row can be changed using the row's API methods.
```typescript
public togglePinning(index: number) {
@@ -339,6 +453,24 @@ function toggleRowPin(index: number) {
grid.getRowByIndex(index).pinned = !grid.getRowByIndex(index).pinned;
}
```
+
+
+
+On click of the custom icon the pin state of the related row can be changed using the row's API methods.
+
+```typescript
+public togglePinning(row: IgcRowType) {
+ row.pinned = !row.pinned;
+}
+```
+
+
+```tsx
+function toggleRowPin(row: IgrRowType) {
+ row.pinned = !row.pinned;
+}
+```
+
#### Demo
diff --git a/doc/en/components/grids/_shared/row-selection.md b/doc/en/components/grids/_shared/row-selection.md
index 8d9c929d2..11c9ee7bb 100644
--- a/doc/en/components/grids/_shared/row-selection.md
+++ b/doc/en/components/grids/_shared/row-selection.md
@@ -24,7 +24,7 @@ The sample below demonstrates the four types of `{ComponentName}`'s **row select
-The sample below demonstrates the three types of `{ComponentName}`'s **row selection** behavior. Use the buttons below to enable each of the available selection modes. A brief description will be provided on each button interaction through a snackbar message box. Use the switch button to _hide_ or _show_ the row selector checkbox.
+The sample below demonstrates the three types of `{ComponentName}`'s **row selection** behavior. Use the drop-down below to enable each of the available selection modes. Use the checkbox to _hide_ or _show_ the row selector checkboxes.
diff --git a/doc/en/components/grids/_shared/selection.md b/doc/en/components/grids/_shared/selection.md
index 8c916cbda..2aec3ed29 100644
--- a/doc/en/components/grids/_shared/selection.md
+++ b/doc/en/components/grids/_shared/selection.md
@@ -35,9 +35,9 @@ A brief description will be provided on each button interaction through a snackb
## {Platform} {ComponentTitle} Selection Options
-
+
The {ProductName} `{ComponentName}` component provides three different selection modes - [Row selection](row-selection.md), [Cell selection](cell-selection.md) and [Column selection](column-selection.md). By default only **Multi-cell selection** mode is enabled in the `{ComponentName}`. In order to change/enable selection mode you can use `RowSelection`, `CellSelection` or `Selectable` properties.
-
+
### {Platform} {ComponentTitle} Row Selection
@@ -47,11 +47,11 @@ Property `RowSelection` enables you to specify the following options:
- `Single` - Selection of only one row within the `{ComponentName}` would be available.
- `Multiple` - Multi-row selection would be available by using the row selectors, with a key combination like ctrl + click, or by pressing the space key once a cell is focused.
-
+
- `MultipleCascade` - This is a mode for cascading selection, resulting in the selection of all children in the tree below the record that the user selects with user interaction. In this mode a parent's selection state entirely depends on the selection state of its children.
-
+
> Go to [Row selection topic](row-selection.md) for more information.
diff --git a/doc/en/components/grids/_shared/sorting.md b/doc/en/components/grids/_shared/sorting.md
index b5492d7bf..e8fe51568 100644
--- a/doc/en/components/grids/_shared/sorting.md
+++ b/doc/en/components/grids/_shared/sorting.md
@@ -77,6 +77,7 @@ import { SortingDirection } from 'igniteui-webcomponents-grids';
import { SortingDirection } from "igniteui-react-grids";
```
+
```typescript
@@ -135,13 +136,74 @@ gridRef.current.sort([
{ fieldName: 'Price', dir: SortingDirection.Desc }
]);
```
+
+
+
+
+```typescript
+
+// Perform a case insensitive ascending sort on the ProductName column.
+this.hierarchicalGrid.sort({ fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true });
+
+// Perform sorting on both the ProductName and Price columns.
+this.hierarchicalGrid.sort([
+ { fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true },
+ { fieldName: 'Price', dir: SortingDirection.Desc }
+]);
+```
+
+
+
+```typescript
+
+// Perform a case insensitive ascending sort on the ProductName column.
+this.hierarchicalGrid.sort([{ fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true }]);
+
+// Perform sorting on both the ProductName and Price columns.
+this.hierarchicalGrid.sort([
+ { fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true },
+ { fieldName: 'Price', dir: SortingDirection.Desc }
+]);
+```
+
+
+```razor
+@code {
+ this.hierarchicalGrid.SortAsync(new IgbSortingExpression[]
+ {
+ new IgbSortingExpression
+ {
+ FieldName = "CompanyName",
+ Dir = SortingDirection.Asc
+ },
+ new IgbSortingExpression
+ {
+ FieldName = "Country",
+ Dir = SortingDirection.Asc
+ }
+ });
+}
+```
+
+```tsx
+// Perform a case insensitive ascending sort on the ProductName column.
+hierarchicalGridRef.current.sort([{ fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true }]);
+
+// Perform sorting on both the ProductName and Price columns.
+hierarchicalGridRef.current.sort([
+ { fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true },
+ { fieldName: 'Price', dir: SortingDirection.Desc }
+]);
+```
+
> [!Note]
> Sorting is performed using our `DefaultSortingStrategy` algorithm. Any `Column` or `ISortingExpression` can use a custom implementation of the `ISortingStrategy` as a substitute algorithm. This is useful when custom sorting needs to be defined for complex template columns, or image columns, for example.
As with the filtering behavior, you can clear the sorting state by using the `ClearSort` method:
+
```typescript
// Removes the sorting state from the ProductName column
@@ -169,6 +231,37 @@ gridRef.current.clearSort();
this.grid.ClearSortAsync("");
}
```
+
+
+
+
+```typescript
+// Removes the sorting state from the ProductName column
+this.hierarchicalGrid.clearSort('ProductName');
+
+// Removes the sorting state from every column in the {ComponentTitle}
+this.hierarchicalGrid.clearSort();
+```
+
+
+```tsx
+// Removes the sorting state from the ProductName column
+hierarchicalGridRef.current.clearSort('ProductName');
+
+// Removes the sorting state from every column in the {ComponentTitle}
+hierarchicalGridRef.current.clearSort();
+```
+
+```razor
+@code {
+ @*Removes the sorting state from the Title column*@
+ this.hierarchicalGrid.ClearSortAsync("Title");
+
+ @*Removes the sorting state from every column in the Grid*@
+ this.hierarchicalGrid.ClearSortAsync("");
+}
+```
+
> [!Note]
> The `SortStrategy` of the `{ComponentName}` is of different type compared to the `SortStrategy` of the `Column`, since they work in different scopes and expose different parameters.
@@ -180,6 +273,7 @@ gridRef.current.clearSort();
It is possible to set the initial sorting state of the `{ComponentName}` by passing an array of sorting expressions to the `SortingExpressions` property of the `{ComponentName}`.
+
```typescript
public ngOnInit() {
@@ -227,6 +321,57 @@ useEffect(() => {
];
}, [])
```
+
+
+
+
+```typescript
+public ngOnInit() {
+ this.hierarchicalGrid.sortingExpressions = [
+ { fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true },
+ { fieldName: 'Price', dir: SortingDirection.Desc }
+ ];
+}
+```
+
+
+```razor
+@code {
+ protected override void OnAfterRender(bool first)
+ {
+ if (first)
+ {
+ this.hierarchicalGrid.SortingExpressions = new IgbSortingExpression[]{
+ new IgbSortingExpression()
+ {
+ FieldName = "Title",
+ Dir = SortingDirection.Asc
+ }};
+ }
+ }
+}
+```
+
+
+```typescript
+public connectedCallback() {
+ this.hierarchicalGrid.sortingExpressions = [
+ { fieldName: 'ProductName', dir: SortingDirection.Asc, ignoreCase: true },
+ { fieldName: 'Price', dir: SortingDirection.Desc }
+ ];
+}
+```
+
+
+```tsx
+useEffect(() => {
+ hierarchicalGridRef.current.sortingExpressions = [
+ { fieldName: 'UnitsInStock', dir: SortingDirection.Asc, ignoreCase: true },
+ { fieldName: 'ProductName', dir: SortingDirection.Desc }
+ ];
+}, [])
+```
+
> [!Note]
> If values of type `string` are used by a column of `DataType` `Date`, the `{ComponentName}` won't parse them to `Date` objects and using `{ComponentName}` `Sorting` won't work as expected. If you want to use `string` objects, additional logic should be implemented on an application level, in order to parse the values to `Date` objects.
@@ -238,7 +383,6 @@ useEffect(() => {
The `{ComponentName}` supports remote sorting, which is demonstrated in the [{ComponentTitle} Remote Data Operations](remote-data-operations.md) topic.
-
## Sorting Indicators Templates
@@ -254,10 +398,11 @@ The sorting indicator icon in the column header can be customized using a templa
```
-- `SortHeaderIconTemplate` – re-templates the sorting icon when no sorting is applied.
+- `SortHeaderIconTemplate` – re-templates the sorting icon when no sorting is applied.
-
+
+
```razor
<{ComponentSelector} SortHeaderIconTemplate="SortDefaultTemplate">{ComponentSelector}>
@@ -268,8 +413,10 @@ The sorting indicator icon in the column header can be customized using a templa
};
}
```
-
+
+
+
```ts
constructor() {
var grid = this.grid = document.getElementById('grid') as {ComponentName}Component;
@@ -281,7 +428,10 @@ public sortHeaderIconTemplate = (ctx: IgcGridHeaderTemplateContext) => {
return html``;
}
```
+
+
+
```tsx
function sortHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
return (
@@ -291,8 +441,10 @@ function sortHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
);
}
-
+<{ComponentSelector} sortHeaderIconTemplate={sortHeaderIconTemplate}>{ComponentSelector}>
```
+
+
@@ -308,8 +460,8 @@ function sortHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
- `SortAscendingHeaderIconTemplate` – re-templates the sorting icon when the column is sorted in ascending order.
-
-
+
+
```razor
<{ComponentSelector} SortAscendingHeaderIconTemplate="SortAscendingTemplate">{ComponentSelector}>
@@ -320,8 +472,10 @@ function sortHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
};
}
```
-
+
+
+
```ts
constructor() {
var grid = this.grid = document.getElementById('grid') as {ComponentName}Component;
@@ -333,7 +487,10 @@ public sortAscendingHeaderIconTemplate = (ctx: IgcGridHeaderTemplateContext) =>
return html``;
}
```
+
+
+
```tsx
function sortAscendingHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
return (
@@ -343,8 +500,10 @@ function sortAscendingHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
);
}
-
+<{ComponentSelector} sortAscendingHeaderIconTemplate={sortAscendingHeaderIconTemplate}>{ComponentSelector}>
```
+
+
@@ -360,7 +519,8 @@ function sortAscendingHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
- `SortDescendingHeaderIconTemplate` – re-templates the sorting icon when the column is sorted in descending order.
-
+
+
```razor
<{ComponentSelector} SortDescendingHeaderIconTemplate="SortDescendingTemplate">{ComponentSelector}>
@@ -371,8 +531,10 @@ function sortAscendingHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
};
}
```
-
+
+
+
```ts
constructor() {
var grid = this.grid = document.getElementById('grid') as {ComponentName}Component;
@@ -384,7 +546,10 @@ public sortDescendingHeaderIconTemplate = (ctx: IgcGridHeaderTemplateContext) =>
return html``;
}
```
+
+
+
```tsx
function sortDescendingHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
return (
@@ -394,8 +559,10 @@ function sortDescendingHeaderIconTemplate(ctx: IgrGridHeaderTemplateContext) {
);
}
-
+<{ComponentSelector} sortDescendingHeaderIconTemplate={sortDescendingHeaderIconTemplate}>{ComponentSelector}>
```
+
+
diff --git a/doc/en/components/grids/_shared/summaries.md b/doc/en/components/grids/_shared/summaries.md
index c2597e482..bb9dbb9b9 100644
--- a/doc/en/components/grids/_shared/summaries.md
+++ b/doc/en/components/grids/_shared/summaries.md
@@ -42,6 +42,7 @@ All available column data types could be found in the official [Column types top
`{ComponentName}` summaries are enabled per-column by setting `HasSummary` property to **true**. It is also important to keep in mind that the summaries for each column are resolved according to the column data type. In the `{ComponentName}` the default column data type is `string`, so if you want `number` or `date` specific summaries you should specify the `DataType` property as `number` or `date`. Note that the summary values will be displayed localized, according to the grid `Locale` and column `PipeArgs`.
+
```html
<{ComponentSelector} #grid1 [data]="data" [autoGenerate]="false" height="800px" width="800px" (columnInit)="initColumn($event)">
@@ -87,9 +88,76 @@ All available column data types could be found in the official [Column types top
{ComponentSelector}>
```
+
+
+
+
+```html
+<{ComponentSelector} #hierarchicalGrid [data]="data" [autoGenerate]="false" height="800px" width="800px" (columnInit)="initColumn($event)">
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+```razor
+<{ComponentSelector} AutoGenerate="false" Data="SingersData" Name="hierarchicalGrid" @ref="hierarchicalGrid" Id="hierarchicalGrid" PrimaryKey="ID">
+
+
+
+
+
+
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
The other way to enable/disable summaries for a specific column or a list of columns is to use the public method `EnableSummaries`/`DisableSummaries` of the `{ComponentName}`.
+
```html
<{ComponentSelector} #grid [data]="data" [autoGenerate]="false" height="800px" width="800px" (columnInit)="initColumn($event)" >
@@ -185,6 +253,101 @@ function disableSummary() {
```
+
+
+
+
+```html
+<{ComponentSelector} #hierarchicalGrid [data]="data" [autoGenerate]="false" height="800px" width="800px">
+
+
+
+
+
+{ComponentSelector}>
+
+
+```
+
+
+
+```html
+
+
+
+
+
+
+
+
+
+```
+```ts
+constructor() {
+ var hierarchicalGrid = this.hierarchicalGrid = document.getElementById('hierarchicalGrid') as {ComponentName};
+ var enableBtn = this.enableBtn = document.getElementById('enableBtn') as HTMLButtonElement;
+ var disableBtn = this.disableBtn = document.getElementById('disableBtn') as HTMLButtonElement;
+ hierarchicalGrid.data = this.data;
+ enableBtn.addEventListener("click", this.enableSummary);
+ disableBtn.addEventListener("click", this.disableSummary);
+}
+```
+
+
+
+```typescript
+public enableSummary() {
+ this.hierarchicalGrid.enableSummaries([
+ {fieldName: 'GrammyNominations'},
+ {fieldName: 'GrammyAwards'}
+ ]);
+}
+public disableSummary() {
+ this.hierarchicalGrid.disableSummaries(['GrammyNominations']);
+}
+```
+
+
+```razor
+<{ComponentSelector} AutoGenerate="false" Data="SingersData" Name="hierarchicalGrid" @ref="hierarchicalGrid" Id="hierarchicalGrid" PrimaryKey="ID">
+
+
+
+
+
+{ComponentSelector}>
+
+@code {
+ public async void DisableSummaries()
+ {
+ object[] disabledSummaries = { "GrammyNominations" };
+ await this.hierarchicalGrid.DisableSummariesAsync(disabledSummaries);
+ }
+}
+```
+
+```tsx
+function enableSummary() {
+ hierarchicalGridRef.current.enableSummaries([
+ {fieldName: 'GrammyNominations'},
+ {fieldName: 'GrammyAwards'}
+ ]);
+}
+function disableSummary() {
+ hierarchicalGridRef.current.disableSummaries(['GrammyNominations']);
+}
+
+
+
+
+
+
+
+
+
+
+```
+
## Custom {ComponentTitle} Summaries
@@ -298,7 +461,7 @@ See [Custom summaries, which access all data](#custom-summaries-which-access-all
> [!Note]
> In order to calculate the summary row height properly, the {ComponentTitle} needs the `Operate` method to always return an array of `SummaryResult` with the proper length even when the data is empty.
-
+
And now let's add our custom summary to the column `UnitsInStock`. We will achieve that by setting the Summaries` property to the class we create below.
```html
@@ -361,6 +524,67 @@ igRegisterScript("WebGridCustomSummary", (event) => {
}
}, false);
```
+
+
+
+And now let's add our custom summary to the column `GrammyAwards`. We will achieve that by setting the Summaries` property to the class we create below.
+
+```html
+<{ComponentSelector} #hierarchicalGrid [data]="data" [autoGenerate]="false" height="800px" width="800px">
+
+
+
+
+
+{ComponentSelector}>
+```
+
+
+
+```html
+
+
+
+
+
+
+
+```
+```ts
+constructor() {
+ var hierarchicalGrid = this.hierarchicalGrid = document.getElementById('hierarchicalGrid') as {ComponentName};
+ var grammyAwards = this.grammyAwards = document.getElementById('grammyAwards') as IgcColumnComponent;
+ hierarchicalGrid.data = this.data;
+ grammyAwards.summaries = this.mySummary;
+}
+```
+
+
+```typescript
+export class HierarchicalGridComponent implements OnInit {
+ mySummary = MySummary;
+}
+```
+
+```razor
+<{ComponentSelector}
+ AutoGenerate="true"
+ Name="hierarchicalGrid"
+ @ref="hierarchicalGrid"
+ Data="SingersData"
+ PrimaryKey="ID"
+ ColumnInitScript="WebHierarchicalGridCustomSummary">
+{ComponentSelector}>
+
+// In Javascript
+igRegisterScript("WebHierarchicalGridCustomSummary", (event) => {
+ if (event.detail.field === "GrammyAwards") {
+ event.detail.summaries = WebHierarchicalGridSummary;
+ }
+}, false);
+```
+
+
### Custom summaries, which access all data
Now you can access all {ComponentTitle} data inside the custom column summary. Two additional optional parameters are introduced in the SummaryOperand `Operate` method.
@@ -409,6 +633,7 @@ class WebGridDiscontinuedSummary {
}
```
+
`sample="/{ComponentSample}/data-summaries-custom", height="650", alt="{Platform} {ComponentTitle} data summary custom"`
@@ -420,6 +645,11 @@ class WebGridDiscontinuedSummary {
`sample="/{ComponentSample}/data-summary-options", height="650", alt="{Platform} {ComponentTitle} data summary options"`
+
+
+
+`sample="/{ComponentSample}/data-summary-options", height="650", alt="{Platform} {ComponentTitle} data summary options"`
+
@@ -488,14 +718,8 @@ When a default summary is defined, the height of the summary area is calculated
-
-
`sample="/{ComponentSample}/data-summary-template", height="650", alt="{Platform} {ComponentTitle} data summary template"`
-
-
-
-
## Formatting summaries
By default, summary results, produced by the built-in summary operands, are localized and formatted according to the grid `Locale` and column `PipeArgs`. When using custom operands, the `Locale` and `PipeArgs` are not applied. If you want to change the default appearance of the summary results, you may format them using the `SummaryFormatter` property.
@@ -536,20 +760,36 @@ constructor() {
}
```
-
-
```razor
-igRegisterScript("SummaryFormatter", (summary, summaryOperand) => {
- return summary.summaryResult + " rows";
-}, false);
+igRegisterScript("SummaryFormatter", (summary) => {
+ const result = summary.summaryResult;
+ if (summaryOperand instanceof IgcDateSummaryOperand && summary.key !== "count" && result !== null && result !== undefined) {
+ const format = new Intl.DateTimeFormat("en", { year: "numeric" });
+ return format.format(new Date(result));
+ }
+ return result;
+}, true);
```
-`sample="/{ComponentSample}/data-summary-formatter", height="650", alt="{Platform} {ComponentTitle} data summary formatter"`
-
+```tsx
+public summaryFormatter(
+ summary: IgrSummaryResult,
+ summaryOperand: IgrSummaryOperand
+ ): string {
+ const result = summary.summaryResult;
+ if (summary.key !== "count" && result !== null && result !== undefined) {
+ const format = new Intl.DateTimeFormat("en", { year: "numeric" });
+ return format.format(new Date(result));
+ }
+ return result;
+ }
+
+
+```
-
+`sample="/{ComponentSample}/data-summary-formatter", height="650", alt="{Platform} {ComponentTitle} data summary formatter"`
@@ -630,6 +870,7 @@ The summary rows can be navigated with the following keyboard interactions:
In addition to the predefined themes, the grid could be further customized by setting some of the available [CSS properties](../theming.md).
In case you would like to change some of the colors, you need to set a class for the grid first:
+
```html
<{ComponentSelector} class="grid">{ComponentSelector}>
```
@@ -657,7 +898,37 @@ Then set the related CSS properties for that class:
### Demo
`sample="/{ComponentSample}/groupby-summary-styling", height="710", alt="{Platform} {ComponentTitle} groupby summary styling"`
+
+
+
+```html
+<{ComponentSelector} id="hierarchicalGrid">{ComponentSelector}>
+```
+
+```razor
+<{ComponentSelector} id="hierarchicalGrid">{ComponentSelector}>
+```
+
+```tsx
+<{ComponentSelector} id="hierarchicalGrid">
+{ComponentSelector}>
+```
+
+Then set the related CSS properties for that class:
+
+```css
+#hierarchicalGrid {
+ --ig-grid-summary-background-color:#e0f3ff;
+ --ig-grid-summary-focus-background-color: rgba( #94d1f7, .3 );
+ --ig-grid-summary-label-color: rgb(228, 27, 117);
+ --ig-grid-summary-result-color: black;
+}
+```
+
+### Demo
+`sample="/{ComponentSample}/data-summary-options-styling", height="710", alt="{Platform} {ComponentTitle} groupby summary styling"`
+
diff --git a/doc/en/components/grids/_shared/toolbar.md b/doc/en/components/grids/_shared/toolbar.md
index b34313e6d..6b046f285 100644
--- a/doc/en/components/grids/_shared/toolbar.md
+++ b/doc/en/components/grids/_shared/toolbar.md
@@ -18,11 +18,19 @@ The {ProductName} Toolbar in is a container for UI operations in the {Platform}
The toolbar and the predefined UI components support {Platform} events and expose API for developers.
-
+
## {Platform} Toolbar Grid Example
+`sample="/{ComponentSample}/toolbar-sample-1", height="420", alt="{Platform} {ComponentTitle} Toolbar Example"`
+
+
+
+
+## {Platform} Toolbar Grid Example
`sample="/{ComponentSample}/toolbar-sample-1", height="420", alt="{Platform} {ComponentTitle} Toolbar Example"`
+
+
The predefined `Actions` and `Title` UI components are added inside the `GridToolbar` and this is all needed to have a toolbar providing default interactions with the corresponding Grid features:
@@ -59,7 +67,7 @@ The predefined `Actions` and `Title` UI components are added inside the `GridToo
- Grid Toolbar
+ Grid Toolbar
@@ -118,6 +126,7 @@ The predefined `Actions` and `Title` UI components are added inside the `GridToo
```
+
```html
@@ -132,6 +141,11 @@ The predefined `Actions` and `Title` UI components are added inside the `GridToo
```
+
+
+
+
+
```html
@@ -146,6 +160,45 @@ The predefined `Actions` and `Title` UI components are added inside the `GridToo
```
+
+
+
+
+```tsx
+
+
+
+ Hierarchical Grid Toolbar
+
+
+
+
+
+
+
+
+
+```
+
+
+
+
+
+```razor
+
+
+ Hierarchical Grid Toolbar
+
+
+
+
+
+
+
+
+```
+
+
> [!Note]
> As seen in the code snippet above, the predefined `Actions` UI components are wrapped in the `GridToolbarActions` container. This way, the toolbar title is aligned to the left of the toolbar and the actions are aligned to the right of the toolbar.
@@ -196,6 +249,7 @@ Of course, each of these UIs can be added independently of each other, or may no
```
+
```html
@@ -203,6 +257,11 @@ Of course, each of these UIs can be added independently of each other, or may no
```
+
+
+
+
+
```html
@@ -210,13 +269,37 @@ Of course, each of these UIs can be added independently of each other, or may no
```
+
-For a comprehensive look over each of the default UI components, continue reading the **Features** section below.
+
+
+```razor
+
+
+
+
+```
+
+
+
+```tsx
+
+
+
+
+```
+
+
+For a comprehensive look over each of the default UI components, continue reading the **Features** section below.
+
+
+
## Toolbar with Child Grids
+
Due to certain limitations in how the child grids of an IgxHierarchicalGrid are implemented and how DI scope works, there is a caveat when
using the toolbar in the scope of child grids. When defining a toolbar component inside the `igx-row-island` tags, always make sure to use the IgxGridToolbar and pass the provided grid instance as an input property to the toolbar itself.
This will make sure you always have the correct grid instance in the scope of your template:
@@ -236,8 +319,85 @@ This will make sure you always have the correct grid instance in the scope of yo
```
+
+
+
+Due to certain limitations in how the child grids of an `{ComponentSelector}` are implemented and how DI scope works, to define a toolbar component inside the `{RowIslandSelector}`, use the `ToolbarTemplate` input property. This allows child grids to create their own separate toolbar instances:
+
+
+
+
+
+```ts
+constructor() {
+ var rowIsland1 = document.getElementById('rowIsland1') as IgcRowIslandComponent;
+ rowIsland1.toolbarTemplate = this.rowIslandToolbarTemplate;
+}
+
+public rowIslandToolbarTemplate = () => {
+ return html`
+
+
+
+
+
+
+ `;
+}
+```
+
+```html
+
+ ...
+
+
+
+```
+
+```razor
+
+ ...
+
+
+
+
+//In JavaScript:
+igRegisterScript("RowIslandToolbarTemplate", () => {
+ var html = window.igTemplating.html;
+ return html`
+
+
+
+
+
+
+ `;
+}, false);
+```
+
+```tsx
+function rowIslandToolbarTemplate = () => {
+ return (
+
+
+
+
+
+
+
+
+ );
+}
+
+
+ ...
+
+
+
+```
+
## Features
@@ -249,8 +409,15 @@ These features can be enabled independently from each other by following a patte
Listed below are the main features of the toolbar with example code for each of them.
+
`sample="/{ComponentSample}/toolbar-sample-2", height="630", alt="{Platform} {ComponentTitle} toolbar sample 2"`
+
+
+
+`sample="/{ComponentSample}/toolbar-sample-2", height="630", alt="{Platform} {ComponentTitle} toolbar sample 2"`
+
+
### Title
@@ -259,29 +426,47 @@ Setting a title for the toolbar in your grid is achieved by using the `GridToolb
Users can provide anything from simple text to more involved templates.
+
+
```html
Grid toolbar title
```
+
+
+
+
```html
Grid toolbar title
```
+
+
+
+
```tsx
- Grid toolbar title
+
+ Grid toolbar title
+
```
+
+
+
+
```razor
Grid toolbar title
```
+
+
### Actions
@@ -290,6 +475,8 @@ The `GridToolbarActions` is where users can place actions/interactions in relati
As with the title portion of the toolbar, users can provide anything inside that template part, including the default
toolbar interaction components.
+
+
```html
@@ -299,15 +486,11 @@ toolbar interaction components.
```
+
+
-```razor
-
-
-
-
-
-```
-
+
+
```html
@@ -315,15 +498,33 @@ toolbar interaction components.
```
+
+
+
+
+```razor
+
+
+
+
+
+```
+
+
+
+
+
```tsx
-
```
+
+
+
Each action now exposes a way to change the overlay settings of the actions dialog by using the `OverlaySettings` input. For example:
@@ -386,6 +587,8 @@ The `GridToolbarPinning` component provides the default UI for interacting with
The component is setup to work out of the box with the parent grid containing the toolbar as well as several input properties for customizing the UI, such as the component title, the placeholder for the component input and the height of the dropdown itself.
+
+
```html
@@ -398,15 +601,11 @@ The component is setup to work out of the box with the parent grid containing th
```
+
+
-```razor
-
-
-
-
-
-```
-
+
+
```html
@@ -418,7 +617,23 @@ The component is setup to work out of the box with the parent grid containing th
```
+
+
+
+
+
+```razor
+
+
+
+
+
+```
+
+
+
+
```tsx
@@ -426,12 +641,16 @@ The component is setup to work out of the box with the parent grid containing th
```
+
+
### Column Hiding
The `GridToolbarHiding` provides the default UI for interacting with column hiding. Exposes the same input properties for customizing the UI, such as the component
title, the placeholder for the component input and the height of the dropdown itself.
+
+
```html
@@ -444,15 +663,11 @@ title, the placeholder for the component input and the height of the dropdown it
```
+
+
-```razor
-
-
-
-
-
-```
-
+
+
```html
@@ -464,7 +679,23 @@ title, the placeholder for the component input and the height of the dropdown it
```
+
+
+
+
+
+```razor
+
+
+
+
+
+```
+
+
+
+
```tsx
@@ -472,11 +703,15 @@ title, the placeholder for the component input and the height of the dropdown it
```
+
+
### Advanced Filtering
Toolbar Advanced Filtering component provides the default UI for the Advanced Filtering feature. The component exposes a way to change the default text of the button.
+
+
```html
@@ -484,15 +719,11 @@ Toolbar Advanced Filtering component provides the default UI for the Advanced Fi
```
+
+
-```razor
-
-
-
-
-
-```
-
+
+
```html
@@ -500,7 +731,23 @@ Toolbar Advanced Filtering component provides the default UI for the Advanced Fi
```
+
+
+
+
+```razor
+
+
+
+
+
+```
+
+
+
+
+
```tsx
@@ -508,6 +755,8 @@ Toolbar Advanced Filtering component provides the default UI for the Advanced Fi
```
+
+
### Data Exporting
@@ -550,6 +799,8 @@ These range from changing the display text, to enabling/disabling options in the
Here is a snippet showing some of the options which can be customized through the {Platform} template:
+
+
```html
@@ -566,15 +817,11 @@ Here is a snippet showing some of the options which can be customized through th
```
+
+
-```razor
-
-
-
-
-
-```
-
+
+
```html
@@ -583,7 +830,23 @@ Here is a snippet showing some of the options which can be customized through th
```
+
+
+
+
+
+```razor
+
+
+
+
+
+```
+
+
+
+
```tsx
@@ -591,6 +854,8 @@ Here is a snippet showing some of the options which can be customized through th
```
+
+
In addition to changing the exported filename, the user can further configure the exporter options by waiting for the `ToolbarExporting` event and customizing the options entry in the event properties.
@@ -601,6 +866,8 @@ In addition to changing the exported filename, the user can further configure th
The following code snippet demonstrates subscribing to the toolbar exporting event and configuring the exporter options:
+
+
```html
<{ComponentSelector} (toolbarExporting)="configureExport($event)" >{ComponentSelector}>
@@ -691,6 +958,64 @@ igRegisterScript("WebGridToolbarExporting", (evt) => {
});
}, false);
```
+
+
+
+
+
+
+```html
+<{ComponentSelector} id="hierarchicalGrid">{ComponentSelector}>
+```
+```ts
+constructor() {
+ var hierarchicalGrid = document.getElementById('hierarchicalGrid') as IgcHierarchicalGridComponent;
+ hierarchicalGrid.addEventListener("toolbarExporting", this.configureExport);
+}
+
+public configureExport(evt: CustomEvent) {
+ const args = evt.detail;
+ const options: IgcExporterOptionsBase = args.options;
+ if (options) {
+ options.fileName = `Report_${new Date().toDateString()}`;
+ (args.exporter as any).columnExporting.subscribe((columnArgs: any) => {
+ columnArgs.cancel = columnArgs.header === 'Photo';
+ });
+ }
+}
+```
+
+
+```tsx
+function configureExport(evt: IgrGridToolbarExportEventArgs) {
+ const args = evt.detail;
+ const options: IgrExporterOptionsBase = args.options;
+
+ options.fileName = `Report_${new Date().toDateString()}`;
+ (args.exporter as any).columnExporting.subscribe((columnArgs: any) => {
+ columnArgs.cancel = columnArgs.header === 'Photo';
+ });
+}
+
+<{ComponentSelector} toolbarExporting={configureExport}>
+{ComponentSelector}>
+```
+
+```razor
+<{ComponentSelector} ToolbarExportingScript="ConfigureExport">{ComponentSelector}>
+
+// In Javascript
+igRegisterScript("ConfigureExport", (evt) => {
+ const args = evt.detail;
+ const options = args.options;
+ options.fileName = `Report_${new Date().toDateString()}`;
+ args.exporter.columnExporting.subscribe((columnArgs) => {
+ columnArgs.cancel = columnArgs.header === 'Photo';
+ });
+}, false);
+```
+
+
The following sample demonstrates how to customize the exported files:
@@ -698,7 +1023,6 @@ The following sample demonstrates how to customize the exported files:
-
## Exporting Indicator
@@ -713,17 +1037,22 @@ The sample belows uses has significant amount of data, in order to increase the
`sample="/{ComponentSample}/data-exporting-indicator", height="370", alt="{Platform} {ComponentTitle} data exporting indicator"`
-
+
## Custom Content
+
+
> [!Note]
> This replaces the old toolbar template directive. If you are migrating from a version before v11 our migrations will handle the moving of the template content. However, we do not handle the bindings in the template, so make sure to double check the modified template files after the migration completes.
+
+
If the actions part of the toolbar component is not sufficient for a particular use case, the toolbar itself has a general content projection where users can provide additional UI. If the user needs the respective grid instance for API calls or bindings, they can create a template reference variable.
Here is a sample snippet:
+
```html
<{ComponentSelector} #gridRef>
@@ -742,9 +1071,11 @@ Here is a sample snippet:
{ComponentSelector}>
```
+
+
```html
<{ComponentSelector} id="grid">
@@ -758,13 +1089,52 @@ Here is a sample snippet:
{ComponentSelector}>
```
+
+
+
+```tsx
+<{ComponentSelector}>
+
+
+ title
+
+ {/*
+ Everything between the toolbar tags except the default toolbar components
+ will be projected as custom content.
+ */}
+
+
+
+{ComponentSelector}>
+```
+
+
+
+
+
+```razor
+<{ComponentSelector}>
+
+ title
+ @*
+ Everything between the toolbar tags except the default toolbar components
+ will be projected as custom content.
+ *@
+
+
+
+{ComponentSelector}>
+```
+
+
+
The following sample demonstrates how to add an additional button to the toolbar to clear the sorting set by clicking on the columns' headers:
`sample="/{ComponentSample}/toolbar-sample-4", height="420", alt="{Platform} {ComponentTitle} toolbar sample 4"`
-
+
@@ -920,6 +1290,15 @@ The last step is to **include** the newly created themes.
+
+
+## Known Limitations
+
+> [!Note]
+> Currently, defining a toolbar component inside the {RowIslandSelector} is not supported.
+
+
+
## API References
The Grid Toolbar service has a few more APIs to explore, which are listed below.
diff --git a/doc/en/components/grids/grid/master-detail.md b/doc/en/components/grids/grid/master-detail.md
index d3fb4d8f6..b27a8b40c 100644
--- a/doc/en/components/grids/grid/master-detail.md
+++ b/doc/en/components/grids/grid/master-detail.md
@@ -1,5 +1,5 @@
---
-title: {Platform} {ComponentTitle} Master-Detail Grid - Infragistics
+title: {Platform} Master-Detail Grid - Infragistics
_description: Define expandable detail view template for data in rows with Ignite UI {Platform} Grid. Useful for displaying master-detail style data in a hierarchical structure.
_keywords: {Platform}, {ComponentKeywords}, {ProductName}, master detail, Infragistics
mentionedTypes: ['Infragistics.Controls.Grid']
diff --git a/doc/en/components/grids/grid/paste-excel.md b/doc/en/components/grids/grid/paste-excel.md
index 17bd900a6..199c9708d 100644
--- a/doc/en/components/grids/grid/paste-excel.md
+++ b/doc/en/components/grids/grid/paste-excel.md
@@ -23,25 +23,393 @@ On the top there is a dropdown button with 2 options:
The new data after the paste is decorated in Italic.
-`sample="/{GridSample}/data-paste-options", height="570", alt="{Platform} Paste from Excel Example"`
+`sample="/{GridSample}/paste", height="570", alt="{Platform} Paste from Excel Example"`
-
+
## Usage
-You should add the `paste-handler` directive (you can find its code in the next section) to the `Grid` and handle its `onDataProcessed` event. The `onDataProcessed` event has one parameter that gives you access to the Excel data in the form of an array. For reference see the `addRecords` and `updateRecords` methods.
+
+You should first bind to the grid's `rendered` event to create and manage a text area element:
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
```html
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
```
+```ts
+public webGridPasteFromExcel() {
+ const grid = document.getElementById("grid") as any;
+ this.onKeyDown = this.onKeyDown.bind(this);
+ grid.addEventListener("keydown", this.onKeyDown);
+}
+public onKeyDown(eventArgs: any): void {
+ const ctrl = eventArgs.ctrlKey;
+ const key = eventArgs.keyCode;
+ // Ctrl-V || Shift-Ins || Cmd-V
+ if ((ctrl || eventArgs.metaKey) && key === 86 || eventArgs.shiftKey && key === 45) {
+ this.textArea.focus();
+ }
+}
+
+private txtArea: any;
+
+public get textArea() {
+ if(!this.txtArea) {
+ const div = document.createElement("div");
+ const divStyle = div.style;
+ divStyle.position = "fixed";
+ document.body.appendChild(div);
+ this.txtArea = document.createElement("textarea");
+ const style = this.txtArea.style;
+ style.opacity = "0";
+ style.height = "0px";
+ style.width = "0px";
+ style.overflow = "hidden";
+ div.appendChild(this.txtArea);
+
+ this.txtArea.addEventListener("paste", (eventArgs: any) => { this.onPaste(eventArgs); });
+ }
+ return this.txtArea;
+ }
+```
+
+```razor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// In JavaScript
+igRegisterScript("WebGridPasteFromExcel", (evtArgs) => {
+ const grid = document.getElementById("grid");
+ grid.addEventListener("keydown", onWebGridPasteFromExcelKeyDown);
+}, false);
+
+function onWebGridPasteFromExcelKeyDown(eventArgs) {
+ const ctrl = eventArgs.ctrlKey;
+ const key = eventArgs.keyCode;
+ // Ctrl-V || Shift-Ins || Cmd-V
+ if ((ctrl || eventArgs.metaKey) && key === 86 || eventArgs.shiftKey && key === 45) {
+ textArea.focus();
+ }
+}
+
+var txtArea;
+var textArea = getTextArea();
+function getTextArea() {
+ if(!txtArea) {
+ const div = document.createElement("div");
+ const divStyle = div.style;
+ divStyle.position = "fixed";
+ document.body.appendChild(div);
+ txtArea = document.createElement("textarea");
+ const style = txtArea.style;
+ style.opacity = "0";
+ style.height = "0px";
+ style.width = "0px";
+ style.overflow = "hidden";
+ div.appendChild(txtArea);
+
+ txtArea.addEventListener("paste", (eventArgs) => { onPaste(eventArgs); });
+ }
+ return txtArea;
+}
+
+```
+
+The code creates a DOM textarea element which is used to receive the pasted data from the clipboard. When the data is pasted in the textarea the code parses it into an array.
+
+```ts
+public onPaste(eventArgs: any) {
+ let data;
+ const clData: any = "clipboardData";
+
+ // get clipboard data - from window.cliboardData for IE or from the original event's arguments.
+ if (window[clData] as any) {
+ (window.event as any).returnValue = false;
+ data = (window[clData] as any).getData("text");
+ } else {
+ data = eventArgs[clData].getData("text/plain");
+ }
+
+ // process the clipboard data
+ const processedData = this.processData(data);
+ if (this.pasteMode === "Paste data as new records") {
+ this.addRecords(processedData);
+ } else {
+ this.updateRecords(processedData);
+ }
+}
+
+public processData(data: any) {
+ const pasteData = data.split("\n");
+ for (let i = 0; i < pasteData.length; i++) {
+ pasteData[i] = pasteData[i].split("\t");
+ // Check if last row is a dummy row
+ if (pasteData[pasteData.length - 1].length === 1 && pasteData[pasteData.length - 1][0] === "") {
+ pasteData.pop();
+ }
+ // remove empty data
+ if (pasteData.length === 1 &&
+ pasteData[0].length === 1 &&
+ (pasteData[0][0] === "" || pasteData[0][0] === "\r")) {
+ pasteData.pop();
+ }
+ }
+ return pasteData;
+}
+```
+
+```razor
+function onPaste(eventArgs) {
+ let data;
+ const clData = "clipboardData";
+
+ // get clipboard data - from window.cliboardData for IE or from the original event's arguments.
+ if (window[clData]) {
+ window.event.returnValue = false;
+ data = window[clData].getData("text");
+ } else {
+ data = eventArgs[clData].getData("text/plain");
+ }
+
+ // process the clipboard data
+ const processedData = processData(data);
+ if (pasteMode === "Paste data as new records") {
+ addRecords(processedData);
+ } else {
+ updateRecords(processedData);
+ }
+}
+function processData(data) {
+ const pasteData = data.split("\n");
+ for (let i = 0; i < pasteData.length; i++) {
+ pasteData[i] = pasteData[i].split("\t");
+ // Check if last row is a dummy row
+ if (pasteData[pasteData.length - 1].length === 1 && pasteData[pasteData.length - 1][0] === "") {
+ pasteData.pop();
+ }
+ // remove empty data
+ if (pasteData.length === 1 &&
+ pasteData[0].length === 1 &&
+ (pasteData[0][0] === "" || pasteData[0][0] === "\r")) {
+ pasteData.pop();
+ }
+ }
+ return pasteData;
+}
+```
+
+The pasted data can then be added as new records or used to update the existing records based on the user selection.
+For reference see the addRecords and updateRecords methods.
+
+```ts
+public addRecords(processedData: any[]) {
+ const grid = this.grid as any;
+ const columns = grid.visibleColumns;
+ const pk = grid.primaryKey;
+ const addedData: any[] = [];
+ for (const curentDataRow of processedData) {
+ const rowData = {} as any;
+ for (const col of columns) {
+ const index = columns.indexOf(col);
+ rowData[col.field] = curentDataRow[index];
+ }
+ // generate PK
+ rowData[pk] = grid.data.length + 1;
+ grid.addRow(rowData);
+ addedData.push(rowData);
+ }
+ // scroll to last added row
+ grid.navigateTo(grid.data.length - 1, 0, () => {
+ this.clearStyles();
+ for (const data of addedData) {
+ const row = grid.getRowByKey(data[pk]);
+ if (row) {
+ const rowNative = this.getNative(row) as any;
+ if (rowNative) {
+ rowNative.style["font-style"] = "italic";
+ rowNative.style.color = "gray";
+ }
+ }
+ }
+ });
+}
+
+public updateRecords(processedData: any[]) {
+ const grid = this.grid as any;
+ const cell = grid.selectedCells[0];
+ const pk = grid.primaryKey;
+ if (!cell) { return; }
+ const rowIndex = cell.row.index;
+ const columns = grid.visibleColumns;
+ const cellIndex = grid.visibleColumns.indexOf(cell.column);
+ let index = 0;
+ const updatedRecsPK: any[] = [];
+ for (const curentDataRow of processedData) {
+ const rowData = {} as any;
+ const dataRec = grid.data[rowIndex + index];
+ const rowPkValue = dataRec ? dataRec[pk] : grid.data.length + 1;
+ rowData[pk] = rowPkValue;
+ for (let j = 0; j < columns.length; j++) {
+ let currentCell;
+ if (j >= cellIndex) {
+ currentCell = curentDataRow.shift();
+ }
+ const colKey = columns[j].field;
+ rowData[colKey] = currentCell || (dataRec ? dataRec[colKey] : null);
+ }
+ if (!dataRec) {
+ // no rec to update, add instead
+ rowData[pk] = rowPkValue;
+ grid.addRow(rowData);
+ continue;
+ }
+ grid.updateRow(rowData, rowPkValue);
+ updatedRecsPK.push(rowPkValue);
+ index++;
+ }
+
+ this.clearStyles();
+ for (const pkVal of updatedRecsPK) {
+ const row = grid.getRowByKey(pkVal);
+ if (row) {
+ const rowNative = this.getNative(row) as any;
+ if (rowNative) {
+ rowNative.style["font-style"] = "italic";
+ rowNative.style.color = "gray";
+ }
+ }
+ }
+}
+```
+
+```razor
+function addRecords(processedData) {
+ const grid = document.getElementById("grid");
+ const columns = grid.visibleColumns;
+ const pk = grid.primaryKey;
+ const addedData = [];
+ for (const curentDataRow of processedData) {
+ const rowData = {};
+ for (const col of columns) {
+ const index = columns.indexOf(col);
+ rowData[col.field] = curentDataRow[index];
+ }
+ // generate PK
+ rowData[pk] = grid.data.length + 1;
+ grid.addRow(rowData);
+ addedData.push(rowData);
+ }
+ // scroll to last added row
+ grid.navigateTo(grid.data.length - 1, 0, () => {
+ clearStyles();
+ for (const data of addedData) {
+ const row = grid.getRowByKey(data[pk]);
+ if (row) {
+ const rowNative = getNative(row);
+ if (rowNative) {
+ rowNative.style["font-style"] = "italic";
+ rowNative.style.color = "gray";
+ }
+ }
+ }
+ });
+}
+
+function updateRecords(processedData) {
+ const grid = document.getElementById("grid");
+ const cell = grid.selectedCells[0];
+ const pk = grid.primaryKey;
+ if (!cell) { return; }
+ const rowIndex = cell.row.index;
+ const columns = grid.visibleColumns;
+ const cellIndex = grid.visibleColumns.indexOf(cell.column);
+ let index = 0;
+ const updatedRecsPK = [];
+ for (const curentDataRow of processedData) {
+ const rowData = {};
+ const dataRec = grid.data[rowIndex + index];
+ const rowPkValue = dataRec ? dataRec[pk] : grid.data.length + 1;
+ rowData[pk] = rowPkValue;
+ for (let j = 0; j < columns.length; j++) {
+ let currentCell;
+ if (j >= cellIndex) {
+ currentCell = curentDataRow.shift();
+ }
+ const colKey = columns[j].field;
+ rowData[colKey] = currentCell || (dataRec ? dataRec[colKey] : null);
+ }
+ if (!dataRec) {
+ // no rec to update, add instead
+ rowData[pk] = rowPkValue;
+ grid.addRow(rowData);
+ continue;
+ }
+ grid.updateRow(rowData, rowPkValue);
+ updatedRecsPK.push(rowPkValue);
+ index++;
+ }
+```
+
+
+
+
+
+## Usage
+
+You should add the `paste-handler` directive (you can find its code in the next section) to the `Grid` and handle its `onDataProcessed` event. The `onDataProcessed` event has one parameter that gives you access to the Excel data in the form of an array. For reference see the `addRecords` and `updateRecords` methods.
+
+```html
+
+
+
+
+
+
+```
+
```typescript
public dataPasted(processedData) {
if (this.pasteMode === "Paste data as new records") {
@@ -132,7 +500,6 @@ You should add the `paste-handler` directive (you can find its code in the next
}
}
```
-
## Paste Handler Directive
@@ -216,15 +583,15 @@ export class PasteHandler {
}
```
+
+
## API References
-* `GridComponent`
+* `Grid`
## Additional Resources
-
* [Excel Exporter](export-excel.md) - Use the Excel Exporter service to export data to Excel from Grid. It also provides the option to only export the selected data from the Grid. The exporting functionality is encapsulated in the ExcelExporterService class and the data is exported in MS Excel table format. This format allows features like filtering, sorting, etc. To do this you need to invoke the ExcelExporterService's export method and pass the Grid component as first argument.
-
Our community is active and always welcoming to new ideas.
* [{ProductName} **Forums**]({ForumsLink})
diff --git a/doc/en/components/grids/hierarchical-grid/load-on-demand.md b/doc/en/components/grids/hierarchical-grid/load-on-demand.md
new file mode 100644
index 000000000..2de0d97ca
--- /dev/null
+++ b/doc/en/components/grids/hierarchical-grid/load-on-demand.md
@@ -0,0 +1,897 @@
+---
+title: {Platform} Hierarchical Grid | Fastest {Platform} Hierarchical Table | Infragistics
+_description: The {ProductName} Hierarchical Grid provides the necessary tools to load data on demand for each child grid that is expanded. That way the volume of data would be greatly reduced and can be retrieved only when the user needs it.
+_keywords: {Platform} hierarchical grid, igniteui for {Platform}, infragistics
+mentionedTypes: [{ComponentApiMembers}]
+namespace: Infragistics.Controls
+---
+
+# Hierarchical Grid Load On Demand
+
+The Ignite UI for {Platform} `HierarchicalGrid` allows fast rendering by requesting the minimum amount of data to be retrieved from the server so that the user can see the result in view and interact with the visible data as quickly as possible. Initially only the root grid’s data is retrieved and rendered, only after the user expands a row containing a child grid, he will receive the data for that particular child grid. This mechanism, also known as Load on Demand, can be easily configured to work with any remote data.
+
+This topic demonstrates how to configure Load on Demand by creating a Remote Service Provider that communicates with an already available remote service. Here's the working demo and later we will go through it step by step and describe the process of creating it.
+
+## {Platform} Hierarchical Grid Load On Demand Example
+
+`sample="/{HierarchicalGridSample}/data-performance-virtualization", height="700", alt="{Platform} Hierarchical Grid Load On Demand Example"`
+
+### Remote Service Provider
+
+First we will prepare our service provider so we will be ready to get the data we would need for the hierarchical grid.
+
+#### Getting basic data
+
+
+We will be communicating with our backend service over HTTP protocol using the XMLHttpRequest interface the browsers provide. In order to achieve this more easily we will use Angular's [`HttpClient`](https://angular.io/api/common/http/HttpClient) module that offers a simplified client HTTP API. That way in order to get our data we will need this simple method in our service:
+
+```typescript
+public getData(dataState): Observable {
+ return this.http.get(this.buildUrl(dataState)).pipe(
+ map(response => response),
+ );
+}
+```
+
+As you can see `this.http` will be a reference to our `HttpCLient` module, and `buildUrl()` will be the method that will generate our url based on the data that we have received. We map our response and return an Observable, since this is executed asynchronously. That way we can later subscribe to it, process it further in our application and pass it to our grid.
+
+
+
+We will be communicating with our backend service over HTTP protocol using the [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) global function the browsers provide. That way in order to get our data we will need this simple method in our service:
+
+```ts
+export function getData(dataState: any): any {
+ return fetch(buildUrl(dataState))
+ .then((result) => result.json());
+}
+```
+
+As you can see `buildUrl()` will be the method that will generate our url based on the data that we have received. We return a Promise, since this is executed asynchronously. That way we can later subscribe to it, process it further in our application and pass it to our grid.
+
+
+
+We will be communicating with our backend service over HTTP protocol using the [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) global function the browsers provide. That way in order to get our data we will need this simple method in our service:
+
+```razor
+function getData(dataState) {
+ return fetch(buildUrl(dataState))
+ .then((result) => result.json());
+}
+```
+
+As you can see `buildUrl()` will be the method that will generate our url based on the data that we have received. We return a Promise, since this is executed asynchronously. That way we can later subscribe to it, process it further in our application and pass it to our grid.
+
+
+#### Building our request url
+
+Next we will define how we should build our URL for the GET request. This is where we will be able to get the data for our main grid but also for any child grid inside it. We will use the `Customers` data from [here](https://data-northwind.indigo.design/swagger/index.html) for our root level and use `Orders` and `Details` for the lower levels. The model will differ per application but we will use the following one:
+
+
+
+What we first need is the `key` of our table to determine from where to get the data for the desired grid, the primary key of the parent row and its unique ID.
+
+
+We will define all this in an interface called `IDataState`. An example:
+
+```typescript
+export interface IDataState {
+ key: string;
+ parentID: any;
+ parentKey: string;
+ rootLevel: boolean;
+}
+
+//...
+public buildUrl(dataState: IDataState): string {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${this.url}${qS}`;
+}
+//...
+```
+
+
+
+We will define all this in the `dataState` object. An example:
+
+```ts
+const dataState: {
+ key: string;
+ parentID: any;
+ parentKey: string;
+ rootLevel: boolean;
+} = {
+ //...
+};
+
+function buildUrl(dataState: any) {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${URL}${qS}`;
+}
+```
+
+
+
+We will define all this in the `dataState` object. An example:
+
+```razor
+const dataState: {
+ key: string;
+ parentID: any;
+ parentKey: string;
+ rootLevel: boolean;
+} = {
+ //...
+};
+
+function buildUrl(dataState) {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${DATA_URL}${qS}`;
+}
+```
+
+
+#### Result
+
+
+Finally, this is how our `remote-lod.service.ts` would look like:
+
+```typescript
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+export interface IDataState {
+ key: string;
+ parentID: any;
+ parentKey: string;
+ rootLevel: boolean;
+}
+
+@Injectable()
+export class RemoteLoDService {
+ public url = `https://data-northwind.indigo.design/`;
+
+ constructor(private http: HttpClient) { }
+
+ public getData(dataState: IDataState): Observable {
+ return this.http.get(this.buildUrl(dataState)).pipe(
+ map((response) => response)
+ );
+ }
+
+ public buildUrl(dataState: IDataState): string {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${this.url}${qS}`;
+ }
+}
+```
+
+
+
+Finally, this is how our remote service would look like:
+
+```ts
+const URL = `https://data-northwind.indigo.design/`;
+
+export function getData(dataState: any): any {
+ return fetch(buildUrl(dataState))
+ .then((result) => result.json());
+}
+
+function buildUrl(dataState: any) {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${URL}${qS}`;
+}
+```
+
+
+
+Finally, this is how our remote service would look like:
+
+```razor
+const DATA_URL = `https://data-northwind.indigo.design/`;
+
+function getData(dataState) {
+ return fetch(buildUrl(dataState))
+ .then((result) => result.json());
+}
+
+function buildUrl(dataState) {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${DATA_URL}${qS}`;
+}
+```
+
+
+### Hierarchical Grid Setup
+
+Next we will setup our hierarchical grid and connect it to our remote service provider.
+
+#### Template defining
+
+First we will define our hierarchical grid template with the levels of hierarchy that we expect to have. We know that our root grid `PrimaryKey` for the customers is their `customerId`, for their orders on the first level - `orderId` and respectively for order details - `productId`. Knowing each database table and their keys allows us to define our initial template:
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+```razor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+There is one thing missing in our template though, and that is the data for our root level hierarchical grid, and eventually its children.
+
+
+We will easily set the data of the root grid after getting its data from the service in our code later, since we can use the `#hGrid` reference.
+
+
+
+We will easily set the data of the root grid after getting its data from the service in our code later, since we can use the `id="hGrid"` reference.
+
+
+
+We will easily set the data of the root grid after getting its data from the service in our code later, since we can use the `ref={hierarchicalGrid}` reference.
+
+
+
+We will easily set the data of the root grid after getting its data from the service in our code later, since we can use the `Id="hGrid"` reference.
+
+
+Setting the data for any child that has been expanded is a bit different. When a row is expanded for the first time, a new child `HierarchicalGrid` is rendered for it and we need to get the reference for the newly created grid to set its data. That is why each `RowIsland` component provides the `GridCreated` event that is fired when a new child grid is created for that specific row island. We can use that to get the reference we need for the new grid, request its data from the service, and apply it.
+
+We can use one method for all row islands since we built our service so that it needs only information if it is the root level, the key of the row island, the primary key of the parent row, and its unique identifier. All this information can be accessed either directly from the event arguments, or from the row island responsible for triggering the event.
+
+
+Let's name the method that we will use `gridCreated`.
+
+
+
+Let's name the method that we will use `OnGridCreated`.
+
+
+
+Since the `GridCreated` event provides the `parentID` property, a reference to the row island as `owner` and the new child `grid` property, it will be passed as the first argument. We are only missing information about the parent row's `primaryKey`, but we can easily pass that as a second argument, depending on which row island we bind.
+
+
+
+Since the `GridCreated` event provides a reference to the row island, the `parentID` property, and the new child `grid` property, this will be passed as the first and second arguments. We are only missing information about the parent row's `primaryKey`, but we can easily pass that as a third argument, depending on which row island we bind.
+
+
+
+Since the `GridCreated` event provides the `parentID` property, a reference to the row island as `owner` and the new child `grid` property, it will be passed as the first argument. We are only missing information about the parent row's `primaryKey`, but we can easily determine that based on the row island `ChildDataKey`.
+
+
+The template file, with these changes added, would look like this:
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+```ts
+constructor() {
+ const ordersRowIsland = document.getElementById("ordersRowIsland");
+ const orderDetailsRowIsland = document.getElementById("orderDetailsRowIsland");
+
+ ordersRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Customers");
+ });
+
+ orderDetailsRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Orders");
+ });
+}
+```
+
+
+
+```tsx
+
+
+
+
+
+
+
+ gridCreated(rowIsland, e, "Customers")}
+ >
+
+
+
+
+
+ gridCreated(rowIsland, e, "Orders")}
+ >
+
+
+
+
+
+
+
+```
+
+
+
+```razor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+
+#### Connecting our service
+
+One of our final steps now will be to connect our previously created service to our hierarchical grid.
+
+
+Since we defined it as an `Injectable`, we can pass it as a provider to our application. We will get a reference to our root grid as well, by using `ViewChild` query to set its data:
+
+```typescript
+@Component({
+ providers: [RemoteLoDService],
+ selector: "app-hierarchical-grid-lod",
+ styleUrls: ["./hierarchical-grid-lod.component.scss"],
+ templateUrl: "./hierarchical-grid-lod.component.html"
+})
+export class HierarchicalGridLoDSampleComponent {
+ @ViewChild("hGrid")
+ public hGrid: IgxHierarchicalGridComponent;
+
+ constructor(private remoteService: RemoteLoDService) { }
+}
+```
+
+In order to make sure that our grid is rendered before we request its data from the service and assign it, we will use the `AfterViewInit` lifecycle hook. As it doesn't have any parents we can only pass that `rootLevel` is **true**, and the key for it, to the `getData` of our service. Since it returns an observable we will need to subscribe to it:
+
+```typescript
+public ngAfterViewInit() {
+ this.remoteService.getData({ parentID: null, rootLevel: true, key: "Customers" }).subscribe((data) => {
+ this.hGrid.data = data;
+ this.hGrid.cdr.detectChanges();
+ });
+}
+```
+
+
+
+We will get a reference to our root grid to set its data. As it doesn't have any parents we can only pass that `rootLevel` is **true**, and the key for it, to the `getData` of our service. Since it returns a Promise we will need to subscribe to it:
+
+```ts
+constructor() {
+ const hierarchicalGrid = document.getElementById("hGrid") as IgcHierarchicalGridComponent;
+
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then((data: any) => {
+ hierarchicalGrid.data = data;
+ hierarchicalGrid.markForCheck();
+ });
+}
+```
+
+
+
+We will get a reference to our root grid via the `useRef` React hook to set its data:
+
+```tsx
+const hierarchicalGrid = useRef(null);
+```
+
+In order to make sure that our grid is rendered before we request its data from the service and assign it, we will use the `useEffect` React hook. As it doesn't have any parents we can only pass that `rootLevel` is **true**, and the key for it, to the `getData` of our service. Since it returns a Promise we will need to subscribe to it:
+
+```tsx
+useEffect(() => {
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
+ (data: any) => {
+ hierarchicalGrid.current.data = data;
+ hierarchicalGrid.current.markForCheck();
+ }
+ );
+}, []);
+```
+
+
+
+We will get a reference to our root grid to set its data. In order to make sure that our grid is rendered before we request its data from the service and assign it, we will use the `Rendered` event. As it doesn't have any parents we can only pass that `rootLevel` is **true**, and the key for it, to the `getData` of our service. Since it returns a Promise we will need to subscribe to it:
+
+```razor
+igRegisterScript("OnGridRendered", () => {
+ const grid = document.getElementById("hGrid");
+
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
+ (data) => {
+ grid.data = data;
+ grid.markForCheck();
+ });
+}, false)
+```
+
+
+
+Next, we only need to create our `gridCreated` method that will request data for any new child grid created.
+
+
+
+Next, we only need to create our `OnGridCreated` method that will request data for any new child grid created.
+
+
+It will be similar to getting the root level grid data, just this time we will need to pass more information, like `parentID` and `parentKey`. `rootLevel` will be **false** for any child:
+
+
+```typescript
+public gridCreated(event: IGridCreatedEventArgs, _parentKey: string) {
+ const dataState = {
+ key: event.owner.key,
+ parentID: event.parentID,
+ parentKey: _parentKey,
+ rootLevel: false
+ };
+ this.remoteService.getData(dataState).subscribe(
+ (data) => {
+ event.grid.data = data;
+ event.grid.cdr.detectChanges();
+ }
+ );
+}
+```
+
+
+
+```ts
+public gridCreated(event: CustomEvent, _parentKey: string) {
+ const context = event.detail;
+ const dataState = {
+ key: context.owner.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false
+ };
+
+ getData(dataState).then((data: any[]) => {
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+}
+```
+
+
+
+```tsx
+function gridCreated(rowIsland: IgrRowIsland, event: IgrGridCreatedEventArgs, _parentKey: string) {
+ const context = event.detail;
+ const dataState = {
+ key: rowIsland.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false,
+ };
+
+ getData(dataState).then((data: any[]) => {
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+}
+```
+
+
+
+```razor
+igRegisterScript("OnGridCreated", (args) => {
+ const context = args.detail;
+ const _parentKey = context.owner.childDataKey === "Orders" ? "Customers" : "Orders";
+ const dataState = {
+ key: context.owner.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false,
+ };
+
+ getData(dataState).then((data) => {
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+}, false)
+```
+
+
+With this, the setup of our application is almost done. This last step aims to improve the user experience by informing the user that the data is still loading so he doesn't have to look at an empty grid in the meantime. That's why the `HierarchicalGrid` supports a loading indicator that can be displayed while the grid is empty. If new data is received, the loading indicator will hide and the data will be rendered.
+
+#### Setup of loading indication
+
+The `HierarchicalGrid` can display a loading indicator by setting the `IsLoading` property to **true** while there is no data. We need to set it initially for the root grid and also when creating new child grids, until their data is loaded. We could always set it to **true** in our template, but we want to hide it and display that the grid has no data if the service returns an empty array by setting it to **false**.
+
+In this case the final version of our configuration would look like this:
+
+
+```typescript
+import { AfterViewInit, Component, ViewChild } from "@angular/core";
+import {
+ IGridCreatedEventArgs,
+ IgxHierarchicalGridComponent,
+ IgxRowIslandComponent
+} from "igniteui-angular";
+import { RemoteLoDService } from "../services/remote-lod.service";
+
+@Component({
+ providers: [RemoteLoDService],
+ selector: "app-hierarchical-grid-lod",
+ styleUrls: ["./hierarchical-grid-lod.component.scss"],
+ templateUrl: "./hierarchical-grid-lod.component.html"
+})
+export class HierarchicalGridLoDSampleComponent implements AfterViewInit {
+ @ViewChild("hGrid")
+ public hGrid: IgxHierarchicalGridComponent;
+
+ constructor(private remoteService: RemoteLoDService) { }
+
+ public ngAfterViewInit() {
+ this.hGrid.isLoading = true;
+ this.remoteService.getData({ parentID: null, rootLevel: true, key: "Customers" }).subscribe((data) => {
+ this.hGrid.isLoading = false;
+ this.hGrid.data = data;
+ this.hGrid.cdr.detectChanges();
+ });
+ }
+
+ public gridCreated(event: IGridCreatedEventArgs, _parentKey: string) {
+ const dataState = {
+ key: event.owner.key,
+ parentID: event.parentID,
+ parentKey: _parentKey,
+ rootLevel: false
+ };
+ event.grid.isLoading = true;
+ this.remoteService.getData(dataState).subscribe(
+ (data) => {
+ event.grid.isLoading = false;
+ event.grid.data = data;
+ event.grid.cdr.detectChanges();
+ }
+ );
+ }
+}
+```
+
+
+
+```ts
+constructor() {
+ const hierarchicalGrid = document.getElementById("hGrid") as IgcHierarchicalGridComponent;
+ const ordersRowIsland = document.getElementById("ordersRowIsland");
+ const orderDetailsRowIsland = document.getElementById("orderDetailsRowIsland");
+
+ ordersRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Customers");
+ });
+
+ orderDetailsRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Orders");
+ });
+
+ hierarchicalGrid.isLoading = true;
+
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then((data: any) => {
+ hierarchicalGrid.isLoading = false;
+ hierarchicalGrid.data = data;
+ hierarchicalGrid.markForCheck();
+ });
+}
+
+public gridCreated(event: CustomEvent, _parentKey: string) {
+ const context = event.detail;
+ const dataState = {
+ key: context.owner.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false
+ };
+
+ context.grid.isLoading = true;
+
+ getData(dataState).then((data: any[]) => {
+ context.grid.isLoading = false;
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+}
+```
+
+
+
+```tsx
+const hierarchicalGrid = useRef(null);
+
+useEffect(() => {
+ hierarchicalGrid.current.isLoading = true;
+
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
+ (data: any) => {
+ hierarchicalGrid.current.isLoading = false;
+ hierarchicalGrid.current.data = data;
+ hierarchicalGrid.current.markForCheck();
+ }
+ );
+}, []);
+
+function gridCreated(rowIsland: IgrRowIsland, event: IgrGridCreatedEventArgs, _parentKey: string) {
+ const context = event.detail;
+ const dataState = {
+ key: rowIsland.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false,
+ };
+
+ context.grid.isLoading = true;
+
+ getData(dataState).then((data: any[]) => {
+ context.grid.isLoading = false;
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+}
+```
+
+
+
+```razor
+igRegisterScript("OnGridRendered", () => {
+ const grid = document.getElementById("hGrid");
+
+ grid.isLoading = true;
+
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
+ (data) => {
+ grid.isLoading = false;
+ grid.data = data;
+ grid.markForCheck();
+ });
+}, false)
+
+igRegisterScript("OnGridCreated", (args) => {
+ const context = args.detail;
+ const _parentKey = context.owner.childDataKey === "Orders" ? "Customers" : "Orders";
+ const dataState = {
+ key: context.owner.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false,
+ };
+
+ context.grid.isLoading = true;
+
+ getData(dataState).then((data) => {
+ context.grid.isLoading = false;
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+}, false)
+```
+
+
+### API References
+
+* `HierarchicalGrid`
+* `RowIsland`
+
+### Additional Resources
+
+* [Hierarchical Grid Component](overview.md)
+
+Our community is active and always welcoming to new ideas.
+
+* [{ProductName} **Forums**]({ForumsLink})
+* [{ProductName} **GitHub**]({GithubLink})
\ No newline at end of file
diff --git a/doc/en/components/grids/hierarchical-grid/overview.md b/doc/en/components/grids/hierarchical-grid/overview.md
index 94f51853a..c20d2ff10 100644
--- a/doc/en/components/grids/hierarchical-grid/overview.md
+++ b/doc/en/components/grids/hierarchical-grid/overview.md
@@ -1,14 +1,883 @@
---
-title: {Platform} Hierarchical Data Grid | Material Table | {ProductName} | Infragistics
-_description: Learn how to use {ProductName} data grid, based on {Platform} Material Table and create a touch-responsive angular component with variety of angular events.
-_keywords: angular data grid, igniteui for angular, infragistics
+title: {Platform} Hierarchical Grid | Fastest {Platform} Hierarchical Table | Infragistics
+_description: The {ProductName} Hierarchical Grid is used to display and manipulate hierarchical with ease. Quickly bind your data with very little coding. Try it for FREE
+_keywords: {Platform} hierarchical grid, igniteui for {Platform}, infragistics
+mentionedTypes: [{ComponentApiMembers}]
namespace: Infragistics.Controls
---
# Hierarchical Data Grid Overview and Configuration
-{ProductName} Hierarchical Data Grid is used to display and manipulate hierarchical data with ease. Quickly bind your data with very little code or use a variety of events to customize different behaviors. This component provides a rich set of features like data selection, excel style filtering, sorting, paging, templating and column moving. The Hierarchical Grid builds upon the Flat Grid Component and extends its functionality by allowing the users to expand or collapse the rows of the parent grid, revealing the corresponding child grid, when more detailed information is needed. Displaying of hierarchical data has never been easier and beautiful thanks to the Material Table-based UI Grid.
+The {ProductName} Hierarchical Data Grid is used to display and manipulate hierarchical tabular data. Quickly bind your data with very little code or use a variety of events to customize different behaviors. This component provides a rich set of features like data selection, excel style filtering, sorting, paging, templating, column moving, column pinning, export to Excel and CSV, and more. The Hierarchical Grid builds upon the Flat Grid Component and extends its functionality by allowing the users to expand or collapse the rows of the parent grid, revealing corresponding child grids, when more detailed information is needed.
-
+## {Platform} Hierarchical Data Grid Example
+
+In this {Platform} grid example you can see how users can visualize hierarchical sets of data and use cell templating to add other visual components.
+
+`sample="/{HierarchicalGridSample}/overview", height="700", alt="{Platform} Hierarchical Grid example"`
+
+## Getting Started with {ProductName} Hierarchical Grid
+
+### Dependencies
+
+To get started with the {Platform} hierarchical grid, first you need to install the {ProductName} package.
+
+
+
+Please refer to these topics on adding the IgniteUI.Blazor package:
+
+- [Getting Started](../../general-getting-started-blazor-client.md)
+- [Adding Nuget Package](../../general-nuget-feed.md)
+
+You also need to include the following CSS link in the index.html file of your application to provide the necessary styles to the hierarchical grid:
+
+```razor
+
+```
+
+Afterwards, you may start implementing the control by adding the following namespaces:
+
+```razor
+@using IgniteUI.Blazor.Controls
+```
+
+
+
+
+
+When installing the {Platform} hierarchical grid package, the core package must also be installed.
+
+```cmd
+npm install --save {PackageCore}
+npm install --save {PackageGrids}
+npm install --save {PackageInputs}
+npm install --save {PackageLayouts}
+```
+
+You also need to include the following import to use the grid:
+
+
+```typescript
+import 'igniteui-webcomponents-grids/grids/combined.js';
+```
+
+
+```tsx
+import "igniteui-react-grids/grids";
+```
+
+The corresponding styles should also be referenced. You can choose light or dark option for one of the [themes](../../themes/overview.md) and based on your project configuration to import it:
+
+
+```typescript
+import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css';
+```
+
+
+```tsx
+import 'igniteui-react-grids/grids/themes/light/bootstrap.css'
+```
+
+
+Or to link it:
+```typescript
+
+```
+
+For more details on how to customize the appearance of the hierarchical grid, you may have a look at the [styling](overview.md#Styling) section.
+
+
+
+
+### Component Modules
+
+```razor
+// in Program.cs file
+
+builder.Services.AddIgniteUIBlazor(typeof(IgbhierarchicalGridModule));
+```
+
+```typescript
+// app.module.ts
+
+import { IgxhierarchicalGridModule } from 'igniteui-angular';
+// import { IgxhierarchicalGridModule } from '@infragistics/igniteui-angular'; for licensed package
+
+@NgModule({
+ imports: [
+ // ...
+ IgxhierarchicalGridModule,
+ // ...
+ ]
+})
+export class AppModule {}
+```
+
+
+
+## Using the {Platform} Hierarchical Data Grid
+
+### Data Binding
+
+The *{HierarchicalGridSelector}* derives from {GridSelector} and shares most of its functionality. The main difference is that it allows multiple levels of hierarchy to be defined. They are configured through a separate tag within the definition of *{HierarchicalGridSelector}*, called *{RowIslandSelector}*. The *{RowIslandSelector}* component defines the configuration for each child grid for the particular level. Multiple row islands per level are also supported.
+The Hierarchical Grid supports two ways of binding to data:
+
+### Using hierarchical data
+
+If the application loads the whole hierarchical data as an array of objects referencing children arrays of objects, then the Hierarchical Grid can be configured to read it and bind to it automatically. Here is an example of a properly structured hierarchical data source:
+
+```ts
+export const singers = [{
+ "Artist": "Naomí Yepes",
+ "Photo": "assets/images/hgrid/naomi.png",
+ "Debut": "2011",
+ "Grammy Nominations": 6,
+ "Grammy Awards": 0,
+ "Tours": [{
+ "Tour": "Faithful Tour",
+ "Started on": "Sep-12",
+ "Location": "Worldwide",
+ "Headliner": "NO",
+ "Toured by": "Naomí Yepes"
+ }],
+ "Albums": [{
+ "Album": "Dream Driven",
+ "Launch Date": new Date("August 25, 2014"),
+ "Billboard Review": "81",
+ "US Billboard 200": "1",
+ "Artist": "Naomí Yepes",
+ "Songs": [{
+ "No.": "1",
+ "Title": "Intro",
+ "Released": "*",
+ "Genre": "*",
+ "Album": "Dream Driven"
+ }]
+ }]
+}];
+```
+```razor
+public class SingersData : List
+{
+ public SingersData()
+ {
+ this.Add(new SingersDataItem()
+ {
+ Artist = "Naomí Yepes",
+ Photo = "assets/images/hgrid/naomi.png",
+ Debut = "2011",
+ GrammyNomination = 6,
+ GrammyAwards = 0,
+ Tours = new List() {
+ new ToursItem() {
+ Tour = "Faithful Tour",
+ StartedOn = new DateTime(),
+ Location = "Worldwide",
+ Headliner = "NO",
+ TouredBy = "Naomí Yepes"
+ }
+ },
+ Albums = new List() {
+ new AlbumItem() {
+ Album = "Dream Driven",
+ LaunchDate = new DateTime(),
+ BillboardReview= "81",
+ Artist = "Naomí Yepes",
+ Songs = new List() {
+ new SongItem() {
+ Number = "1",
+ Title="Intro",
+ Released = "*",
+ Genre = "Rock",
+ Album ="Dream Driven"
+ }
+ }
+ }
+ }
+ });
+ }
+}
+```
+Each *{RowIslandSelector}* should specify the key of the property that holds the children data.
+
+```html
+
+
+
+
+
+
+
+
+```
+
+```html
+
+
+
+
+
+
+
+
+```
+
+```tsx
+
+
+
+
+
+
+
+
+```
+
+```razor
+
+
+
+
+
+
+```
+> [!NOTE]
+> Note that instead of `data` the user configures only the `childDataKey` that the {HierarchicalGridSelector} needs to read to set the data automatically.
+
+### Using Load-On-Demand
+
+Most applications are designed to load as little data as possible initially, which results in faster load times. In such cases {HierarchicalGridSelector} may be configured to allow user-created services to feed it with data on demand.
+
+
+```html
+
+
+
+
+
+
+
+
+```
+
+```typescript
+// hierarchicalGridSample.component.ts
+
+@Component({...})
+export class HierarchicalGridLoDSampleComponent implements AfterViewInit {
+ @ViewChild("hGrid")
+ public hGrid: IgxHierarchicalGridComponent;
+
+ constructor(private remoteService: RemoteLoDService) { }
+
+ public ngAfterViewInit() {
+ this.hGrid.isLoading = true;
+ this.remoteService.getData({ parentID: null, rootLevel: true, key: "Customers" }).subscribe((data) => {
+ this.hGrid.isLoading = false;
+ this.hGrid.data = data;
+ this.hGrid.cdr.detectChanges();
+ });
+ }
+
+ public gridCreated(event: IGridCreatedEventArgs, _parentKey: string) {
+ const dataState = {
+ key: event.owner.key,
+ parentID: event.parentID,
+ parentKey: _parentKey,
+ rootLevel: false
+ };
+ event.grid.isLoading = true;
+ this.remoteService.getData(dataState).subscribe(
+ (data) => {
+ event.grid.isLoading = false;
+ event.grid.data = data;
+ event.grid.cdr.detectChanges();
+ }
+ );
+ }
+}
+```
+
+```typescript
+// remote-load-on-demand.service.ts
+
+@Injectable()
+export class RemoteLoDService {
+ public url = `https://data-northwind.indigo.design/`;
+
+ constructor(private http: HttpClient) { }
+
+ public getData(dataState: any): Observable {
+ return this.http.get(this.buildUrl(dataState)).pipe(
+ map((response) => response)
+ );
+ }
+
+ public buildUrl(dataState) {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${this.url}${qS}`;
+ }
+}
+```
+
+
+
+```html
+
+
+
+
+
+```
+
+```ts
+import { getData } from "./remoteService";
+
+export class HierarchicalGridLoadOnDemand {
+ constructor() {
+ const hierarchicalGrid = document.getElementById("hGrid") as IgcHierarchicalGridComponent;
+ const ordersRowIsland = document.getElementById("ordersRowIsland");
+ const orderDetailsRowIsland = document.getElementById("orderDetailsRowIsland");
+
+ ordersRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Customers");
+ });
+ orderDetailsRowIsland.addEventListener("gridCreated", (event: any) => {
+ this.gridCreated(event, "Orders");
+ });
+
+ hierarchicalGrid.isLoading = true;
+
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then((data: any) => {
+ hierarchicalGrid.isLoading = false;
+ hierarchicalGrid.data = data;
+ hierarchicalGrid.markForCheck();
+ });
+ }
+
+ public gridCreated(event: CustomEvent, _parentKey: string) {
+ const context = event.detail;
+ const dataState = {
+ key: context.owner.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false
+ };
+ context.grid.isLoading = true;
+ getData(dataState).then((data: any[]) => {
+ context.grid.isLoading = false;
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+ }
+}
+```
+
+
+```tsx
+import { getData } from "./remoteService";
+
+export default function Sample() {
+ const hierarchicalGrid = useRef(null);
+
+ function gridCreated(
+ rowIsland: IgrRowIsland,
+ event: IgrGridCreatedEventArgs,
+ _parentKey: string
+ ) {
+ const context = event.detail;
+ const dataState = {
+ key: rowIsland.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false,
+ };
+ context.grid.isLoading = true;
+ getData(dataState).then((data: any[]) => {
+ context.grid.isLoading = false;
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+ }
+
+ useEffect(() => {
+ hierarchicalGrid.current.isLoading = true;
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
+ (data: any) => {
+ hierarchicalGrid.current.isLoading = false;
+ hierarchicalGrid.current.data = data;
+ hierarchicalGrid.current.markForCheck();
+ }
+ );
+ }, []);
+
+ return (
+
+ gridCreated(rowIsland, e, "Customers")}
+ >
+ gridCreated(rowIsland, e, "Orders")}
+ >
+
+
+ );
+}
+```
+
+
+```ts
+const URL = `https://data-northwind.indigo.design/`;
+
+export function getData(dataState: any): any {
+ return fetch(buildUrl(dataState))
+ .then((result) => result.json());
+}
+
+function buildUrl(dataState: any) {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${URL}${qS}`;
+}
+```
+
+
+```razor
+
+
+
+
+
+
+In JavaScript
+igRegisterScript("OnGridRendered", () => {
+ const grid = document.getElementsByTagName("igc-hierarchical-grid")[0];
+ grid.isLoading = true;
+ getData({ parentID: null, rootLevel: true, key: "Customers" }).then(
+ (data) => {
+ grid.isLoading = false;
+ grid.data = data;
+ grid.markForCheck();
+ });
+}, false)
+
+igRegisterScript("OnGridCreated", (args) => {
+ const context = args.detail;
+ const _parentKey = context.owner.childDataKey === "Orders" ? "Customers" : "Orders";
+ const dataState = {
+ key: context.owner.childDataKey,
+ parentID: context.parentID,
+ parentKey: _parentKey,
+ rootLevel: false,
+ };
+ context.grid.isLoading = true;
+ getData(dataState).then((data) => {
+ context.grid.isLoading = false;
+ context.grid.data = data;
+ context.grid.markForCheck();
+ });
+}, false)
+
+const DATA_URL = `https://data-northwind.indigo.design/`;
+
+function getData(dataState) {
+ return fetch(buildUrl(dataState))
+ .then((result) => result.json());
+}
+
+function buildUrl(dataState) {
+ let qS = "";
+ if (dataState) {
+ if (dataState.rootLevel) {
+ qS += `${dataState.key}`;
+ } else {
+ qS += `${dataState.parentKey}/${dataState.parentID}/${dataState.key}`;
+ }
+ }
+ return `${DATA_URL}${qS}`;
+}
+```
+
+## Hide/Show row expand indicators
+
+If you have a way to provide information whether a row has children prior to its expanding, you could use the `HasChildrenKey` input property. This way you could provide a boolean property from the data objects which indicates whether an expansion indicator should be displayed.
+
+```html
+
+
+```
+
+```html
+
+
+```
+
+```tsx
+
+
+```
+
+```razor
+
+
+```
+
+Note that setting the `HasChildrenKey` property is not required. In case you don't provide it, expansion indicators will be displayed for each row.
+
+Additionally if you wish to show/hide the header expand/collapse all indicator you can use the `ShowExpandAll` property.
+This UI is disabled by default for performance reasons and it is not recommended to enable it in grids with large data or grids with load on demand.
+
+## Features
+
+The grid features could be enabled and configured through the {RowIslandSelector} markup - they get applied for every grid that is created for it. Changing options at runtime through the row island instance changes them for each of the grids it has spawned.
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```razor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+The following grid features work on a per grid level, which means that each grid instance manages them independently of the rest of the grids:
+
+- Sorting
+- Filtering
+- Paging
+- Multi Column Headers
+- Hiding
+- Pinning
+- Moving
+- Summaries
+- Search
+
+The Selection and Navigation features work globally for the whole {HierarchicalGridTitle}
+
+- Selection
+ Selection does not allow selected cells to be present for two different child grids at once.
+- Navigation
+ When navigating up/down, if next/prev element is a child grid, navigation will continue in the related child grid, marking the related cell as selected and focused. If the child cell is outside the current visible view port it is scrolled into view so that selected cell is always visible.
+
+## Collapse All Button
+
+The Hierarchical Grid allows the users to conveniently collapse all its currently expanded rows by pressing the "Collapse All" button at its top left corner. Additionally, every child grid which contains other grids and is a Hierarchical Grid itself, also has such a button - this way the user is able to collapse only a given grid in the hierarchy:
+
+
+
+
+
+
+
+## CRUD operations
+
+> [!NOTE]
+> An important difference from the flat Data Grid is that each instance for a given row island has the same transaction service instance and accumulates the same transaction log. In order to enable the CRUD functionality users should inject the `IgxHierarchicalTransactionServiceFactory`.
+
+Calling CRUD API methods should still be done through each separate grid instance.
+
+Check out the How-to [Build CRUD operations with igxGrid](../general/how-to/how-to-perform-crud.md) topic.
+
+
+
+## Styling
+The igxHierarchicalGrid allows styling through the [Ignite UI for Angular Theme Library](../themes/sass/component-themes.md). The grid's [theme]({environment:sassApiUrl}/index.html#function-grid-theme) exposes a wide variety of properties, which allow the customization of all the features of the grid.
+
+In the below steps, we are going through the steps of customizing the igxHierarchicalGrid styling.
+
+### Importing global theme
+To begin the customization of the hierarchical grid, you need to import the `index` file, where all styling functions and mixins are located.
+
+```scss
+@import '~igniteui-angular/lib/core/styles/themes/index'
+```
+
+### Defining custom theme
+Next, create a new theme, that extends the [`grid-theme`]({environment:sassApiUrl}/index.html#function-grid-theme) and accepts the parameters, required to customize the hierarchical grid as desired.
+
+ >[!NOTE]
+ >There is no specific `sass` hierarchical grid function.
+
+
+```scss
+$custom-theme: grid-theme(
+ $cell-active-border-color: #ffcd0f,
+ $cell-selected-background: #6f6f6f,
+ $row-hover-background: #f8e495,
+ $row-selected-background: #8d8d8d,
+ $header-background: #494949,
+ $header-text-color: #fff,
+ $expand-icon-color: #ffcd0f,
+ $expand-icon-hover-color: #e0b710,
+ $resize-line-color: #ffcd0f,
+ $row-highlight: #ffcd0f
+);
+```
+
+### Defining a custom color palette
+In the approach, that was described above, the color values were hardcoded. Alternatively, you can achieve greater flexibility, using the [`igx-palette`]({environment:sassApiUrl}/index.html#function-igx-palette) and [`igx-color`]({environment:sassApiUrl}/index.html#function-igx-color) functions.
+`igx-palette` generates a color palette, based on provided primary and secondary colors.
+
+ ```scss
+$black-color: #494949;
+$yellow-color: #FFCD0F;
+
+$custom-palette: palette(
+ $primary: $black-color,
+ $secondary: $yellow-color
+);
+```
+After a custom palette has been generated, the `igx-color` function can be used to obtain different varieties of the primary and the secondary colors.
+```scss
+$custom-theme: grid-theme(
+ $cell-active-border-color: (igx-color($custom-palette, "secondary", 500)),
+ $cell-selected-background: (igx-color($custom-palette, "primary", 300)),
+ $row-hover-background: (igx-color($custom-palette, "secondary", 100)),
+ $row-selected-background: (igx-color($custom-palette, "primary", 100)),
+ $header-background: (igx-color($custom-palette, "primary", 500)),
+ $header-text-color: (igx-contrast-color($custom-palette, "primary", 500)),
+ $expand-icon-color: (igx-color($custom-palette, "secondary", 500)),
+ $expand-icon-hover-color: (igx-color($custom-palette, "secondary", 600)),
+ $resize-line-color: (igx-color($custom-palette, "secondary", 500)),
+ $row-highlight: (igx-color($custom-palette, "secondary", 500))
+);
+```
+
+### Defining custom schemas
+You can go even further and build flexible structure that has all the benefits of a [**schema**](../themes/sass/schemas.md). The **schema** is the recipe of a theme.
+Extend one of the two predefined schemas, that are provided for every component. In our case, we will use `$_light_grid`.
+```scss
+$custom-grid-schema: extend($_light-grid,(
+ cell-active-border-color: (igx-color:('secondary', 500)),
+ cell-selected-background: (igx-color:('primary', 300)),
+ row-hover-background: (igx-color:('secondary', 100)),
+ row-selected-background: (igx-color:('primary', 100)),
+ header-background: (igx-color:('primary', 500)),
+ header-text-color: (igx-contrast-color:('primary', 500)),
+ expand-icon-color: (igx-color:('secondary', 500)),
+ expand-icon-hover-color: (igx-color:('secondary', 600)),
+ resize-line-color: (igx-color:('secondary', 500)),
+ row-highlight: (igx-color:('secondary', 500))
+));
+```
+In order for the custom schema to be applied, either `light`, or `dark` globals has to be extended. The whole process is actually supplying a component with a custom schema and adding it to the respective component theme afterwards.
+```scss
+$my-custom-schema: extend($light-schema, (
+ igx-grid: $custom-grid-schema
+));
+
+$custom-theme: grid-theme(
+ $palette: $custom-palette,
+ $schema: $my-custom-schema
+);
+```
+
+### Applying the custom theme
+The easiest way to apply your theme is with a `sass` `@include` statement in the global styles file:
+
+```scss
+@include grid($custom-theme);
+```
+
+### Scoped component theme
+
+In order for the custom theme do affect only specific component, you can move all of the styles you just defined from the global styles file to the custom component's style file (including the import of the `index` file).
+
+This way, due to Angular's [ViewEncapsulation](https://angular.io/api/core/Component#encapsulation), your styles will be applied only to your custom component.
+
+ >[!NOTE]
+ >If the component is using an [`Emulated`](../themes/sass/component-themes.md#view-encapsulation) ViewEncapsulation, it is necessary to penetrate this encapsulation using `::ng-deep` in order to style the grid.
+ >[!NOTE]
+ >Wrap the statement inside of a `:host` selector to prevent your styles from affecting elements *outside of* our component:
+
+```scss
+:host {
+ ::ng-deep {
+ @include grid($custom-theme);
+ }
+}
+```
+
+### Demo
+
+
+
+
+>[!NOTE]
+>The sample will not be affected by the selected global theme from `Change Theme`.
+
+
+
+
+## Styling
+In addition to the predefined themes, the grid could be further customized by setting some of the available [CSS properties](../theming.md). In case you would like to change the header background and text color, you need to set a class for the grid first:
+
+
+```html
+
+```
+
+
+```tsx
+
+```
+
+```razor
+
+```
+
+Then set the `--header-background` and `--header-text-color` CSS properties for that class:
+
+```css
+.grid {
+ --header-background: #494949;
+ --header-text-color: #FFF;
+}
+```
+### Demo
+`sample="/{HierarchicalGridSample}/hierarchical-grid-styling", height="700", alt="{Platform} Hierarchical Grid styling example"`
+
+
+
+## Known Limitations
+
+|Limitation|Description|
+|--- |--- |
+|Group By|Group By feature is not supported by the hierarchical grid.|
+
+## API References
+
+* `HierarchicalGrid`
+* `RowIsland`
+* `Grid`
+* `Column`
+* `Cell`
+
+
+
+
+Our community is active and always welcoming to new ideas.
+
+* [{ProductName} **Forums**]({ForumsLink})
+* [{ProductName} **GitHub**]({GithubLink})
\ No newline at end of file
diff --git a/doc/en/components/grids/tree-grid/overview.md b/doc/en/components/grids/tree-grid/overview.md
index 536c77ad9..6c82d4ae6 100644
--- a/doc/en/components/grids/tree-grid/overview.md
+++ b/doc/en/components/grids/tree-grid/overview.md
@@ -80,7 +80,7 @@ For more details on how to customize the appearance of the tree grid, you may ha
-
+
### Component Modules
```razor
@@ -105,7 +105,7 @@ import { IgxTreeGridModule } from 'igniteui-angular';
export class AppModule {}
```
-
+
## Usage
diff --git a/doc/en/components/grids/tree.md b/doc/en/components/grids/tree.md
index 90defb50f..763a22023 100644
--- a/doc/en/components/grids/tree.md
+++ b/doc/en/components/grids/tree.md
@@ -85,8 +85,8 @@ The simplest way to start using the `Tree` is as follows:
### Declaring a tree
`TreeItem` is the representation of every item that belongs to the `Tree`.
-Items provide `disabled`, `active`, `selected` and `expanded` properties, which give you opportunity to configure the states of the item as per your requirement.
-The `value` property can be used to add a reference to the data entry the item represents.
+Items provide `Disabled`, `Active`, `Selected` and `Expanded` properties, which give you opportunity to configure the states of the item as per your requirement.
+The `Value` property can be used to add a reference to the data entry the item represents.
@@ -124,7 +124,7 @@ Items can be bound to a data model so that their expanded and selected states ar
- Declaring a tree by creating static unbound items
-In order to render a tree you do not necessarily need a data set - individual items can be created without an underlying data model using the exposed `label` property or provide a custom slot content for the `TreeItem` label.
+In order to render a tree you do not necessarily need a data set - individual items can be created without an underlying data model using the exposed `Label` property or provide a custom slot content for the `TreeItem` label.
```html
@@ -191,16 +191,49 @@ In order to render a tree you do not necessarily need a data set - individual it
### Item Interactions
-The `Tree` provides the following API methods for item interactions:
+`TreeItem` could be expanded or collapsed:
+- by clicking on the item expand indicator *(default behavior)*.
+- by clicking on the item if the `Tree` `ToggleNodeOnClick` property is set to `true`.
-- `expand` - expands all items. If an items array is passed, expands only the specified items.
-- `collapse` - collapses all items. If an items array is passed, collapses only the specified items.
-- `select` - selects all items. If an items array is passed, selects only the specified items. Does not emit `Selection` event.
-- `deselect` - deselects all items. If an items array is passed, deselects only the specified items. Does not emit `Selection` event.
+```html
+
+
+
+
+
+
+
+
+
+
+```
+
+By default, multiple items could be expanded at the same time. In order to change this behavior and allow expanding only single branch at a time, the `SingleBranchExpand` property could be enabled. This way when an item is expanded, all of the others already expanded branches in the same level will be collapsed.
+
+```html
+
+
+
+
+
+
+
+
+
+
+```
+
+In addition, the `Tree` provides the following API methods for item interactions:
+
+- `Tree.Expand` - expands all items. If an items array is passed, expands only the specified items.
+- `Tree.Collapse` - collapses all items. If an items array is passed, collapses only the specified items.
+- `Tree.Select` - selects all items. If an items array is passed, selects only the specified items. Does not emit `selection` event.
+- `Tree.Deselect` - deselects all items. If an items array is passed, deselects only the specified items. Does not emit `selection` event.
+
## {Platform} Tree Selection
-In order to setup item selection in the {ProductName} Tree component, you just need to set its `selection` property. This property accepts the following three modes: **None**, **Multiple** and **Cascade**. Below we will take a look at each of them in more detail.
+In order to setup item selection in the {ProductName} Tree component, you just need to set its `Selection` property. This property accepts the following three modes: **None**, **Multiple** and **Cascade**. Below we will take a look at each of them in more detail.
### None
@@ -208,7 +241,7 @@ In the `Tree` by default item selection is disabled. Users cannot select or dese
### Multiple
-To enable multiple item selection in the `Tree` just set the `selection` property to **multiple**. This will render a checkbox for every item. Each item has two states - selected or not. This mode supports multiple selection.
+To enable multiple item selection in the `Tree` just set the `Selection` property to **multiple**. This will render a checkbox for every item. Each item has two states - selected or not. This mode supports multiple selection.
```html
diff --git a/doc/en/components/inputs/combo/single-selection.md b/doc/en/components/inputs/combo/single-selection.md
index 690cafdac..24f662e5e 100644
--- a/doc/en/components/inputs/combo/single-selection.md
+++ b/doc/en/components/inputs/combo/single-selection.md
@@ -9,7 +9,7 @@ mentionedTypes: ['Combo', 'Single Selection Combo', 'ComboItem', 'ComboHeader',
The {Platform} `ComboBox` supports single-selection mode and quick filtering of the list of items via the main input prompt. Users can quickly type in the item they are looking for and be presented with a list of options. Upon pressing the enter key, the first highlighted match will be selected.
-## {Platform} Single Selectoin Example
+## {Platform} Single Selection Example
To enable single-selection and quick filtering, set the `SingleSelect` property on the `ComboBox` component. The user experience and keyboard navigation will mostly stay the same, but instead of having to type in your search query into a special filtering box above the list of options, the main input box will be used.
diff --git a/doc/en/components/inputs/mask-input.md b/doc/en/components/inputs/mask-input.md
index 4089e0f73..dbc1f08b9 100644
--- a/doc/en/components/inputs/mask-input.md
+++ b/doc/en/components/inputs/mask-input.md
@@ -39,7 +39,7 @@ First, you need to the install the corresponding {ProductName} npm package by ru
npm install igniteui-react
```
-You will then need to import the `Mask Input`, its necessary CSS, and register its module, like so:
+You will then need to import the `MaskInput`, its necessary CSS, and register its module, like so:
```tsx
import { IgrMaskInput, IgrMaskInputModule } from 'igniteui-react';
import 'igniteui-webcomponents/themes/light/bootstrap.css';
diff --git a/doc/en/components/layouts/accordion.md b/doc/en/components/layouts/accordion.md
index b6d1e13fc..d3b2c72a9 100644
--- a/doc/en/components/layouts/accordion.md
+++ b/doc/en/components/layouts/accordion.md
@@ -45,6 +45,31 @@ For a complete introduction to the {ProductName}, read the [*Getting Started*](.
+
+
+First, you need to the install the corresponding {ProductName} npm package by running the following command:
+
+```cmd
+npm install igniteui-react
+```
+
+You will then need to import the `Accordion` and the `ExpansionPanel`, its necessary CSS, and register its module, like so:
+
+```tsx
+import {
+ IgrAccordion,
+ IgrAccordionModule,
+ IgrExpansionPanel,
+ IgrExpansionPanelModule,
+} from "igniteui-react";
+import "igniteui-webcomponents/themes/light/bootstrap.css";
+
+IgrAccordionModule.register();
+IgrExpansionPanelModule.register();
+```
+
+
+
Before using the `Accordion`, you need to register it as follows:
```razor
@@ -72,7 +97,7 @@ Panels provide `Disabled` and `Open` properties, which give you the ability to c
### Declaring an Accordion
-The accordion wraps all expansion panel`s declared inside it.
+The accordion wraps all expansion panels declared inside it.
```html
@@ -108,6 +133,19 @@ The accordion wraps all expansion panel`s declared inside it.
```
+```tsx
+
+
+
Title Panel 1
+
Content Panel 1
+
+
+
Title Panel 2
+
Content Panel 2
+
+
+```
+
Using the `Panels` accessor you can get a reference to the collection containing all expansion panels children of the `Accordion`.
@@ -123,6 +161,7 @@ constructor() {
```
+
As demonstrated above, the `SingleExpand`property gives you the ability to set whether single or multiple panels can be expanded at a time.
By using the `HideAll` and `ShowAll` methods you can respectively collapse and expand all `ExpansionPanel`s of the `Accordion` programmatically.
diff --git a/doc/en/components/layouts/expansion-panel.md b/doc/en/components/layouts/expansion-panel.md
index 16ab571f2..9495afcc6 100644
--- a/doc/en/components/layouts/expansion-panel.md
+++ b/doc/en/components/layouts/expansion-panel.md
@@ -130,7 +130,7 @@ The `ExpansionPanel` control allows all sorts of content to be added inside of i
The `ExpansionPanel` allows for easy customization of the header through the exposed *title*, *subTitle* and *indicator* slots.
-Configuring the position of the expansion indicator can be done through the `indicatorAlignment` property of the Expansion Panel. The possible options are **start**, **end** or **none**.
+Configuring the position of the expansion indicator can be done through the `IndicatorPosition` property of the Expansion Panel. The possible options are **start**, **end** or **none**.
The next code sample demonstrates how to configure the component's button to go on the *right* side.
diff --git a/doc/en/components/layouts/stepper.md b/doc/en/components/layouts/stepper.md
index 5adbc02f5..d24e27d07 100644
--- a/doc/en/components/layouts/stepper.md
+++ b/doc/en/components/layouts/stepper.md
@@ -10,9 +10,9 @@ The {Platform} Stepper Component provides a wizard-like workflow and is used for
## {Platform} Stepper Example
-The following {ProductName} Stepper Example below shows the component in action. It visualizes the process that an end-user must pass through to change the credentials of their credit card, following several consecutive steps.
+The following {ProductName} Stepper Example below shows the component in action. It visualizes the process that an end-user must pass through to configure an order details, following several consecutive steps.
-`sample="/layouts/stepper/overview", height="725", alt="{Platform} Stepper Example"`
+`sample="/layouts/stepper/linear", height="430", alt="{Platform} Linear Stepper Example"`
@@ -37,6 +37,24 @@ defineComponents(IgcStepperComponent);
For a complete introduction to the {ProductName}, read the [*Getting Started*](../general-getting-started.md) topic.
+
+
+
+First, you need to the install the corresponding {ProductName} npm package by running the following command:
+
+```cmd
+npm install igniteui-react
+```
+
+You will then need to import the `Stepper`, its necessary CSS, and register its module, like so:
+
+```tsx
+import { IgrStepperModule, IgrStepper, IgrStep } from 'igniteui-react';
+import 'igniteui-webcomponents/themes/light/bootstrap.css';
+IgrStepperModule.register();
+```
+
+
```razor
// in Program.cs file
@@ -58,7 +76,7 @@ You will also need to link an additional CSS file to apply the styling to the `S
Now you can start with a basic configuration of the {Platform} `Stepper` and its steps.
## How To Use {Platform} Stepper
-The `Step` is the representation of every step that belongs to the `Stepper`. Steps provide `Invalid`, `Active`, `Optional`, `Disabled` and `Complete` properties, which give you the ability to configure the step states according to your business requirement.
+The `Step` is the representation of every step that belongs to the `Stepper`. Steps provide `Step.Invalid`, `Step.Active`, `Step.Optional`, `Step.Disabled` and `Step.Complete` properties, which give you the ability to configure the step states according to your business requirement.
### Declaring {Platform} Stepper
Steps can be declared using one of the following approaches.
@@ -89,6 +107,16 @@ Steps can be declared using one of the following approaches.
```
+```tsx
+
+ {this.StepsData.map(item =>
+
+
{item.title}
+
+ }
+
+```
+
- Creating static steps
```html
@@ -112,6 +140,17 @@ Steps can be declared using one of the following approaches.
```
+
+```tsx
+
+
+
Step 1
+
+
+
Step 2
+
+
+```
For each step the user has the ability to configure indicator, title and subtitle using the `Indicator`, `Title` and `Subtitle` slots as follows:
> [!Note]
@@ -143,6 +182,20 @@ For each step the user has the ability to configure indicator, title and subtitl
```
+
+```tsx
+
+
+
+
Home
+
Home Sub Title
+
+ Step Content
+ ...
+
+
+
+```
### Orientation in {Platform} Stepper
@@ -165,23 +218,6 @@ The sample below demonstrates how stepper orientation and titles position could
-
-
-### Stepper Animations
-
-The {Platform} `Stepper` Animations provide the end-users with a beautiful experience interacting with the defined steps. The available animation options differ depending on the orientation of the stepper.
-
-When the stepper is horizontally orientated, it is configured to use the `slide` animation by default. It also supports `fade` as an alternative. The animations are configured through the `horizontalAnimation` input.
-
-In a vertically orientated layout, the animation type could be defined using the `verticalAnimation` property. By default, its value is set to `grow` and the user has the ability to set it to `fade` as well.
-
-Setting `none` to both animation type inputs disables stepper animations.
-
-The `Stepper` component also gives you the ability to configure the duration of the transition between the steps. This could be achieved through the `animationDuration` property, which takes a number as an argument and it is common to both orientations. The default value is set to 320ms.
-
-`sample="/layouts/stepper/animations", height="600", alt="{Platform} Stepper Animations Example"`
-
-
### Step States
@@ -196,20 +232,46 @@ The `Stepper` component also gives you the ability to configure the duration of
The {Platform} `Stepper` gives you the opportunity to set its steps flow using the `Linear` property. By default, linear is set to *false* and the user is enabled to select any non-disabled step in the `Stepper`.
-When the linear property is set to *true*, the stepper will require the current non-optional step to be valid before proceeding to the next one.
-
-If the current non-optional step is not valid you cannot go forward to the next step until you validate the current one.
-> [!Note]
-> Optional steps validity is not taken into account in order to move forward.
+```html
+
+
+
Step 1
+
+
+
Step 2
+
+
+```
-The following example demonstrates how to configure a linear stepper:
+```razor
+
+
+
+
+
+```
+When the linear property is set to *true*, the stepper will require the current non-optional step to be valid before proceeding to the next one.
+If the current non-optional step is not valid you cannot go forward to the next step until you validate the current one.
-
+> [!Note]
+> Optional steps validity is not taken into account in order to move forward.
### Step Interactions
@@ -269,9 +331,25 @@ The sample below demonstrates all exposed step types and how they could be chang
`sample="/layouts/stepper/steptypes", height="300", alt="{Platform} Step Types Example"`
+
+
+
+### Stepper Animations
+The {Platform} `Stepper` Animations provide the end-users with a beautiful experience interacting with the defined steps. The available animation options differ depending on the orientation of the stepper.
+
+When the stepper is horizontally orientated, it is configured to use the `slide` animation by default. It also supports `fade` as an alternative. The animations are configured through the `HorizontalAnimation` input.
+
+In a vertically orientated layout, the animation type could be defined using the `VerticalAnimation` property. By default, its value is set to `grow` and the user has the ability to set it to `fade` as well.
+
+Setting `none` to both animation type inputs disables stepper animations.
+
+The `Stepper` component also gives you the ability to configure the duration of the transition between the steps. This could be achieved through the `animationDuration` property, which takes a number as an argument and it is common to both orientations. The default value is set to 320ms.
+
+`sample="/layouts/stepper/animations", height="600", alt="{Platform} Stepper Animations Example"`
+
## Keyboard Navigation
diff --git a/doc/en/components/nextjs-usage.md b/doc/en/components/nextjs-usage.md
new file mode 100644
index 000000000..e8ac11691
--- /dev/null
+++ b/doc/en/components/nextjs-usage.md
@@ -0,0 +1,266 @@
+---
+title: Use {ProductName} components in Next.js application | Infragistics
+_description: Use Infragistics' {Platform} components to create apps and improve data visualization with the world’s fastest {Platform} data grid and charts in Next.js.
+_keywords: {ProductName} Next.js, {ProductName} Components in Next.js, Infragistics
+mentionedTypes: []
+---
+
+# Integrating {ProductName} with Next.js
+
+Explore the seamless integration of {ProductName} into your Next.js project. This topic is crafted to help developers make the most of the Infragistics {Platform} components while leveraging the features of Next.js for building robust and performant full stack applications.
+
+## Prerequisites
+
+1. Install NodeJS.
+2. Install Visual Studio Code.
+
+
+
+## Creating New Next.js Project
+
+With above prerequisites installed, we can create a new Next.js application.
+
+1 - Open **VS Code**, select **Terminal** menu and then **New Terminal** option.
+
+2 - Type the following commands in terminal window:
+
+```cmd
+npx create-next-app@latest MyAppName
+cd MyAppName
+```
+
+## Updating Existing Next.js App
+
+If you want to use {ProductName} in an existing Next.js project (one that you have from before). We have you covered! All you have to do is execute these commands:
+
+```cmd
+npm install --save {PackageCommon}
+npm install --save {PackageCharts} {PackageCore}
+npm install --save {PackageExcel} {PackageCore}
+npm install --save {PackageGauges} {PackageCore}
+npm install --save {PackageGrids} {PackageCore}
+npm install --save {PackageMaps} {PackageCore}
+npm install --save {PackageSpreadsheet} {PackageCore}
+```
+
+Or
+
+```cmd
+yarn add {PackageCharts} {PackageCore}
+yarn add {PackageExcel} {PackageCore}
+yarn add {PackageGauges} {PackageCore}
+yarn add {PackageGrids} {PackageCore}
+yarn add {PackageMaps} {PackageCore}
+yarn add {PackageSpreadsheet} {PackageCore}
+```
+
+This will automatically install packages for {ProductName}, along with all of their dependencies, font imports and styles references to the existing project.
+
+## Importing Component Modules
+
+First we have to import the required modules of the components we want to use. We will go ahead and do this for the [**GeographicMap**](geo-map.md) component.
+
+```ts
+"use client"
+import { IgrGeographicMapModule, IgrGeographicMap } from 'igniteui-react-maps';
+import { IgrDataChartInteractivityModule } from 'igniteui-react-charts';
+
+IgrGeographicMapModule.register();
+IgrDataChartInteractivityModule.register();
+```
+> [!Note]
+> It's important to note that {ProductName} components are using client-only features like state and browser events. Infragistics' components will work as expected within Client Next.js Components since they have the "use client" directive, but they won't work within Server Components.
+
+## Using Components
+
+We are now ready to use the {ProductName} map component in our Next.js component! Let's go ahead and define it:
+
+```tsx
+function App() {
+ return (
+
+
+
+ );
+}
+```
+
+## Running Application
+
+Finally, we can run our new application by using one of the following commands:
+
+```cmd
+npm run dev
+```
+
+After executing this command, your project will be built and served locally on your computer. It will automatically open in your default browser and you will be able to use {ProductName} components in your project.
+
+The final result should look something like this screenshot:
+
+
+
+## Using {Platform} in Next.js Server Components
+As mentioned earlier, most components of {Platform} rely on state and browser events, making them incompatible with direct use within Server Components. Nevertheless, if you find the need to use them this way, Infragistics' components can be wrapped within their respective Client Components.
+
+```tsx
+'use client'
+import { IgrGeographicMap } from 'igniteui-react-maps';
+IgrGeographicMapModule.register();
+
+export default IgrGeographicMap;
+```
+
+Then, in a Next.js Server Component the IgrGeographicMap can be used directly:
+
+```tsx
+import IgrGeographicMap from './wrapped-geographic-map';
+
+function App() {
+ return (
+