Telerik Forums
UI for Blazor Forum
1 answer
32 views
When enabling a GridSearchBox in my Grid, while I'm typing or deleting letters from the search box, I get spammed in my Ouput from Debug with

"Exception thrown: 'System.Threading.Tasks.TaskCanceledExceptuion' in System.Private.CoreLib.dll"

Here is my code:


<TelerikGrid Data=@TestItemsList
             FilterMode="GridFilterMode.FilterRow"
             Sortable="true"
             EditMode="GridEditMode.Inline"
             Height="2000px"
             FilterRowDebounceDelay="300">
    
    <GridToolBarTemplate>
        <GridCommandButton Command="Add" Icon="@SvgIcon.Plus" Enabled="@UserModel.CanEdit()">Add Item</GridCommandButton>
        <GridSearchBox Fields="@SearchableFields" Placeholder="Search..." Width="300px" />
    </GridToolBarTemplate>

    <GridColumns>
        <GridColumn Field="@nameof(TestModel.FileName)"
                    Title="File Name"
                    Editable="false" />

        <GridCommandColumn>
            <GridCommandButton Command="Save"
                               Icon="@SvgIcon.Save"
                               ShowInEdit="true"
                               Enabled="@UserModel.CanEdit()"
                               OnClick="@OnUpdate">
                Update
            </GridCommandButton>

            <GridCommandButton Command="Edit"
                               Icon="@SvgIcon.Pencil"
                               Enabled="@UserModel.CanEdit()">
                Edit
            </GridCommandButton>

            <GridCommandButton Command="Delete"
                               Icon="@SvgIcon.Trash"
                               Enabled="@UserModel.CanEdit()"
                               OnClick="@OnDelete">
                Delete
            </GridCommandButton>

            <GridCommandButton Command="Cancel"
                               Icon="@SvgIcon.Cancel"
                               ShowInEdit="true"
                               Enabled="@UserModel.CanEdit()">
                Cancel
            </GridCommandButton>

        </GridCommandColumn>

    </GridColumns>
</TelerikGrid>

@* Only showing relevent code here *@
@code {

    private List<string> SearchableFields = new List<string> { nameof(SDSModel.Title), nameof(SDSModel.FileName) };

}

Details:
System.Threading.Tasks.TaskCanceledException
  HResult=0x8013153B
  Message=A task was canceled.

Call Stack:
Tsvetomir
Telerik team
 answered on 24 Dec 2024
1 answer
77 views

Hi,

Is there any way to correctly display an HTML-formatted output using the TelerikAIPrompt control? The response I get from the API call is a Markdown string. I converted this to HTML, and all I see is text with the HTML tags printed (listed listed in the sample below). 

It would be nice to have a way to use (MarkupString) to ensure the HTML is correctly shown.

My code is listed below for reference:

@page "/aitest"

@inject Microsoft.Extensions.Options.IOptions<ServerConfig> ServerConfig;

@using Ganss.Xss;
@using Markdig;
@using Newtonsoft.Json.Linq;
@using RestSharp;

<TelerikAIPrompt OnPromptRequest="@HandlePromptRequest" @ref="@AIPromptRef">
</TelerikAIPrompt>

@code {
    private TelerikAIPrompt AIPromptRef { get; set; } = default!;

    private async Task HandlePromptRequest(AIPromptPromptRequestEventArgs args)
    {
        string url = "{url}";

        var options = new RestClientOptions(url);
        var client = new RestClient(options);
        var request = new RestRequest("", Method.Post);

        request.AddHeader("Content-Type", "application/json");
        request.AddJsonBody("{\"api_key\": \"" + ServerConfig.Value.APIKey.ToString() + "\", \"question\": \"" + args.Prompt + "\"}");

        RestResponse response = new();
        response = await client.PostAsync(request);

        JObject data = JObject.Parse(response.Content ?? string.Empty);

        var answer = data["answer"] switch
        {
            null => string.Empty,
            _ => data["answer"]!.ToString()
        };

        // Convert the Markdown in the output to HTML
        var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
        string html = Markdown.ToHtml(answer, pipeline);

        // Sanitize the HTML
        var sanitizer = new HtmlSanitizer();
        string safeHtml = sanitizer.Sanitize(html);

        args.Output = safeHtml;
    }
}
Hristian Stefanov
Telerik team
 answered on 24 Dec 2024
