Hi,
the Blazor form controls like DropDownList & ComboBox have a fixed width of 300px (why ???).
This does not respect the Boostrap 4 style guidelines and in a <form> looks like:
where the "Currency" field is a standard <select> and "Model Reader Engine" is a <TelerikDropDownList>.
If I try to set the "Width" attribute of the DropDownList to "100%" the result is:
but if I try to open the DropDown the element list is large as the entire screen:
Have you planned a fix for this ?
Thanks in advance
Based on the example used in this page (https://docs.telerik.com/blazor-ui/components/grid/editing/incell)
i tried to use a component of my own composed by teleriks components in the editor template
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject IAccessTokenProvider AuthenticationService
@inject NavigationManager Navigation
@inject WeatherForecastDataSource WeatherForecastDataSource
@using Olympus.Artemis.Shared
@attribute [Authorize]
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
<TelerikGrid Data="_data" Height="400px"
Pageable="true" Sortable="true" Groupable="true" EditMode="@GridEditMode.Incell" Navigable="true"
FilterMode="Telerik.Blazor.GridFilterMode.FilterRow" @ref="_grid"
Resizable="true" Reorderable="true">
<GridColumns>
<GridColumn Field=@nameof(TestItem.WeatherForecastID) Title="Position" Width="200px">
<Template Context="item">
@{
var value = ((TestItem)item).WeatherForecastID;
var text = data.Where(x => x.ID == value).Select(x => x.Date).FirstOrDefault();
}
@text
</Template>
<EditorTemplate>
@{
currentItem = context as TestItem;
<Test2 OnChange="@onChange" DataSource="@this.WeatherForecastDataSource" Value="@currentItem.WeatherForecastID"></Test2>
}
</EditorTemplate>
</GridColumn>
</GridColumns>
</TelerikGrid>
</tbody>
</table>
@code {
protected async Task onChange(object o) {
currentItem.WeatherForecastID =(Guid) o;
Console.WriteLine("wrwerwe"+currentItem.WeatherForecastID);
await CloseEditor(currentItem);
}
protected async override Task OnParametersSetAsync()
{
data =await WeatherForecastDataSource.GetDataAsync();
await base.OnParametersSetAsync();
}
public List<WeatherForecast> data = new List<WeatherForecast>();
public TestItem currentItem { get; set; }
TelerikGrid<TestItem> _grid;
DateTime selectedValue { get; set; } = DateTime.Now;
private List<TestItem> _data = new List<TestItem>()
{
new TestItem { MyDate = DateTime.Today, DateName = "Σημερα" ,WeatherForecastID= new Guid("be4f3a98-5fd3-4972-bc49-1c442cdf87dd") ,ID=Guid.NewGuid()},
new TestItem { MyDate =DateTime.Today.AddDays(1), DateName = "Αύριο",WeatherForecastID=new Guid("7fac0c25-653b-4606-afef-19f6e27fc57a"),ID=Guid.NewGuid() },
new TestItem { MyDate =DateTime.Today.AddDays(2), DateName = "Μεθαύριο" ,WeatherForecastID= new Guid("48eb0a12-5971-479a-852d-6383f30e14cb"),ID=Guid.NewGuid()},
new TestItem { MyDate =DateTime.Today.AddDays(3), DateName = "Αντιμεθαύριο" ,WeatherForecastID= new Guid("113bde91-b0b9-45e0-9d4b-5b280650e042"),ID=Guid.NewGuid()}
};
public class TestItem:Olympus.Artemis.Shared.InfoEntities.BaseInfo {
public Guid WeatherForecastID { get; set; }
public DateTime MyDate { get; set; }
public string DateName { get; set; }
public override bool Equals(object obj)
{
if (obj != null && obj is TestItem)
{
TestItem curr = obj as TestItem;
return (ID == curr.ID) && (WeatherForecastID == curr.WeatherForecastID) && (MyDate == curr.MyDate) && (DateName == curr.DateName);
}
return false;
}
}
public async Task CloseEditor(TestItem currentItem)
{
var state = _grid?.GetState();
if (currentItem.ID == null && state.InsertedItem != null)
{
// insert operation - the item is new
await CreateHandler(new GridCommandEventArgs()
{
Item = state.InsertedItem
});
}
else
if (currentItem.ID != null && state.EditItem != null)
{
Console.WriteLine($"field c {state.EditField} {typeof(TestItem).GetProperty(state.EditField).GetValue(currentItem)}");
Console.WriteLine($"field e {state.EditField} {typeof(TestItem).GetProperty(state.EditField).GetValue(state.EditItem)}");
// edit operation on an existing item
await UpdateHandler(new GridCommandEventArgs()
{
Item = state.EditItem,
Field = state.EditField
});
}
state.InsertedItem = state.OriginalEditItem = state.EditItem = default;
StateHasChanged();
await Task.Delay(200); // let the grid re-render and close the cell if keyboard navigation is enabled
await _grid?.SetState(state);
}
async Task UpdateHandler(GridCommandEventArgs args)
{
string fieldName = args.Field;
object newVal = args.Value; // you can cast this, if necessary, according to your model
Console.WriteLine(fieldName);
TestItem item = (TestItem)args.Item; // you can also use the entire model
Console.WriteLine(item.ID);
// 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
var index = _data.FindIndex(i => i.ID == item.ID);
if (index != -1)
{
if (!_data[index].Equals(item))
{
_data[index] = item;
Console.WriteLine("Update event is fired for " + args.Field + typeof(TestItem).GetProperty(args.Field).GetValue(item));
// this copies the entire item, consider altering only the needed field
}
}
}
async Task CreateHandler(GridCommandEventArgs args)
{
TestItem item = (TestItem)args.Item;
item.ID = Guid.NewGuid();
_data.Insert(0, item);
Console.WriteLine("create");
// perform actual data source operation here through your service
}
}
The test2 component created by me is this one It only includes a telerikdropdown
@using Olympus.Artemis.Shared
<TelerikComboBox Data="@Items" Value="@Value" ValueField="ID" OnChange="@OnChange" TextField="Date">
</TelerikComboBox>
@code {
[Parameter]
public EventCallback<Object> OnChange { get; set; }
[Parameter]
public Guid Value { get; set; }
[Parameter]
public DataSource<WeatherForecast> DataSource { get; set; }
private IEnumerable<WeatherForecast> Items { get; set; } = new List<WeatherForecast>();
protected async override Task OnInitializedAsync()
{
Items = await DataSource.GetDataAsync();
await base.OnInitializedAsync();
}
}
But when i try to select something from the dropdown list the grid cel does not close gracefully
I get this error (the problem is when it executed the line await _grid?.SetState(state);)
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
The test control is a simplified version of a more complex control i was trying to create (mutlicolumn combobox)
If I instead use the telerikdropdown in editortemplate everything works ok
Just wondering if there has been any movement on this issue. We are seeing this in our production system application insights logs. Thanks!
System.ObjectDisposedException: at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender (Microsoft.AspNetCore.Components, Version=3.1.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer.ProcessPendingRender (Microsoft.AspNetCore.Components.Server, Version=3.1.6.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue (Microsoft.AspNetCore.Components, Version=3.1.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged (Microsoft.AspNetCore.Components, Version=3.1.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContextDispatcher.InvokeAsync (Microsoft.AspNetCore.Components, Version=3.1.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Telerik.Blazor.Components.RootComponent.TelerikFragmentContainer.Refresh (Telerik.Blazor, Version=2.16.0.0, Culture=neutral, PublicKeyToken=20b4b0547069c4f8) at Telerik.Blazor.Components.RootComponent.TelerikRootComponentFragment.Dispose (Telerik.Blazor, Version=2.16.0.0, Culture=neutral, PublicKeyToken=20b4b0547069c4f8) at Microsoft.AspNetCore.Components.Rendering.ComponentState.Dispose (Microsoft.AspNetCore.Components, Version=3.1.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60) at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose (Microsoft.AspNetCore.Components, Version=3.1.7.0, Culture=neutral, PublicKeyToken=adb9793829ddae60)
Related:
I have a numeric text box that is bound to a nullable int. There is also a combo box on the page that will auto set the value and disable the numeric text box if certain values are selected. as follows:
<TelerikComboBox Data="@TareTypes"
TextField="Name" ValueField="Id"
ValueExpression="@(() => Material.TareTypeId)"
ValueChanged="@((int? e) => TareTypeChanged(e))"
Width="200px"
Placeholder="Tare Type" ClearButton="true"></TelerikComboBox>
<TelerikNumericTextBox @bind-Value="@Material.TareWeight" Arrows="false" Enabled="@tareWeightEnabled" ></TelerikNumericTextBox>
and the code...
private void TareTypeChanged(int? tareTypeId)
{
Material.TareTypeId = tareTypeId;
tareWeightEnabled = true;
if (tareTypeId > 0)
{
var tareTypeWeight = TareTypes.Single(t => t.Id == tareTypeId).Weight;
if (tareTypeWeight.HasValue)
{
Material.TareWeight = tareTypeWeight;
tareWeightEnabled = false;
editContext.NotifyFieldChanged(editContext.Field("TareWeight"));
}
}
}
the following steps should reproduce the problem
As we are porting many of our applications from Telerik MVC to Blazor, our clients are complaining about particular features no longer being available.
One of which is the multiline edit for incell edit that is available in Telerik-MVC.
This feature is nice as it allows the grid to have a very "excel - like" feel to it, with a small triangle in the corner to indicate the cell/view-model has been edited.
As is, the user is forced to edit the data line-by-line, and save per line.
In real client work, data is not necessarily modified in this linear/per-row fashion.
Take for example, a client has a list of delivery dates which need to be updated down 1 column, current functionality is painful, as you need to edit 1 date, click save, then move onto the next row instead of just moving down the rows and clicking save after you have finished your edits (like you can with Telerik MVC grid).
My rationale for this feature add: The "big data" age is upon us - and blazor is very well suited for these types of applications being strongly typed/c# etc; would be great to see Telerik lead in rich data input components for data heavy applications, and the grid is the most core UI component hence should be the most feature rich and performant.
Hello
I have just received some feedback from a client re. the DateInput -Blazor control whereby they are describing the default behaviour as "strange" - and on having a closer look I tend to agree / believe there to be bugs with this.
Please see video and below notes - let me know if there are any workarounds to these things.
I do see there is an existing bug report which may partially cover these issues (DatePicker loses focus when used as data editor in the Grid and the input date starts with 0 (telerik.com)) , however, it seems this is "unplanned" ?
QA Telerik DateInput:
Entering a date without using the mouse to move focus is quite important for big data-entry in grids where you are tabbing or clicking over from field to field in large quantities.
Cheers
Phil
Wè would like to have the Fluent UI style available for Blazor. We are using the Telerik UI controls in a large project werd the UI has to be very similar to the one of Microsoft D365 Customer Service.
Regards, Henk
Can you add Debounce to the filtering?
---
ADMIN EDIT
At the moment, you can use the OnRead to implement custom filtering and also debounce the operations: https://docs.telerik.com/blazor-ui/components/combobox/events#onread and the particular example the article links is shown here: https://docs.telerik.com/blazor-ui/knowledge-base/combo-debounce-onread
You may also want to look at item virtualization in the dropdowns - Follow it here: https://feedback.telerik.com/blazor/1457808-combobox-virtualization
There is also a sample attached of implementing debouncing in a WASM app as a reference too.
---
A stack panel component that creates a layout of items that are vertically positioned.
It could also have a wrap layout to make the items horizontal with wrapping
or horizontal without wrapping
Create code snippets for all Blazor controls.
Provide either automation for installing into the Visual Studio toolbox or just provide as a web page for users to copy paste them into the Toolbox.
<TelerikDatePicker Id="startDate" @bind-Value="@StartDate" Width="160px" Format="dd-MMM-yy"></TelerikDatePicker>
DateTime StartDate=DateTime.Now
When our users type to click on the year and type another one they lose one of the digits - so if they try typing 19 or 18 for instance then it sets the date to year 01
I am implementing custom filtering by column in a data grid. The data source is very large so the filtering will be done by a stored procedure in the database. In order to avoid excessive calls to the procedure it would be great if the TextBox had a DebounceDelay property like the one in the SearchBox.
---
ADMIN EDIT
While not technically useful for the grid itself (see the bottom of this thread for more ideas and information on that, a built-in feature is coming there as well), there can be benefit in adding that to the inputs (e.g., the Editor has something like that already by default because it is designed for large content).
Thus, I am reopening this so we can gauge the interest.
In the meantime, using a few lines of application code can achieve debouncing of expensive api calls. Using the OnChange or OnBlur event may also be suitable workarounds, depending on the goal you are after.
---
Reloading the page described down below cause memory leak. Commenting lines with telerik button prevents the problem.
@page "/"
<h3 style="position:absolute; top: 0; z-index: 1000; margin-top: 10px">Home</h3>
↓ commenting these lines prevents the memory leak
<div>
<TelerikButton OnClick="@SayHelloHandler" Primary="true">Say Hello</TelerikButton>
<div>@helloString</div>
</div>
↑ commenting these lines prevents the memory leak
@code {
List<string> strings = new List<string>();
MarkupString helloString;
protected override void OnInitialized()
{
// Attempt to clear memory with Garbage Collector
GC.Collect();
GC.WaitForPendingFinalizers();
for (int i = 0; i < 1000000; i++)
{
string a = "asdasdasdasdddddddddasasdasdasdasdddddddddasasdasdasdasdddddddddasasdasdasdasdddddddddasasda";
strings.Add(a + "b");
}
base.OnInitialized();
}
void SayHelloHandler()
{
string msg = string.Format("Hello from <strong>Telerik Blazor</strong> at {0}.<br /> Now you can use <b><u><i>C#</i></u></b> to write front-end!", DateTime.Now);
helloString = new MarkupString(msg);
}
}
MainLayout.razor:
@layout TelerikLayout
@inherits LayoutComponentBase
<style>
.navmenu .k-drawer-items {
margin-top: 3.5rem;
}
.navmenu .k-widget.k-drawer {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 100%);
}
.k-drawer-container {
height: 100vh;
}
.btn-margin, .btn-margin:hover {
width: 48px;
height: 56px;
color: #FFF;
}
.navmenu .k-drawer {
color: #ffffffd6;
}
.navmenu .k-drawer-item:hover, .navmenu .k-drawer-item.k-state-hover {
color: #ffffffd6;
background-color: #f0f0f012;
}
.navmenu .k-drawer-item:hover.k-state-selected {
color: #ffffff;
background-color: #7bafff94;
}
.navmenu .k-drawer-item:not(:hover).k-state-selected {
color: #ffffff;
background-color: #7bafffbd;
}
.navmenu .k-drawer:hover .k-drawer-wrapper {
width: 240px;
}
.navmenu .k-drawer .k-drawer-wrapper {
transition-duration: 300ms !important;
}
</style>
<TelerikDrawer Data="@NavigablePages" MiniMode="true" Mode="@DrawerMode.Push" SelectedItem="SelectedItem" Class="navmenu sidebar"
SelectedItemChanged="ChangeSelectedItem" TItem="DrawerItem">
<Content>
<div class="page">
<div class="main">
<div class="top-row px-4 auth">
</div>
<div class="content px-4">
@Body
</div>
</div>
</div>
</Content>
</TelerikDrawer>
@code {
List<DrawerItem> NavigablePages { get; set; } =
new List<DrawerItem>
{
new DrawerItem { Text = "Home", Url = "/", Icon = "home" }
};
public class DrawerItem
{
public string Text { get; set; }
public string Url { get; set; }
public string Icon { get; set; }
public bool IsSeparator { get; set; }
}
DrawerItem SelectedItem { get; set; }
private void ChangeSelectedItem(DrawerItem chosenItem)
{
SelectedItem = chosenItem;
}
}
This code is example. The main problem was with TelerikGrid. Usage of any telerik component caused the same memory leak.
For example, I want to set the Sunday day to red or any other date to a special color.
<AdminEdit>
Here is a workaround that can be used until the feature is released
<style>
.hide-calendar {
display: none;
}
.special {
color: red;
font-weight: bold;
}
</style>
<div style="width: 400px">
<TelerikDateInput @bind-Value="@DateValue" Width="90%"></TelerikDateInput>
<TelerikButton Icon="calendar"
OnClick="@( () => isClicked = !isClicked )">
</TelerikButton>
</div>
<TelerikCalendar Class="@(!isClicked ? "hide-calendar" : "")"
@bind-Value="@DateValue"
OnCellRender="@OnCellRenderHandler"
Min="@(new DateTime(2000, 1, 1))"
Max="@(new DateTime(2090, 1, 1))">
</TelerikCalendar>
@code {
private void OnCellRenderHandler(CalendarCellRenderEventArgs args)
{
if (args.View == CalendarView.Month)
{
args.Class = args.Date.Day % 3 == 0 ? "special" : "";
}
else if (args.View == CalendarView.Decade)
{
args.Class = args.Date.Year == 2020 ? "special" : "";
}
}
private DateTime DateValue { get; set; } = DateTime.Today;
private bool isClicked { get; set; }
}
</AdminEdit>