Hi!
When i set GridCommandButton
<GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Save</GridCommandButton>
in a Grid component, I always get a Button with a label "Update". How can I change this?
Thank you!
I have a blazor grid with a large number of columns which I would like to have the width of the page and a horizontal scrollbar to be able to scroll through all of the columns.
According the the documentation I have found (https://demos.telerik.com/blazor-ui/grid/scrolling), setting the width of the grid to 100% and providing widths for the columns which exceed that of the width of the grid/page should cause the horizontal scrollbar to appear. Instead of doing this, however, the grid just expands horizontally to fit all of the columns, no matter what I try. In addition, it appears to be expanding the entire page horizontally to fit itself, as it is increasing the size of all of my bootstrap columns so that it fits within the bootstrap container.
Here is an example of a page containing a grid where I am experiencing this:
@page "/admin/users/manageusers"
@inherits ManageUsersBase
<h3>Manage Users</h3>
<WS7.Components.PDAuthorizeBase AllowedRoleIds="ManageAllUsers,ManageAssignedUsers" />
@if (this.Users == null)
{
<p><em>Loading...</em></p>
}
else
{
<div class="form-group">
<label for="UserSearch" class="col-form-label">Search</label>
<input id="UserSearch" class="form-control" type="search" aria-label="User Search" placeholder="Search" @bind-value="Filter" @bind-value:event="oninput" />
</div>
<TelerikGrid Data="@FilteredUsers" TItem="WS7.Engine.Models.ViewModels.ManageUsersViewModel" Height="600px" Width="100%" Pageable="true" PageSize="40" Sortable="true" Groupable="false"
FilterMode="GridFilterMode.FilterMenu" Resizable="true" Reorderable="true" OnEdit="EditUser" ScrollMode="@GridScrollMode.Scrollable">
<GridToolBar>
<GridCommandButton OnClick="(()=>AddUser())">
<span class="oi oi-plus"></span> Add
</GridCommandButton>
</GridToolBar>
<GridColumns>
<GridCommandColumn Width="100px">
<GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
</GridCommandColumn>
<GridColumn Field="UserName" Title="User Name" Width="500px" />
<GridColumn Field="Email" Title="Email" Width="500px" />
<GridColumn Field="FirstName" Title="First Name" Width="500px" />
<GridColumn Field="LastName" Title="Last Name" Width="500px" />
<GridColumn Field="AccountStatus" Title="Account Status" Width="500px">
<Template>
@{
string toolTip;
WS7.Engine.Models.ViewModels.ManageUsersViewModel user = context as WS7.Engine.Models.ViewModels.ManageUsersViewModel;
toolTip = "Account Status: " + user.AccountStatus;
toolTip += Environment.NewLine + "Active: " + user.Active.ToString();
toolTip += Environment.NewLine + "Email Confirmed: " + user.EmailConfirmed.ToString();
}
<div class="badge badge-pill badge-info">
<span class="oi oi-info" data-toggle="tooltip" data-placement="top" title="@toolTip"></span>
</div>
</Template>
</GridColumn>
@*<GridCommandColumn Width="90px">
<GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
</GridCommandColumn>*@
</GridColumns>
</TelerikGrid>
}
---
ADMIN EDIT
You can find some more details on the origin of the issue in the thread below and in the following Knowledge Base article, which also offers a few ideas for solutions to this browser behavior: https://docs.telerik.com/blazor-ui/knowledge-base/grid-bootstrap-flex-width-issue
---
ADMIN EDIT: The issue stems from the data operations in the business logic, and it is not a bug in the component and it does not relate to WebAPI usage.
Hi there,
as a follow-up of https://feedback.telerik.com/blazor/1461176-set-specific-position-in-virtual-scrolling-mode we have implemented the suggested skip handling. But there seems an issue when the data is fetched asynchronously, specifically from an Web API.
After hours of debugging and analyzing i have narrowed it down to the following simple Blazor app showcasing the bug:
https://github.com/ViRuSTriNiTy/blazor-app-telerik-grid-skip-bug
Please clone the repo, start the application and follow the steps displayed above the grid to reproduce the bug.
The second skip followed immediatelly after the first one originates from the Telerik assembly hence i cannot investigate it further (no source code).
What are your thoughts? Is it a bug?
So lonG
Daniel
Here's the reproducible:
@using System.ComponentModel.DataAnnotations
@* Used for the model annotations only *@
<strong>REPRO: activate the validation for the Name field to see the issue - click Save with an empty input</strong>
<TelerikGrid Data=@MyData EditMode="@GridEditMode.Popup" Pageable="true" Height="500px"
OnUpdate="@UpdateHandler" OnDelete="@DeleteHandler" OnCreate="@CreateHandler">
<GridToolBar>
<GridCommandButton Command="Add" Icon="add">Add Employee</GridCommandButton>
</GridToolBar>
<GridColumns>
<GridColumn Field=@nameof(SampleData.ID) Title="ID" Editable="false" />
<GridColumn Field=@nameof(SampleData.Name) Title="Name" />
<GridCommandColumn>
<GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
<GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
<GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
<GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
public class SampleData
{
public int ID { get; set; }
[Required(ErrorMessage = "aa something else")] // the first word is 1 or 2 characters to show the issue
public string Name { get; set; }
}
async Task UpdateHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operations here through your service
// if the grid Data is not tied to the service, you may need to update the local view data too
var index = MyData.FindIndex(i => i.ID == item.ID);
if (index != -1)
{
MyData[index] = item;
}
}
async Task DeleteHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operation here through your service
// if the grid Data is not tied to the service, you may need to update the local view data too
MyData.Remove(item);
}
async Task CreateHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operation here through your service
// if the grid Data is not tied to the service, you may need to update the local view data too
item.ID = MyData.Count + 1;
MyData.Insert(0, item);
}
public List<SampleData> MyData { get; set; }
protected override void OnInitialized()
{
MyData = new List<SampleData>();
for (int i = 0; i < 50; i++)
{
MyData.Add(new SampleData()
{
ID = i,
Name = "Name " + i.ToString()
});
}
}
}
column virtualization is a great feature for wide table - and we would like to use keyboard navigation with it.
can both be supported together?
thanks
wei
*** Thread created by admin on behalf of this customer ***
It would be good to have a Grid parameter like "ExpandDetailsOnSelection" for the Grid:
-> When the user selects a row, the DetailTemplate automatically expands - the DetailTemplate of the previous selected item is automatically collapsed
Advantages:
- no "+" button needed
- easy to integrate for 2-way-binding on SelectedItems (no need to use GridState and RowClick event)
I localize the names of my columns in the models. This works for the root-level model I bind to the grid, but using nested (navigation) properties does not let them pick up the title.
---
ADMIN EDIT
A sample project is attached that showcases the localization of the displayname attribute, and how that works for the main model. Since it does not work for the nested models, a small helper method to extract the required resource manually is added to the Title parameter of such a column.
---
Data load in background thread with selected row on UI crashing application when there is selection
1. Select a row
2. Click the button
3. check the server console and/or try to do something else
@using System.Collections.ObjectModel
<TelerikGrid @ref="@Grid"
Data="@GridData"
SelectionMode="@GridSelectionMode.Single"
OnRowClick="@OnRowClickHandler"
@bind-SelectedItems="@SelectedData"
EditMode="@GridEditMode.Incell"
Resizable="true"
Width="100%"
Height="200px"
Reorderable="true"
Groupable="false"
ShowColumnMenu="false"
FilterMode="@GridFilterMode.None"
Sortable="true">
<GridColumns>
<GridColumn Field=@nameof(ViewModel.Name) Editable="false">
</GridColumn>
</GridColumns>
</TelerikGrid>
<TelerikButton OnClick="RefreshButtonClick">Refresh</TelerikButton>
@code {
private const int RowHeight = 40;
private const string Height = "700px";
private const int PageSize = 20;
private ObservableCollection<ViewModel> GridData { get; set; } = new ObservableCollection<ViewModel>();
private IEnumerable<ViewModel> SelectedData { get; set; } = Enumerable.Empty<ViewModel>();
private TelerikGrid<ViewModel> Grid { get; set; }
protected override async Task OnInitializedAsync()
{
await LoadData();
await base.OnInitializedAsync();
}
async Task LoadData()
{
var data = Enumerable.Range(1, 5).Select(x => new ViewModel { Name = $"name {x}" });
GridData = new ObservableCollection<ViewModel>(data);
}
private async Task RefreshButtonClick()
{
Console.WriteLine("reload data");
// spawn a new thread, a Timer will do as well
await Task.Run(() =>
{
IEnumerable<ViewModel> data = new List<ViewModel> { new ViewModel { Name = "1" }, new ViewModel { Name = "2" }, new ViewModel { Name = "3" } };
this.GridData.Clear();
this.GridData.AddRange(data);
});
}
private void OnRowClickHandler(GridRowClickEventArgs args)
{
Console.WriteLine("click to select");
ViewModel viewModel = (ViewModel)args.Item;
//this is here because of theincell editing, not relevant to the issue
SelectedData = new List<ViewModel>() { viewModel };
}
public class ViewModel
{
public ViewModel()
{
}
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
}
I have a column in the grid that is bound to a enum. The enum value names show up fine in the grid, but when exported, I get the underlying int value, which is incomprehensible to the users.
Thanks
---
ADMIN EDIT:
As a workaround you could generate the .xlsx file yourself. I'm attaching a sample project that allows you to do that. The relevant line of code is line 125 in Index.razor
---
My grid starts with Groupable=false and at some point I may need to make it groupable. The group panel appears, but I cannot drag the column headers to it to actually group.
---
ADMIN EDIT
A workaround is to hide the grid so it can re-initialize with the new groupable setting:
Is Groupable: @IsGroupable
<TelerikButton OnClick="@ToggleGroupable">Toggle Groupable</TelerikButton>
@if (isGridVisible)
{
<TelerikGrid Data=@GridData @ref="@GridRef" Groupable="@IsGroupable" Pageable="true" Height="400px">
<GridColumns>
<GridColumn Field=@nameof(Employee.Name) Groupable="false" />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
<GridColumn Field=@nameof(Employee.IsOnLeave) Title="On Vacation" />
</GridColumns>
</TelerikGrid>
}
@code {
bool IsGroupable { get; set; }
bool isGridVisible { get; set; } = true;
TelerikGrid<Employee> GridRef { get; set; }
async Task ToggleGroupable()
{
//save state (sorting, paging,...) - it will be lost when we hide the grid
var state = GridRef.GetState();
//hide the grid so it can later re-initialize with the new groupable setting
isGridVisible = false;
await InvokeAsync(StateHasChanged);
await Task.Delay(20);
IsGroupable = !IsGroupable;
isGridVisible = true;
//afte the grid re-initialized and rendered with the new setting, restore its state
await InvokeAsync(StateHasChanged);
await Task.Delay(20);
await GridRef.SetState(state);
}
public List<Employee> GridData { get; set; }
protected override void OnInitialized()
{
GridData = new List<Employee>();
var rand = new Random();
for (int i = 0; i < 15; i++)
{
GridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3,
IsOnLeave = i % 2 == 0
});
}
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public bool IsOnLeave { get; set; }
}
}---
1. Use the code from the incell editing docs (https://docs.telerik.com/blazor-ui/components/grid/editing/incell)and monitor the server console
2. Edit a name (row 3 and onward)
3. Press Enter
I expect OnEdit to fire, but only OnUpdate fires