1 answer
43 views
I have a TelerikGrid utilizing the FilterRow for FilterMode. One of the columns is called CurrentVersion where the CurrentVersion could be a copy of multiple other objects but it's Revision is higher. The objects with CurrentVersion = true, I want to be the only initially displayed items. If there is an item that is CurrentVersion = false, I still want it to be accessible by changing the filter to All instead of True, but I need true to be the default. How would I go about this? I've checked documentation and can't find a solution. I've also checked online and other forums posts and can't seem to find a solution. ChatGPT and CoPilot are also no help here.

<TelerikGrid Data=@TestItemsList
             FilterMode="GridFilterMode.FilterRow"
             Sortable="true"
             EditMode="GridEditMode.Inline"
             Height="2000px">

        <GridColumn Field="@nameof(TestModel.CurrentVersion)"
                    Title="Current Version"
                    Editable="true"
                    Filterable="true">

</TelerikGrid>
Hristian Stefanov
Telerik team
 answered on 24 Dec 2024
1 answer
61 views

Hi,
I am reacting to the need for unbind two system solutions for Template RenderFragment of FomItem. If I use standard FormItem, I am getting everything solved - styles, messages, label, ... However just because I need TextArea instead of standard input, the very first thing I am loosing is for in label, because for unknown reason your components have given ID and it cannot be read for that for attribute of label. After losing that standard behaviour, I am also losing error propagating and validations. I am supposed to manually retrieve error messages with TelerikValidationMessage, however for some unknown reason you've enforced Expression for FieldIdentifier and hide the possibility to set FieldIdentifier manually. So I had to derive my custom component, hide your For parameter and set it to "() => default" so it would not trigger null check exception.

Now, why all this. Because I've successfully cloned original Model with all properties and attributes with custom Assembly. I am also able to omit or include ValidationAttribute attributes - thus enabling or disabling validations. And for those templates, I've made RenderFragment<EditModel<TValue>> extension of your Template (I hate Blazor for inability to extend parameters - I had to create a new one - BindTemplate), so I was also able to cover that original model with BindValue property, which has all attributes included and it is also properly notifying EditContext if wrapped value changed - to original FieldIdentifier. So now I can have BindTemplate with not only correct typed binding for any two way binding with property, but also GetValidationMessage ony my EditModel Context, so everything within that template without need to manually do that work. It is up to you, if you want to include my project or create some other form type for that. However, it would be nice, since My system is much more robust and provides binded way for message and its property to be used within the template:

 

<AnetFormItem EditModel="() => this.Is.Your.Previous.For.Attribute">
<BindTemplate Context="model">
<TelerikTextArea @bind-value="model.BindValue">
@model.GetValidationMessage()/* No For here, it is already binded within Context model */
</BindTemplate>
</AnetFormItem>
It seems more logical to me - to derive that BindValue directly form For expression instead making programmer to bind whatever and then figure out the correct MemberExpression for the message. You could also provide RenderFragment for lable on that model and much more - that is meaning of this post ... It is also only logical as this is similar for Grid cell template ...
Dimo
Telerik team
 answered on 23 Dec 2024
1 answer
50 views
I have a TelerikGrid that the first column will open a TelerikWindow with a TelerikUpload. This is so that the user can upload files to the server that will be associated with the object. The object being edited has values that depend on the file being uploaded. For example, the file being uploaded has a File Name. If the File Name already exists, I want to change the name of the file currently being uploaded to include the Revision number at the end of the file name. For example, we have a file on the server named TestFile.pdf, and I am uploading a file named TestFile.pdf. If TestFile.pdf exists, I want to check what the revision of the TestFile.pdf that's already uploaded is, and add it to the end of the file name (TestFile_rev0.pdf). That part is simple, because it's just manipulation of the saved file on the server. However, the new file being uploaded I want to then change the name of it to TestFile_rev1.pdf, and I can do that and save it to the server, but the object in the grid that's currently being added, I need to pass the data to that object being edited, however it will not pass the data. How can we do that?


@page "/SDS"

@using SafetySite.Models;
@using Helpers

@inject SDSModel SDSModel
@inject UserModel UserModel
@inject NavigationManager NavigationManager

<PageTitle>Safety Data Sheets</PageTitle>

