diff --git a/components/grid/toolbar.md b/components/grid/toolbar.md index 4f3f2e3f0e..ec7bc291ba 100644 --- a/components/grid/toolbar.md +++ b/components/grid/toolbar.md @@ -10,208 +10,152 @@ position: 45 # Grid Toolbar -The grid provides a toolbar where you can add a variety of actions that are not tied to a concrete row. +The [Blazor Grid](https://demos.telerik.com/blazor-ui/grid/overview) toolbar can render built-in and custom tools. This article describes the built-in tools and shows how to add [custom tools](#custom-tools) or create a [custom toolbar](#custom-toolbar-configuration). -To use a toolbar, define the `GridToolBarTemplate` tag of the grid. In it, you can use arbitrary HTML and components to get the desired layout, and also `GridCommandButton` instances in (you can read more about the features available in those buttons in the [Command Column](slug://components/grid/columns/command) article). +## Built-In Tools ->note The toolbar is not associated with an item from the data source. The `Item` field on the click event handler argument of a `GridCommandButton` will always be `null` and the `Edit`, `Update`, `Cancel` commands do not work with it. +The [Blazor Grid](https://demos.telerik.com/blazor-ui/grid/overview) provides several built-in tools that can be added to the component toolbar. To include a specific tool in the [toolbar configuration](#toolbar-tools-configuration), use the respective tool tags below. -In this article, you will learn how to use: +### Command Tools -* [Built-in Commands](#built-in-commands) -* [Custom Commands](#custom-commands) -* [Custom Layout](#custom-layout) +@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) +| Tool Name | Tool Tag | Description | +| --- | --- | --- | +| Add | `GridToolBarAddTool` | An add command that fires the [`OnAdd` event](slug://components/grid/editing/overview#events). | +| CsvExport | `GridToolBarCsvExportTool` | An export command for CSV files that fires the [`OnBeforeExport` event](slug://grid-export-events#onbeforeexport). | +| ExcelExport | `GridToolBarExcelExportTool` | An export command for Excel files that fires the [`OnBeforeExport` event](slug://grid-export-events#onbeforeexport). | +| SearchBox | `GridToolBarSearchBoxTool` | A searchbox that filters multiple Grid columns simultaneously. | -## Built-in Commands +### Layout Tools -The grid offers built-in commands that you can invoke through its toolbar. To use them, set the `Command` property of the button to the command name. The built-in command names are: +| Tool Name | Tool Tag | Description | +| --- | --- | --- | +| Spacer | `GridToolBarSpacerTool` | Consumes the available empty space and pushes the rest of the tools next to one another. | -* `Add` - starts [inserting a new item in the grid](slug://components/grid/editing/overview). +## Custom Tools -* `ExcelExport` - starts an [Excel export of the grid data](slug://grid-export-excel). +In addition to the built-in tools, the Grid also supports custom tools. Use the `` tag, which is a standard Blazor `RenderFragment`. See the example below. -* `CsvExport` - starts an [CSV export of the grid data](slug://grid-export-csv). +## Toolbar Tools Configuration +Add a `` tag inside `` to configure a toolbar, for example: ->caption How to insert a new item in the grid +* Arrange the Grid tools in a specific order; +* Remove some of the built-in tools; +* Add custom tools. -````RAZOR -@result +>important `` and `` cannot be used together in the same Grid instance. - - - Add Employee - +>caption Grid Toolbar Tools + +````RAZOR + + + + Custom Grid Tool + + + + Add a product + + + + Export to CSV + + + + Export to Excel + + + + + + - - - - - Edit - Save - Cancel + + + + + + + @code { - string result; - public List MyData { get; set; } + private List GridData { get; set; } - private async Task UpdateHandler(GridCommandEventArgs args) + private void OnToolbarCustomClick() { - SampleData item = args.Item as SampleData; - - // perform actual data source operations here through your service - SampleData updatedItem = await MyService.Update(item); - - // update the local view-model data with the service data - await GetGridData(); - - result = string.Format("Employee with ID {0} now has name {1} and hire date {2}", updatedItem.ID, updatedItem.Name, updatedItem.HireDate); + Console.WriteLine("Custom Grid Toolbar tool clicked!"); } - private async Task CreateHandler(GridCommandEventArgs args) + protected override void OnInitialized() { - SampleData item = args.Item as SampleData; - - // perform actual data source operations here through your service - SampleData insertedItem = await MyService.Create(item); + var data = new List(); + var rand = new Random(); - // update the local view-model data with the service data - await GetGridData(); - - result = string.Format("On {2} you added the employee {0} who was hired on {1}.", insertedItem.Name, insertedItem.HireDate, DateTime.Now); + for (int i = 0; i < 50; i++) + { + data.Add(new Person() + { + EmployeeId = i, + Name = "Employee " + i.ToString(), + HireDate = DateTime.Now.Date.AddDays(-(i * 2)), + AgeInYears = 20 + }); + } + GridData = new List(data); } - //in a real case, keep the models in dedicated locations, this is just an easy to copy and see example - public class SampleData + private void CreateItem(GridCommandEventArgs args) { - public int ID { get; set; } - public string Name { get; set; } - public DateTime HireDate { get; set; } - } + var argsItem = args.Item as Person; - async Task GetGridData() - { - MyData = await MyService.Read(); - } + argsItem.EmployeeId = GridData.Count + 1; - protected override async Task OnInitializedAsync() - { - await GetGridData(); + GridData.Insert(0, argsItem); } - // the following static class mimics an actual data service that handles the actual data source - // replace it with your actual service through the DI, this only mimics how the API can look like and works for this standalone page - public static class MyService + private void UpdateItem(GridCommandEventArgs args) { - private static List _data { get; set; } = new List(); - - public static async Task Create(SampleData itemToInsert) - { - itemToInsert.ID = _data.Count + 1; - _data.Insert(0, itemToInsert); - - return await Task.FromResult(itemToInsert); - } - - public static async Task> Read() - { - if (_data.Count < 1) - { - for (int i = 1; i < 50; i++) - { - _data.Add(new SampleData() - { - ID = i, - Name = "Name " + i.ToString(), - HireDate = DateTime.Now.AddDays(-i) - }); - } - } - - return await Task.FromResult(_data); - } + var argsItem = args.Item as Person; + var itemForEdit = GridData.FirstOrDefault(i => i.EmployeeId == argsItem.EmployeeId); - public static async Task Update(SampleData itemToUpdate) + if (itemForEdit != null) { - var index = _data.FindIndex(i => i.ID == itemToUpdate.ID); - if (index != -1) - { - _data[index] = itemToUpdate; - return await Task.FromResult(_data[index]); - } - - throw new Exception("no item to update"); + itemForEdit.AgeInYears = argsItem.AgeInYears; + itemForEdit.HireDate = argsItem.HireDate; + itemForEdit.Name = argsItem.Name; } } -} -```` - ->caption The result from the code snippet above, after the built-in Create button in the toolbar was clicked -![Blazor Create Toolbar Button](images/create-toolbar-button.png) - -## Custom Commands - -You can use the toolbar to add buttons that invoke actions specific to your application. - ->caption How to define a custom command in the grid toolbar + public class Person + { + public int? EmployeeId { get; set; } -````RAZOR -@result + public string Name { get; set; } - - - Fire My Command - - - - - - + public int? AgeInYears { get; set; } -@code { - string result; - - private void MyCommandFromToolbar(GridCommandEventArgs args) - { - //note - the args.Item object is null because the command item is not associated with an item - - result = "my custom toolbar command fired at " + DateTime.Now.ToString(); - - StateHasChanged(); - } - - //in a real case, keep the models in dedicated locations, this is just an easy to copy and see example - public class SampleData - { - public int ID { get; set; } - public string Name { get; set; } - public DateTime HireDate { get; set; } - } - - public IEnumerable MyData = Enumerable.Range(1, 50).Select(x => new SampleData - { - ID = x, - Name = "name " + x, - HireDate = DateTime.Now.AddDays(-x) - }); + public DateTime HireDate { get; set; } + } } ```` ->caption The result from the code snippet above, after the custom command button in the toolbar was clicked +## Custom Toolbar Configuration -![Blazor Custom Command Toolbar](images/custom-command-toolbar.png) +Add a `` tag inside `` to configure a custom toolbar. You can add your own HTML and components to create a more complex layout in the Grid header to match your business needs and also `GridCommandButton` instances (read more about the features available in those buttons in the [Command Column](slug://components/grid/columns/command) article). -## Custom Layout +When using a ``, you need to use the `Tab` key to navigate between the focusable items. This is because the `` allows rendering of custom elements. On the other hand, the `` uses the [built-in keyboard navigation](slug://accessibility-overview#keyboard-navigation) through arrow keys. -You can add your own HTML and components to create a more complex layout in the grid header to match your business needs. You can still use the grid command buttons, as well as other components and logic. - ->caption Custom Grid Toolbar Layout +>caption Custom Grid Toolbar ````RAZOR @result @@ -219,24 +163,14 @@ You can add your own HTML and components to create a more complex layout in the -
- @* the first level children in the toolbar get display: inline-flex and flex-shrink: 0 inherited from the grid, - we change it here to show we can, or you can work with the layout the grid defines if it suits your needs *@ - -
- Add Employee -
-
- -
- -
- @* one example of aligning content to the right with flex *@ - -
+
+ + Add Employee + + +
@@ -252,7 +186,7 @@ You can add your own HTML and components to create a more complex layout in the @code { - string result; + private string result; private void CreateHandler(GridCommandEventArgs args) { @@ -273,19 +207,19 @@ You can add your own HTML and components to create a more complex layout in the public List MyData = Enumerable.Range(1, 50).Select( x => new SampleData - { - ID = x, - Name = "name " + x, - HireDate = DateTime.Now.AddDays(-x) - }).ToList(); + { + ID = x, + Name = "name " + x, + HireDate = DateTime.Now.AddDays(-x) + }).ToList(); } ```` ->caption The result from the code snippet above, after adding a row, changing the dropdown and clicking the custom button. +## Next Steps -![Blazor Custom Toolbar Layout](images/custom-toolbar-layout.png) +* [Handle Grid events](slug://grid-events) ## See Also - * [Live Demo: Grid Toolbar](https://demos.telerik.com/blazor-ui/grid/editing-inline) - * [Blazor Grid](slug://grid-overview) +* [Grid Live Demo](https://demos.telerik.com/blazor-ui/grid/overview) +* [Grid API](/blazor-ui/api/Telerik.Blazor.Components.TelerikGrid) diff --git a/components/treelist/toolbar.md b/components/treelist/toolbar.md index e9f8930362..dcc3c35061 100644 --- a/components/treelist/toolbar.md +++ b/components/treelist/toolbar.md @@ -1,7 +1,7 @@ --- title: Toolbar page_title: TreeList - Toolbar -description: Use toolbar and custom actions in treelist for Blazor. +description: Use toolbar and custom actions in Treelist for Blazor. slug: treelist-toolbar tags: telerik,blazor,treelist,toolbar published: True @@ -10,145 +10,227 @@ position: 45 # TreeList Toolbar -The treelist provides a toolbar where you can add a variety of actions that are not tied to a concrete row. +The [Blazor TreeList](https://demos.telerik.com/blazor-ui/treelist/overview) toolbar can render built-in and custom tools. This article describes the built-in tools and shows how to add custom tools or [customize the toolbar](#custom-toolbar-configuration). -To use a toolbar, define the `TreeListToolBarTemplate` tag of the treelist. In it, you can use arbitrary HTML and components to get the desired layout, and also `TreeListCommandButton` instances in (you can read more about the features available in those buttons in the [Command Column](slug://treelist-columns-command) article). +## Built-In Tools ->note The toolbar is not associated with an item from the data source. The `Item` and `ParentItem` fields on the click event handler argument of a `TreeListCommandButton` will always be `null`, and the `Edit`, `Update`, `Cancel` commands do not work with it. +The [Blazor TreeList](https://demos.telerik.com/blazor-ui/treelist/overview) displays all its built-in tools in the order below. Use the respective tool tag if you need to define a tool explicitly in a [toolbar configuration](#toolbar-tools-configuration). -In this article, you will learn how to use: +### Command Tools -* [Built-in Commands](#built-in-commands) -* [Custom Commands](#custom-commands) -* [Custom Layout](#custom-layout) +@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) +| Tool Name | Tool Tag | Description | +| --- | --- | --- | +| Add | `TreeListToolBarAddTool` | An add command that fires the [`OnAdd` event](slug://treelist-editing-overview#events). | +| SearchBox | `TreeListToolBarSearchBoxTool` | A searchbox that filters multiple TreeList columns simultaneously. | -## Built-in Commands +### Layout Tools -The treelist offers built-in commands that you can invoke through its toolbar. To use them, set the `Command` property of the button to the command name. The built-in command names are: +| Tool Name | Tool Tag | Description | +| --- | --- | --- | +| Spacer | `TreeListToolBarSpacerTool` | Consumes the available empty space and pushes the rest of the tools next to one another. | -* `Add` - starts inserting a new item in the treelist. +## Custom Tools -For an example of using the toolbar to insert a new item, see the [TreeList Editing Overview](slug://treelist-editing-overview) article. +In addition to the built-in tools, the TreeList also supports custom tools. Use the `` tag, which is a standard Blazor `RenderFragment`. See the example below. -## Custom Commands +## Toolbar Tools Configuration -You can use the toolbar to add buttons that invoke actions specific to your application. +Add a `` tag inside `` to configure a toolbar, for example: ->caption How to define a custom command in the treelist toolbar +* Arrange the TreeList toolbar tools in a specific order; +* Remove some of the built-in tools; +* Add custom tools. -````RAZOR -@result - - +>important `` and `` cannot be used together in the same TreeList instance. - - Fire My Command - +>caption TreeList Toolbar Tools +````RAZOR + + + Add Product + + + Custom TreeList Tool + + + + + + - - - - + + + + + Add Child + Edit + Delete + Update + Cancel + @code { - public List Data { get; set; } + private List Data { get; set; } + private int LastId { get; set; } = 1; - // sample custom command handling - string result; - async Task MyCommandFromToolbar(TreeListCommandEventArgs args) + private void OnToolbarCustomClick() { - //note - the args.Item object is null because the command item is not associated with an item - - result = "my custom toolbar command fired at " + DateTime.Now.ToString(); + Console.WriteLine("Custom TreeList Toolbar tool clicked!"); } - // sample model + protected override void OnInitialized() + { + Data = new List(); - public class Employee + for (int i = 1; i < 6; i++) + { + var newItem = new HierarchicalModel() + { + Id = LastId, + FirstName = "Employee " + i.ToString(), + Items = new List(), + HasChildren = true, + OutOfOffice = i % 4 == 0 ? true : false + }; + + Data.Add(newItem); + LastId++; + + for (int j = 0; j < 5; j++) + { + newItem.Items.Add(new HierarchicalModel() + { + Id = LastId, + FirstName = " Employee " + i + " : " + j.ToString(), + OutOfOffice = i % 3 == 0 ? true : false + }); + + LastId++; + } + } + } + + private void UpdateItem(TreeListCommandEventArgs args) { - public int Id { get; set; } - public string Name { get; set; } - public string EmailAddress { get; set; } - public DateTime HireDate { get; set; } + var item = args.Item as HierarchicalModel; - public List DirectReports { get; set; } - public bool HasChildren { get; set; } + var foundItem = FindItemRecursive(Data, item.Id); + if (foundItem != null) + { + foundItem.FirstName = item.FirstName; + foundItem.HireDate = item.HireDate; + foundItem.OutOfOffice = item.OutOfOffice; + } } - // data generation - public int LastId { get; set; } = 1; - protected override async Task OnInitializedAsync() + private HierarchicalModel FindItemRecursive(List items, int id) { - Data = await GetTreeListData(); + foreach (var item in items) + { + if (item.Id.Equals(id)) + { + return item; + } + + if (item.Items?.Count > 0) + { + var childItem = FindItemRecursive(item.Items, id); + + if (childItem != null) + { + return childItem; + } + } + } + + return null; } - async Task> GetTreeListData() + private void DeleteItem(TreeListCommandEventArgs args) { - List data = new List(); + var item = args.Item as HierarchicalModel; - for (int i = 1; i < 15; i++) + RemoveChildRecursive(Data, item); + } + + private void RemoveChildRecursive(List items, HierarchicalModel item) + { + for (int i = 0; i < items.Count(); i++) { - Employee root = new Employee + if (item.Equals(items[i])) { - Id = LastId, - Name = $"root: {i}", - EmailAddress = $"{i}@example.com", - HireDate = DateTime.Now.AddYears(-i), - DirectReports = new List(), - HasChildren = true - }; - data.Add(root); - LastId++; + items.Remove(item); - for (int j = 1; j < 4; j++) + return; + } + else if (items[i].Items?.Count > 0) { - int currId = LastId; - Employee firstLevelChild = new Employee - { - Id = currId, - Name = $"first level child {j} of {i}", - EmailAddress = $"{currId}@example.com", - HireDate = DateTime.Now.AddDays(-currId), - DirectReports = new List(), - HasChildren = true - }; - root.DirectReports.Add(firstLevelChild); - LastId++; + RemoveChildRecursive(items[i].Items, item); - for (int k = 1; k < 3; k++) + if (items[i].Items.Count == 0) { - int nestedId = LastId; - firstLevelChild.DirectReports.Add(new Employee - { - Id = LastId, - Name = $"second level child {k} of {j} and {i}", - EmailAddress = $"{nestedId}@example.com", - HireDate = DateTime.Now.AddMinutes(-nestedId) - }); ; - LastId++; + items[i].HasChildren = false; } } } + } - return await Task.FromResult(data); + private void CreateItem(TreeListCommandEventArgs args) + { + var argsItem = args.Item as HierarchicalModel; + + argsItem.Id = LastId++; + + if (args.ParentItem != null) + { + var parent = (HierarchicalModel)args.ParentItem; + + parent.HasChildren = true; + if (parent.Items == null) + { + parent.Items = new List(); + } + + parent.Items.Insert(0, argsItem); + } + else + { + Data.Insert(0, argsItem); + } } -} + public class HierarchicalModel + { + public int Id { get; set; } + public string FirstName { get; set; } + public DateTime HireDate { get; set; } + public List Items { get; set; } + public bool HasChildren { get; set; } + public bool OutOfOffice { get; set; } + } +} ```` ->caption The result from the code snippet above, after the custom command button in the toolbar was clicked +## Custom Toolbar Configuration -![Blazor TreeList Custom Command Toolbar](images/custom-command-toolbar.png) +Add a `` tag inside `` to configure a custom toolbar. You can add your own HTML and components to create a more complex layout in the TreeList header to match your business needs and also `TreeListCommandButton` instances (read more about the features available in those buttons in the [Command Column](slug://treelist-columns-command) article). -## Custom Layout +When using a ``, you need to use the `Tab` key to navigate between the focusable items. This is because the `` allows rendering of custom elements. On the other hand, the `` uses the [built-in keyboard navigation](slug://accessibility-overview#keyboard-navigation) through arrow keys. -You can add your own HTML and components to create a more complex layout in the treelist header to match your business needs. You can still use the treelist command buttons, as well as other components and logic. - ->caption Custom TreeList Toolbar Layout +>caption Custom TreeList Toolbar ````RAZOR @* for brevity the insert operation is not implemented in this sample *@ @@ -158,24 +240,14 @@ You can add your own HTML and components to create a more complex layout in the -
- @* the first level children in the toolbar get display: inline-flex and flex-shrink: 0 inherited from the grid, - we change it here to show we can, or you can work with the layout the grid defines if it suits your needs *@ - -
- Add Employee -
-
- -
- -
- @* one example of aligning content to the right with flex *@ - -
+
+ + Add Employee + + +
@@ -188,11 +260,11 @@ You can add your own HTML and components to create a more complex layout in the @code { - public List Data { get; set; } + private List Data { get; set; } // sample custom command handling - string result; - async Task MyCommandFromToolbar(TreeListCommandEventArgs args) + private string result; + private async Task MyCommandFromToolbar(TreeListCommandEventArgs args) { //note - the args.Item object is null because the command item is not associated with an item @@ -200,7 +272,6 @@ You can add your own HTML and components to create a more complex layout in the } // sample model - public class Employee { public int Id { get; set; } @@ -213,13 +284,13 @@ You can add your own HTML and components to create a more complex layout in the } // data generation - public int LastId { get; set; } = 1; + private int LastId { get; set; } = 1; protected override async Task OnInitializedAsync() { Data = await GetTreeListData(); } - async Task> GetTreeListData() + private async Task> GetTreeListData() { List data = new List(); @@ -272,10 +343,12 @@ You can add your own HTML and components to create a more complex layout in the } ```` ->caption The result from the code snippet above, after changing the dropdown and clicking the custom button. +## Next Steps + +* [Handle TreeList events](slug://treelist-events) -![Blazor Custom Toolbar Layout](images/custom-toolbar-layout.png) ## See Also - * [Live Demo: TreeList Toolbar](https://demos.telerik.com/blazor-ui/treelist/editing-inline) +* [TreeList Live Demo](https://demos.telerik.com/blazor-ui/treelist/overview) +* [TreeList API](/blazor-ui/api/Telerik.Blazor.Components.TreeList)