# Grid > AstrolGrid is a Blazor component used to represent information, providing a grid system to display organized data using rows and columns. It allows for essential functionalities such as applying filters, sorting, pagination, and more. Source page: https://doc.astrolui.com/basic-component/grid ## 1. Demo AstrolGrid In this example, [confirmations](/basic-component/confirm), [notifications](/basic-component/notification), and [buttons](/basic-component/button) are implemented. It is advisable to refer to the documentation of each component for more details. ```razor @using Astrol.Component.Basic.Grid @using Astrol.Component.Basic.Button @using Astrol.Component.Basic.Confirm @using Astrol.Entities.Basic.Static.Notification @using Astrol.Entities.Basic.UI @using Astrol.JSInterop.Base @inject AstrolJSInterop jsI @context.Id @code { ``` ```csharp private AstrolGrid? _grid; private AstrolConfirm? _conf; private List dataList = new List { new Client { Id = 1, Points= 34.56F, Name = "Juan", Surnames = "Pérez", Sex = true, MaritalStatus = MaritalStatus.Widower, Age = 25, RegistrationDate = new DateTime(2022, 1, 1) }, new Client { Id = 2, Points= 23.14F, Name = "María", Surnames = "García", Sex = false, MaritalStatus = MaritalStatus.Married, Age = 32, RegistrationDate = new DateTime(2021, 3, 15) }, new Client { Id = 3, Points= 36.32F, Name = "Pedro", Surnames = "Rodríguez", Sex = true, Age = 45, MaritalStatus = MaritalStatus.Single, RegistrationDate = new DateTime(2020, 6, 30) }, new Client { Id = 4, Points= 56.09F , Name = "Laura", Surnames = "Fernández", Sex = false, Age = 19, MaritalStatus = MaritalStatus.Divorced,RegistrationDate = new DateTime(2022, 2, 28) }, new Client { Id = 5, Points= 12.05F, Name = "Carlos", Surnames = "Sánchez", Sex = true, Age = 56,MaritalStatus = MaritalStatus.Married, RegistrationDate = new DateTime(2019, 12, 1) }, new Client { Id = 6,Points= 15.26F, Name = "Ana", Surnames = "Gómez", Age = 29, Sex = false, RegistrationDate = new DateTime(2021, 7, 10) }, new Client { Id = 7,Points= 14.34F , Name = "Pablo", Surnames = "Martínez", Sex = true, Age = 41, MaritalStatus = MaritalStatus.Married, RegistrationDate = new DateTime(2022, 4, 5) }, new Client { Id = 8,Points= 5.2F, Name = "Lucía", Surnames = "Jiménez", Age = 22,Sex = false, RegistrationDate = new DateTime(2023, 1, 2) }, new Client { Id = 9,Points= 88.53F, Name = "Javier", Surnames = "Hernández",Sex = true, Age = 37,MaritalStatus = MaritalStatus.Married, RegistrationDate = new DateTime(2022, 9, 15) }, new Client { Id = 10,Points= 45.23F , Name = "Sofía", Surnames = "Ruiz",Sex = false, Age = 28, RegistrationDate = new DateTime(2023, 3, 20) }, new Client { Id = 11,Points= 32.54F, Name = "Miguel", Surnames = "López",Sex = true, Age = 60, MaritalStatus = MaritalStatus.Other, RegistrationDate = new DateTime(2020, 5, 11) }, new Client { Id = 12,Points= 14.52F, Name = "Carmen", Surnames = "González",Sex = false, Age = 31, RegistrationDate = new DateTime(2021, 11, 16) }, new Client { Id = 13,Points= 78.8F, Name = "Antonio", Surnames = "Santos",Sex = true, Age = 48, RegistrationDate = new DateTime(2020, 3, 7) }, new Client { Id = 14,Points= 65.456F, Name = "Isabel", Surnames = "Ortega",Sex = false, Age = 20,MaritalStatus = MaritalStatus.Other, RegistrationDate = new DateTime(2022, 7, 31) }, new Client { Id = 15,Points= 56, Name = "David", Surnames = "Ramírez",Sex = true,Age = 43, RegistrationDate = new DateTime(2019, 10, 25) }, new Client { Id = 16,Points= 34.01F, Name = "Raquel", Surnames = "Pardo",Sex = false, Age = 26,MaritalStatus = MaritalStatus.Other, RegistrationDate = new DateTime(2021, 2, 14) }, }; private async Task DeleteItem(Client item) { if (await _conf!.Confirmation("Are you sure?", "Do you want to delete the item?")) { dataList.Remove(item); await jsI.Notification("Item removed successfully.".NotificationSuccess("astrol-ok")); await _grid!.RefreshGrid(); } } public class Client { public int Id { get; set; } public string? Name { get; set; } public bool Sex { get; set; } public string? Surnames { get; set; } public int Age { get; set; } public float Points { get; set; } public DateTime RegistrationDate { get; set; } public MaritalStatus MaritalStatus { get; set; } public string FullName => $"{Name} {Surnames}"; } public enum MaritalStatus { Single, Married, Divorced, Widower, Other } } ``` ### Supported parameters - TItem **(object)**, type of the grid rows. - Data **(IEnumerable)**, in-memory data: the grid sorts, filters and pages on the client **without copying or modifying** the list. If the content changes without changing the list, call **RefreshGrid()** or change **DataVersion**. - DataVersion **(object)**, change it to force a refresh when the content of **Data** changes without changing the reference or the number of items. It also works with **ReadItems** (calls the server again). - ReadItems **(EventCallback>)**, server-side loading (see below). When set, **Data** is not used. - ShowLoad **(bool)**, shows the loading animation while data is being fetched (default **true**). - IconLoad **(string)**, loading icon (default **astrol-spin5** *). - Pageable **(bool)**, paging (default **true**). - PageSize **(int)**, items per page (default **10**). - PageSizeList **(List)**, page size options (default **{ 5, 10, 20, 50, 100, int.MaxValue }**; **int.MaxValue** means "All"). - Selectable **(bool)**, rows selectable with a checkbox (default **false**). - KeySelector **(Func)**, unique key of each row: keeps the selection across pages and reloads and improves performance when reordering. - OnSelected **(EventCallback>)**, raised when the selection changes, with the selected rows. - Virtualize **(bool)**, renders only the visible rows; useful for large pages or no paging. **RowHeight** (float, approximate row height, default **41**) and **OverscanCount** (int, default **5**). - Options **(RenderFragment)**, top area for grid buttons or options. - Texts **(string)**: **NoSearchResultText**, **PagePaginationText**, **OfPaginationText**, **PageSizePaginationText**, **ItemPaginationText**, **AllPaginationText**, **SelectAllText**, **SelectRowText**. When not set, they follow the app language (English or Spanish). The pagination navigation button labels always come from **AstrolText**. - Methods and properties: **RefreshGrid(resetSelection = true)** reloads the data (by default it clears the selection without raising **OnSelected**; use **RefreshGrid(false)** to keep it), **GridInfo** (current page, sort and filters) and **CurrentPageItems** (visible rows). - Columns **(RenderFragment)**, grid columns (****). Inside a column, **context** is the row. - **Name** (string): property to display, sort and filter; supports paths like **"Customer.Name"**. It is the value sent to the server in **ColumnSort** / **ColumnFilter**. - **Field** (Expression): typed alternative to Name, e.g. **Field="x => x.Customer.Name"**. - **Title** (string): header text. - **Format** (string): value format when there is no custom content, e.g. **"dd/MM/yyyy"** or **"N2"**. - **Width** (string): column width (default **auto**). - **Sortable** (bool): sorting when clicking the header (ascending, descending, none); requires **Name** or **Field** (default **false**). - **Filtrable** (bool): header filter based on the property type: text, number, date (DateOnly), date and time (DateTime), time (TimeOnly / TimeSpan), bool or enum; other types show no filter (default **false**). - **FilterPlaceholder** (string): filter placeholder. - **TypeOf** (Type): type used to choose the filter when it cannot be inferred, e.g. **typeof(DateOnly)**. - **DefaultValue** (object): initial filter value. - **Resizable** (bool): width can be changed by dragging the right edge; it is kept when paging or sorting (default **false**). - **Id** (string): column identifier (optional). - **ClassHead** / **ClassRow** (string): css classes for the header and the cells. - **ChildContent** (RenderFragment): custom cell content; the row is **context**. - ReadItems **(EventCallback>)**, loading from your API. It receives **GridInfo** and must fill **AstrolPaginatedResponse**: - **GridInfo**: **Page** (int), **PageSize** (int), **SortInfo** (**ColumnSort**, **SortDirection**: None / Ascending / Descending) and **FilterInfo** (list of **ColumnFilter** / **ValueFilter**). - **AstrolPaginatedResponse**: **TotalItems** (int) and **PageItems** (IEnumerable). - On the server you can use **query.SortList(gridInfo.SortInfo).Paginate(gridInfo)**: it builds expressions that EF Core translates to SQL. - Filters are not applied automatically on the server: loop through **FilterInfo** and apply them to your query (**ValueFilter** arrives as text). Computed properties (e.g. **FullName**) sort in memory but EF Core cannot translate them to SQL. ## 2. Demo AstrolGrid selectable with options This example simulates loading data from the server; rows are selectable and column filtering has been disabled. **KeySelector** is needed to keep the selection across pages when data comes from the server (each read returns new objects). After changing the data call **RefreshGrid()** through **@ref** (it clears the selection; **RefreshGrid(false)** keeps it). **DataVersion** is optional: change it to force a refresh from parameters. ```razor @using Astrol.Component.Basic.Grid @using Astrol.Component.Basic.Button @using Astrol.Entities.Basic.UI @using Astrol.Entities.Basic.UI.Grid @using Astrol.Entities.Basic.Response @using Astrol.Entities.Basic.Static.Extensions @code { ``` ```csharp private AstrolGrid? _gridServer; private List _selected = new(); // Simulates the database table (on a real server: an EF Core IQueryable). private List _db = new List { /* same data as example 1 */ }; private async Task ReadItems(GridResponse request) { await Task.Delay(200); // simulated latency // Sorts, counts and pages (Astrol.Entities.Basic.Static.Extensions) request.AstrolPaginatedResponse = _db.AsQueryable().ToPaginatedResponse(request.GridInfo); // Async EF Core: same steps with SortList + Paginate // var query = dbContext.Clients.SortList(request.GridInfo.SortInfo); // request.AstrolPaginatedResponse = new() { // TotalItems = await query.CountAsync(), // PageItems = await query.Paginate(request.GridInfo).ToListAsync() }; } private void OnSelected(List selected) => _selected = selected; private async Task DeleteSelected() { var ids = _selected.Select(x => x.Id).ToHashSet(); _db.RemoveAll(x => ids.Contains(x.Id)); _selected = new(); await _gridServer!.RefreshGrid(); // reads again and clears the selection } } ```