<TelerikGrid Data=@SDSItemsList
             FilterMode="GridFilterMode.FilterMenu"
             Sortable="true"
             EditMode="GridEditMode.Inline"
             Height="2000px">

    <GridToolBarTemplate>
        <GridCommandButton Command="Add"  Icon="@SvgIcon.Plus" Enabled="@UserModel.CanEdit()">Add SDS Sheet</GridCommandButton>
    </GridToolBarTemplate>

    <GridColumns>
        <GridColumn Field="@(nameof(SDSModel.FileExists))"  Title="File" Width="120px">

            <EditorTemplate>

                @{
                    var item = context as SDSModel;
                    if(item != null)
                    {
                        <TelerikButton OnClick="@(() => ToggleUploadWindow(item))"
                                       Icon="@SvgIcon.Upload"
                                       Class="btn btn-sm btn-primary">
                            Upload File
                        </TelerikButton>
                    }
                }

            </EditorTemplate>
            
            <Template>

                @{
                    var item = context as SDSModel;
                    if(item != null)
                    {
                        <div class="text-center">
                            <TelerikButton OnClick="@(() => NavigateToViewSDSFile(item.FileName!))"
                                           Class="navlinkgrow">

                                <div class="navlink-content">
                                    <span class="@(item.FileExists ? "text-success" : "text-danger")">
                                        <i class="fa-duotone fa-solid fa-file-pdf fa-2x"></i>
                                    </span>
                                </div>

                            </TelerikButton>
                        </div>

                    }
                }

            </Template>
        </GridColumn>


        <GridColumn Field="@nameof(SDSModel.Title)"
                    Title="Title"
                    Editable="true" />


        <GridColumn Field="@nameof(SDSModel.Revision)"
                    Title="Revision"
                    Editable="true" />


        <GridColumn Field="@nameof(SDSModel.CurrentVersion)"
                    Title="CurrentVersion"
                    Editable="true">

            <Template>
                @{
                    var item = context as SDSModel;
                    if (item != null)
                    {
                        <input type="checkbox" checked="@item.CurrentVersion" disabled />
                    }
                }
            </Template>

        </GridColumn>


        <GridColumn Field="@nameof(SDSModel.CreatedBy)"
                    Title="Created By"
                    Editable="false" />

        <GridColumn Field="@nameof(SDSModel.EditedBy)"
                    Title="Edited By"
                    Editable="false" />

        <GridColumn Field="@nameof(SDSModel.CreationDate)"
                    Title="Creation Date"
                    DisplayFormat="{0:yyyy-MM-dd}"
                    Editable="false" />

        <GridColumn Field="@nameof(SDSModel.EditedDate)"
                    Title="Edit Date"
                    DisplayFormat="{0:yyyy-MM-dd}"
                    Editable="false" />
        
        <GridCommandColumn>
            <GridCommandButton Command="Save"
                               Icon="@SvgIcon.Save"
                               ShowInEdit="true"
                               Enabled="@UserModel.CanEdit()"
                               OnClick="@OnUpdate">
                Update
            </GridCommandButton>

            <GridCommandButton Command="Edit"
                               Icon="@SvgIcon.Pencil"
                               Enabled="@UserModel.CanEdit()">
                Edit
            </GridCommandButton>

            <GridCommandButton Command="Delete"
                               Icon="@SvgIcon.Trash"
                               Enabled="@UserModel.CanEdit()"
                               OnClick="@OnDelete">
                Delete
            </GridCommandButton>

            <GridCommandButton Command="Cancel"
                               Icon="@SvgIcon.Cancel"
                               ShowInEdit="true"
                               Enabled="@UserModel.CanEdit()">
                Cancel
            </GridCommandButton>

        </GridCommandColumn>

    </GridColumns>
</TelerikGrid>


@* THIS TELERIK WINDOW OPENS A POPUP OF A TELERIK FILE MANAGER THAT ALLOWS FOR THE INDIVIDUAL TO PLACE A PDF ASSOCIATED WITH THAT ITEM INTO THE FOLDER *@
<TelerikWindow Width="400px" Height="fit-content" Centered="true" @bind-Visible="@IsUploadFileWindowVisible">
    <WindowTitle>
        <strong>Upload SDS File</strong>
    </WindowTitle>

    <WindowActions>
        <WindowAction Name="Close" OnClick="@(() => IsUploadFileWindowVisible = !IsUploadFileWindowVisible)" />
    </WindowActions>

    <WindowContent>
        <TelerikUpload Multiple="false"
                       SaveUrl="@SaveUrl"
                       RemoveUrl="@RemoveUrl"
                       OnSuccess="@OnFileUploadSuccess"
                       AllowedExtensions="@AllowedExtensions"
                       MaxFileSize="10485760"/>

    </WindowContent>
</TelerikWindow>


