Unplanned
Last Updated: 10 Jun 2020 06:43 by ADMIN
ben
Created on: 15 Mar 2020 11:10
Category: ComboBox
Type: Feature Request
7
Combobox Virtualization

Transitioning our application from Telerik React to Blazor, our comboboxes in our React application are hooked up to OData endpoints because of the amount of data they could display, some as large as 30mb of json.

Server filtering, https://feedback.telerik.com/blazor/1447481-server-filtering-with-custom-data-request-event-that-can-accommodate-remote-data, almost works, however:

  • I can't set PageSize on the combobox
  • I can't set TotalCount on the combobox
  • Using Telerik.Blazor.ExtensionMethods.ToOdataString throws a NullReferenceException when I try to use it in the ReadItems method with the ComboBoxReadEventArgs args.Reqeuest.ToOdataString()

I tried setting up my combobox like my OData Grid, i.e.


<TelerikComboBox Data="@Dtos"
                         OnRead="@ReadItems"
                         Filterable="true"
                         Placeholder="Find what you seek by typing"
                         @bind-Value="@SelectedValue"
                         TextField="Name" 
                         ValueField="Id"
                         Pageable="true" 
                         PageSize="20" 
                         TotalCount=@Dtos.Count
                         >

However it throws an exception:

blazor.webassembly.js:1 WASM: System.InvalidOperationException: Object of type 'Telerik.Blazor.Components.TelerikComboBox`2[[MyType, MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Guid, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' does not have a property matching the name 'Pageable'.

Was hoping this would 'just work' like it does with the Grid, which is amazing!

4 comments
ADMIN
Marin Bratanov
Posted on: 10 Jun 2020 06:43

A second idea would be to simulate a dropdown through an animation container and put a grid with virtualization in it. A basic example (albeit with a treeview in it) is available here: https://feedback.telerik.com/blazor/1456580-dropdowntree

 

Regards,
Marin Bratanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
ADMIN
Marin Bratanov
Posted on: 10 Jun 2020 06:39

For the time being, there are two performance optimizations you can do through OnRead - debounce the filter so the request is sent to the server more rarely not on every keystroke, and to also enforce a min filter length so fewer items are returned: https://docs.telerik.com/blazor-ui/knowledge-base/combo-debounce-onread

 

Regards,
Marin Bratanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
ben
Posted on: 16 Mar 2020 15:48

Marin,

Completely understand...wanted to try and add PageSize, TotalCount, etc while poking around to see if they were lurking in the background and maybe they would "just work".

Excited for this one to be exposed/implemented.  I realize the implementation might not match the Grid implementation...the React Combobox version didn't match the React Grid, but both implementations made sense, and were easy to use.  

At the end of the day they did both "just worked".  Here is hoping this one moves up the priority list!

ADMIN
Marin Bratanov
Posted on: 16 Mar 2020 12:15

Hello Ben,

The combobox does not yet have a virtualization feature, so it does not expose features like PageSize and TotalCount. This is also why adding these parameters to the component breaks the app - they cannot compile because they do not exist.

When such a feature gets implemented, we will document how it is to be used (at this point I cannot say if it will be the exact same parameters as the grid). You can Follow this page to get status updates on the status of this enhancement.

On the .ToODataString() extension method - it is in the Telerik.Blazor.ExtensionMethods namespace, so you need to add a using statement for it.

Here's a basic example of how you can use it as base for further development at the moment:

 

@using Telerik.Blazor.ExtensionMethods
@* needed for the .ToODataString() method *@

@SelectedValue
<br />
<TelerikComboBox Data="@Options"
                 OnRead="@ReadItems"
                 Filterable="true"
                 Placeholder="Find what you seek by typing"
                 @bind-Value="@SelectedValue">
</TelerikComboBox>

@code{
    public string SelectedValue { get; set; }
    List<string> Options { get; set; } = new List<string>();

    async Task ReadItems(ComboBoxReadEventArgs args)
    {
        if (args.Request.Filters.Count > 0) // there is user filter input, skips providing data on initialization
        {
            Telerik.DataSource.FilterDescriptor filter = args.Request.Filters[0] as Telerik.DataSource.FilterDescriptor;
            string userInput = filter.Value.ToString();
            string method = filter.Operator.ToString();

            // For the time being, you need to set the field name that needs to be serialized for the filter.
            // When binding to a complex model you should probably use the TextField
            filter.Member = "someField";
            filter.MemberType = Type.GetType("System.String");


            Console.WriteLine(args.Request.ToODataString());


            //new data collection comes down from the service
            Options = await GetOptions(userInput, method);
        }
        else
        {
            // when there is no user input you may still want to provide data
            // in this example we just hardcode a few items, you can either fetch all the data
            // or you can provide some subset of most common items, or something based on the business logic
            Options = new List<string>() { "one", "two", "three" };
        }
    }

    async Task<List<string>> GetOptions(string userInput, string filterOperator)
    {
        await Task.Delay(500); // simulate network delay, remove it for a real app

        //sample logic for getting suggestions - here they are generated, you can call a remote service
        //for brevity, this example does not use the filter operator, but your actual service can
        List<string> optionsData = new List<string>();
        for (int i = 0; i < 5; i++)
        {
            optionsData.Add($"option {i} for input {userInput}");
        }

        return optionsData;
    }
}

 

 

 

Regards,
Marin Bratanov
Progress Telerik

 UI for Blazor