Hi, I'm looking to reproduce visual behavior with the Blazor WASM Gird that we've already standardized on in our implementation of the KendoReact Grid component.
one of the things we're doing that i'm not seeing yet in the Blazor Grid docs is rendering a triple-dot icon in the column header that clicks down to show a custom menu... looking around, the closest thing i see so far is the Blazor Grid support for a "Toolbar" header... that would probably work as a path forward but I wanted to ask if i was missing anything else more similar? or perhaps eventual plans.
or is there any facility to custom render the column header ourselves?
i'm including a screenshot example of what we've settled on so far after several iterations
Thank you! this Blazor wasm direction you're supporting is fantastic =)
row height set in grid definition must apply to all rows in the grid for row virtualization as of now.
in real business case there might be complex content in each row that can't reinforce this - but if each row report its own height, grid still can visualize the load, and it will be much more flexible.
In the following reproducible, try filtering the third column (SomeNavigationProperty.Field1). It does not work.
<TelerikGrid Data="@myData" Pageable="true" Sortable="true" FilterMode="@GridFilterMode.FilterRow" Groupable="true">Hello,
I am new to your Blazor UI components. Please provide a link for exporting a grid to excel.
Thanks,
Earl
For example, I'd like something like this:
Field Name: record.TotalSales -> Auto-generated column title: "Total Sales" with inserted space
ADMIN EDIT: See also the idea below about "AutoGeneratedTitles" Func<string, string> property where the user could perform whatever processing they liked upon the default value. Please leave your comment on what approach you would prefer to be exposed.
I want to fetch grid records page per page according to the appropriate filter settings. While this is possible through the OnRead event, I want to be able to send the request to the server so that it is easier to fetch the data, like in the UI for ASP.NET Core grid. Currently you can do this only for a server-side project because you can pass the request object by reference, but for a WASM project it needs to serialize in an HTTP request.
---
ADMIN EDIT
You can find examples of doing this here: https://github.com/telerik/blazor-ui/tree/master/grid/datasourcerequest-on-server
---
@GridEditMode.Incell mode does not update automatically on row change when an editortemplate is used, as below
<GridColumn Field=@nameof(ProjectRankingInfo.Ranking.Option2) Title="@Option2Title" Width="120px" Filterable="false">
<EditorTemplate>
@{
currentItem = context as ProjectRankingInfo.Ranking;
<TelerikNumericTextBox Max="10" Min="0" Step="1" @bind-Value=@currentItem.Option2 />
}
</EditorTemplate>
</GridColumn>
one must click the update button for the update to occur,
Incell works fine and updates on row change for simple grid columns
ADMIN EDIT: SOLUTION: Read the details in the following article: https://docs.telerik.com/blazor-ui/components/grid/editing/incell#notes
ADMIN EDIT: this thread is rather long and I am adding the workaround offered by René here:
<TelerikGrid Data="@GridData" OnUpdate="@UpdateHandler"> ... </TelerikGrid>Currently I need to define a custom JsonConverter to serialize the state of the grid. I would prefer not to have to do this, however I understand that may just be the way things are for now. Creating this ticket / issue to track if this is ever changed to not being needed.
For now I'll be setting up two serializers, one just for the grids that uses Newtonsoft, and the one I would prefer to use that uses System.Text.Json, https://github.com/Blazored/LocalStorage.
From https://docs.telerik.com/blazor-ui/components/grid/state
// to store the serialized grid state, we need to have a custom serialized // based on Newtonsoft.Json serialization. In the future this may not be required public class FilterDescriptorJsonConverter : JsonConverter {
///rest omitted
}
Reproducible
<TelerikButton OnClick="@(_ => _Splited = !_Splited)">Toggle columns - works fine</TelerikButton>We are using Grid control with OData source (ToODataString() exstension) and OnRead event. When we try to group by some column, it douesn't work. OData query to API is same and OnRead event fires but grid not grouping.
Reproducible:
@using System.Collections.ObjectModel;
<div style="align-self:center;text-align:center" class="alert-danger">
@errorMessages
</div>
<div style="align-self:center;text-align:center" class="alert-success">
@successMessages
</div>
<TelerikGrid Data=@entitlementsExtended
Pageable="true"
Groupable="false"
PageSize="@PageSize"
OnUpdate="@UpdateHandler"
Sortable="false"
FilterMode="Telerik.Blazor.GridFilterMode.FilterMenu">
<GridColumns>
<GridColumn Field="@nameof(EntitlementValueDTOExtended.Description)" Editable="false" />
<GridColumn Field=@nameof(EntitlementValueDTOExtended.Value)>
<EditorTemplate>
@{
CurrentlyEditedEntitlement = context as EntitlementValueDTOExtended;
<div>
<TelerikDropDownList Data="@entitlementOptions" @bind-Value="CurrentlyEditedEntitlement.Value" Width="60px" PopupHeight="auto"></TelerikDropDownList>
</div>
}
</EditorTemplate>
</GridColumn>
<GridCommandColumn Width="300px">
<GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
<GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
<GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
int PageSize = 10;
public EntitlementValueDTOExtended CurrentlyEditedEntitlement { get; set; } = new EntitlementValueDTOExtended();
//changing this to List<> works
public ObservableCollection<EntitlementValueDTOExtended> entitlementsExtended { get; set; } = new ObservableCollection<EntitlementValueDTOExtended>();
public static List<string> entitlementOptions = new List<string> { "I", "E" };
public string errorMessages { get; set; } = "";
public string successMessages { get; set; } = "";
protected async override Task OnInitializedAsync()
{
IEnumerable<int> entitlements = Enumerable.Range(1, 50);
//this is a simplified workaround for people needing nested models
foreach (var entitlement in entitlements)
{
EntitlementValueDTOExtended entitlementExtended = new EntitlementValueDTOExtended();
entitlementExtended.Id = Guid.NewGuid();
entitlementExtended.Description = $"descr {entitlement}";
entitlementExtended.Value = $"value {entitlement}";
entitlementExtended.EntitlementTypeId = entitlement;
entitlementsExtended.Add(entitlementExtended);
}
StateHasChanged();
await base.OnInitializedAsync();
}
public async Task UpdateHandler(GridCommandEventArgs args)
{
EntitlementValueDTOExtended item = (EntitlementValueDTOExtended)args.Item;
var matchingItem = entitlementsExtended.FirstOrDefault(c => c.Id == item.Id);
if (matchingItem != null)
{
matchingItem.Description = item.Description;
matchingItem.EntitlementTypeId = item.EntitlementTypeId;
matchingItem.Value = item.Value;
}
successMessages = $"updated grid on {DateTime.Now}";
StateHasChanged();
}
public class EntitlementValueDTOExtended
{
public Guid Id { get; set; }
public string Description { get; set; } = "";
public string Value { get; set; } = "";
public int EntitlementTypeId { get; set; } = 0;
}
ADMIN EDIT: The following knowledge base article has been updated to explain how to use nested models: https://docs.telerik.com/blazor-ui/knowledge-base/grid-bind-navigation-property-complex-object
At the moment, you must use flat models with primitive types for binding the grid. If you don't, the data source operations break and they can't even display "nested" values. Examples here and here.
I would like to be able to use my complex models so I can point a grid's column to a field like MyModel.MyNestedModel.MyPrimitiveField
My be related to binding to a data table and dynamic expando.
TelerikGird with virtual scrolling was working in version 2.7, but after upgrading to 2.10, it is only showing placeholders.
When scrolling, it shows the values for a split second, but then those get replaced by the placeholders.
@page "/test"
<TelerikGrid Data=@GridData
SelectionMode="GridSelectionMode.Single"
ScrollMode="GridScrollMode.Virtual"
Height="300px" RowHeight="20">
<GridColumns>
<GridColumn Field=@nameof(Employee.Name) />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
</GridColumns>
</TelerikGrid>
@code {
public List<Employee> GridData { get; set; }
protected override void OnInitialized()
{
GridData = new List<Employee>();
for (int i = 0; i < 15; i++)
{
GridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3
});
}
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
}
}
A workaround is to initialize the collection of the selected items:
<TelerikButton OnClick="@LoadData">Load Data</TelerikButton>
<TelerikGrid Data=@adminUsers Height="300px" Pageable=true PageSize=10 SelectionMode="@GridSelectionMode.Multiple"
@bind-SelectedItems="SelectedAdminUsers">
<GridColumns>
<GridCheckboxColumn SelectAll="true"></GridCheckboxColumn>
<GridColumn Field=@nameof(User.DisplayName) Title="User Name" />
<GridColumn Field=@nameof(User.Department) Title="Department" />
<GridColumn Field=@nameof(User.Status) Title="Status" />
<GridColumn Field=@nameof(User.EmployeeId) Title="Employee Id" />
</GridColumns>
</TelerikGrid>
@code
{
public IEnumerable<User> SelectedAdminUsers { get; set; } = Enumerable.Empty<User>();
public List<User> adminUsers { get; set; }
void LoadData()
{
adminUsers = Enumerable.Range(1, 200).Select(x => new User
{
EmployeeId = x,
Status = $"status {x}",
Department = $"department {x}",
DisplayName = $"name {x}"
}
).ToList();
}
public class User
{
public string DisplayName { get; set; }
public string Department { get; set; }
public string Status { get; set; }
public int EmployeeId { get; set; }
}
}