@code {

    private bool IsUploadFileWindowVisible { get; set; } = false;
    private List<SDSModel> SDSItemsList = new();
    private SDSModel? CurrentItem { get; set; } = new SDSModel();
    private List<string> AllowedExtensions = new List<string> { ".pdf" };
    private bool CanSaveUpload { get; set; } = false;
    private string SaveUrl = String.Empty;
    private string RemoveUrl = String.Empty;

    public void ToggleUploadWindow(SDSModel item)
    {
        CurrentItem = item;
        SaveUrl = $"{NavigationManager.BaseUri}api/Upload/SavePdf?rev={item.Revision}";
        RemoveUrl = $"{NavigationManager.BaseUri}api/Upload/RemovePdf";
        IsUploadFileWindowVisible = !IsUploadFileWindowVisible;
    }

    private void NavigateToViewSDSFile(string fileName)
    {

        if (!string.IsNullOrEmpty(fileName))
        {
            string fileUrl = $"/SafetyDataSheets/{fileName}";
            NavigationManager.NavigateTo(fileUrl, forceLoad: true);
        }
        else
        {
            Console.WriteLine("No document found for the specified file name.");
        }
    }


    private async Task OnFileUploadSuccess(UploadSuccessEventArgs args)
    {
        if (CurrentItem != null && args.Files.Count > 0)
        {
            var uploadedFile = args.Files[0];
            string fileName = uploadedFile.Name;

            // Check if a file with the same name already exists in the database
            bool fileExists = await SDSModel.FileExistsAsync(fileName);

            if (fileExists)
            {
                var existingItem = await SDSModel.GetSDSItemByFileNameAsync(fileName);
                if(existingItem != null)
                {
                    existingItem.CurrentVersion = false;
                    await SDSModel.UpdateOldSDSItemAsync(existingItem.FileName, UserModel.EmployeeID);

                    CurrentItem.Revision = existingItem.Revision + 1;
                    fileName = $"{Path.GetFileNameWithoutExtension(uploadedFile.Name)}_rev{CurrentItem.Revision}{Path.GetExtension(uploadedFile.Name)}";
                }
            }

            CurrentItem.FileName = fileName;
            CurrentItem.FileExists = true;
            CurrentItem.CurrentVersion = true;
        }
    }

    private async Task OnUpdate(GridCommandEventArgs args)
    {
        var item = args.Item as SDSModel;
        if (item != null)
        {
            item.EditedBy = UserModel.EmployeeID;
            await SDSModel.SaveSDSItemAsync(item);
            SDSItemsList = await SDSModel.GetSDSItemsAsync();
        }
    }

    private async Task OnDelete(GridCommandEventArgs args)
    {
        var item = args.Item as SDSModel;
        if (item != null)
        {
            await SDSModel.DeleteSDSItemAsync(item);
            SDSItemsList = await SDSModel.GetSDSItemsAsync();
        }
    }


    protected override async Task OnInitializedAsync()
    {
        SDSItemsList = await SDSModel.GetSDSItemsAsync();
        await base.OnInitializedAsync();
    }

}

Glenn
Top achievements
Rank 1
Iron
Iron
 answered on 23 Dec 2024
1 answer
59 views

Hi, my application layout has 2 default drawer (left one as Push and Right one as Overlay).

To handle this layout i used the suggestion on:

https://www.telerik.com/forums/nested-drawer-for-menu-on-left-and-right

The application is managed with this gerarchy:

- Right drawer

- Left drawer inside right drawer content

- Application components inside Left drawer content

 

Now i need a side panel inside of some application compoents: note who i don't need menu items, but only a side panel with a custom component on it, but i have not found a telerik component to handle it.

There is a telerik component to handle an overlay side panel (other than TelerikDrawer)? 

I tried to add another TelerikDrawer with a custom template, but is seem not working.

Adding a Drawer in one of my application components result in unexpected behaviour: the left drawer is rendered on the right side of the screen.

 

Any suggestion? thanks

 

 

Dimo
Telerik team
 answered on 20 Dec 2024
1 answer
60 views

Out of the box, after updating today to 7.1.0, converted the Weather page from table to TelerikGrid component and the date was being displayed with coma as separator. My html tag's lang was set to en-US, and the SatelliteResourceLanguage property was set to en-US, my OS's regional setting is US and yet the display was European culture.


            var cult = CultureInfo.GetCultureInfo( "en-US" );
            CultureInfo.DefaultThreadCurrentCulture = cult;
            CultureInfo.DefaultThreadCurrentUICulture = cult;

Adding the above code, resolved the issue. But my expectation is to default to the system's culture even when the application is supporting globalization/localization.

Dimo
Telerik team
 answered on 20 Dec 2024
1 answer
58 views

Hi, 

I couldn't find any articles about customizing Telerik components with additional properties,
but want to add my own property directly to a Telerik component, like this:
<TelerikWindow MyOwnProperty="SomeValue" />

I would like to avoid creating a custom wrapper component where I would use the Telerik component inside.
Is there any way to achieve this directly with Telerik components without having to wrap them?

Huge thanks for your response,
Bohdan

 
Tsvetomir
Telerik team
 answered on 18 Dec 2024
1 answer
27 views

I want to have a MultiSelect experience for a field in a ListView editor. I'd like the binding to work with the model's navigation collection instead of an ancillary Id collection.

Take the following example where we have a ListView of Appointments. An Appointment has a collection of Contacts called Attendees that we want to manage on Create and Edit with a MultiSelect.

TelerikMultiSelect doesn't like a bind-value with a collection of objects - it wants Ids. One way to solve this could be to do gymnastics with an extra AttendeeIds collection on the Appointment and synchronize that collection with the navigation entities on read/create/update. Is there a way to avoid the gymnastics and solve this case more directly? 

Can you provide an example? Thanks.


<TelerikListView TItem="Appointment"...>
...
<EditTemplate> <TelerikMultiSelect Data="@Contacts" Placeholder="Select attendees" AutoClose="false" @bind-Value="@context.Attendees" <-this does not work TextField="@nameof(Contact.Name)" ValueField="@nameof(Contact.Id)" DebounceDelay="0" /> </EditTemplate>
...
</TelerikListView> List<Contact> Contacts {get; set;} =[]; //loaded in oninitializeasync public class Appointment { public Guid Id {get; set;} public List<Contact> Attendees {get; set;} } public class Contact { public Guid Id {get; set;} public string Name {get; set;} }
...

Hristian Stefanov
Telerik team
 answered on 18 Dec 2024
0 answers
48 views

I'm receiving the following error when I tab from the last row in group to the next group.

Unhandled exception rendering component: No parameterless constructor defined for type 'Telerik.Blazor.Components.Grid.Grouping.GridGroup'.
System.MissingMethodException: No parameterless constructor defined for type 'Telerik.Blazor.Components.Grid.Grouping.GridGroup'.

Here is my grid.

 <TelerikGrid @ref="@TheGrid" Data="Mappings"
              Groupable="true"
              OnStateInit="@((GridStateEventArgs<object> args) => OnStateInitHandler(args))"
              OnRead="@ReadHandler"
              OnUpdate="@UpdateHandler"
              EditMode="@GridEditMode.Incell"
              Pageable="true"
              PageSize="15" RowHeight="32"
              Navigable="true" Sortable="true">
     <GridToolBarTemplate>
         <GridSearchBox Width="200px"></GridSearchBox>
         <span class="k-toolbar-spacer"></span>
         <GridCommandButton Command="ExcelExport" Icon="@SvgIcon.FileExcel">Export to Excel</GridCommandButton>
         <GridCommandButton Command="CsvExport" Icon="@SvgIcon.FileCsv">Export to CSV</GridCommandButton>
     </GridToolBarTemplate>
     <GridColumns>
         <GridColumn Field="@nameof(SiteMappingDto.SiteName)" FieldType="@typeof(string)" Title="Site" Editable="false" />
         <GridColumn Field="@nameof(SiteMappingDto.SiteReference)" FieldType="@typeof(string)" Title="Reference" Editable="false" />
         <GridColumn Field="@nameof(SiteMappingDto.TagName)" FieldType="@typeof(string)" Title="Tag" Editable="false" />
         <GridColumn Field="@nameof(SiteMappingDto.TagDescription)" FieldType="@typeof(string)" Title="Description" Editable="false" />
         <GridColumn Field="@nameof(SiteMappingDto.MappingValue)" FieldType="@typeof(string)" Title="Value" Editable="true" />
     </GridColumns>
 </TelerikGrid>

And the dto used:
 public class SiteMappingDto
 {
     public SiteMappingDto()
     {
     
     }

     public int Id { get; set; }
     public string? SiteName { get; set; }
     public string? SiteReference { get; set; }
     public string? TagName { get; set; }
     public string? TagDescription { get; set; }
     public int TagOrder { get; set; }
     public string? MappingValue { get; set; }
 }

 

 

Robert
Top achievements
Rank 1
Iron
 asked on 18 Dec 2024
Top users last month
Anislav
Top achievements
Rank 6
Silver
Bronze
Bronze
Jianxian
Top achievements
Rank 1
Iron
Marco
Top achievements
Rank 3
Iron
Iron
Iron
Jim
Top achievements
Rank 2
Iron
Iron
Nurik
Top achievements
Rank 2
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?