How to initialize a MultSelect with previous selections using a remote paged datasource?

Hi,


I have a MultiSelect with my CustomDataAdaptor to access a remote data source that can have thousands of product items where the API returns pages with a maximum of 50 records.


The control does the search properly, displays the selected items on chips with the Product Description (VisualMode.Box), is limited to select a maximum of 50 items, and is working fine.


The point is, this selection needs to be saved for later use or review. So I need a way to bring this control already populated with that selection, as if it were in the "same state" as when the initial selection was made and still allow the user to search and make new selections.


As the saved selection can have products located in any "API page", I know that when initializing the DataSource I need to bring all selected Ids from the API, allowing the control to correctly display the chips with the descriptions of the selected products..


I used the Query property with a WhereFilter with the list of Ids to bring from the API only the records previously selected in the component's initialization and it worked well too.


Okay, now I just need to clear this WhereFilter to allow the user to access all other products to be able to make new selections.


The problem is that this forces the DataSource to reload and clears my selection.


I tried using the Custom FIlter (below) to update my _query property in the new search, however a "new Query()" clears the current selection.


private void onFilter(FilteringEventArgs args)

 {

        args.PreventDefaultAction = true;

        var query = new Query().Search(args.Text, new List<string> {"Description"});


        _query = string.IsNullOrEmpty(args.Text) ? new Query() : query ;

}


Setting the Query property to null didn't work either.


Could you please guide me on how to achieve this goal?



Thanks,


Sergio Sant'Anna


26 Replies

BC Berly Christopher Syncfusion Team December 9, 2021 05:07 PM UTC

Hi Sergio, 
  
Greetings from Syncfusion support. 
  
We will check and update the further details in two business days (13th December 2021). We appreciate your patience until then. 
  
Regards, 
Berly B.C 



DR Deepak Ramakrishnan Syncfusion Team December 16, 2021 04:28 PM UTC

Hi Sergio, 
 
Thanks for your patience. 
 
 
We request you to create new instances of Query (new Query()) as you have used in the provided snippet instead of setting null to it  . It will work as expected i.e it will load all the items in the datasource like initial loading of the popup . Kindly refer the below highlighted code for reference. 
 
 
 
private void onFilter(FilteringEventArgs args) 
 { 
        args.PreventDefaultAction = true; 
        var query = new Query().Search(args.Text, new List<string> {"Description"}); 
 
        _query = string.IsNullOrEmpty(args.Text) ? new Query() : query ; 
} 
 
 
If this does not meet your requirement , Kindly update the use case for updating null for the query . 
 
Thanks, 
Deepak R. 



SS Sergio Sant'Anna December 16, 2021 05:34 PM UTC

Hi,


Thanks for the feedback, but maybe I can't make myself understood.


As I mentioned, I had already tried both situations. Creating a new instance (new Query()) or assigning null has the same unwanted effect and clears my selection.


How to change my WhereFilter clause and keep previous selection?


Regards,


Sérgio Sant'Anna




BC Berly Christopher Syncfusion Team December 17, 2021 04:06 PM UTC

Hi Sergio Sant'Anna, 
  
If you are creating the new instance for the Query, then request will be sent to the server and it will load complete data in the popup. This is the behavior of the component. Based on the shared details, we suspect that you want to maintain the previous selection of the multiselect component. So, we suggest you to use our HideSelectedItem property which help you to maintain the previously selected item in the popup. 
  
  
  
<SfMultiSelect TValue="string[]" TItem="Countries" Placeholder="e.g. Australia" DataSource="@Country" HideSelectedItem=false> 
    <MultiSelectFieldSettings Text="Name" Value="Code"></MultiSelectFieldSettings> 
</SfMultiSelect> 
 
  
Regards, 
Berly B.C 



SS Sergio Sant'Anna December 20, 2021 01:25 PM UTC

Hi,


Thanks for the feedback, but changing the HideSelectedItem property didn't cause any change in my case.


The documentation for this property is vague and just says "Hides the selected item from the list item", which doesn't really explain what behaviors are changed.


Here's my component code:


@using Syncfusion.Blazor
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.DropDowns

<SfMultiSelect @ref=@_multiSelectRef
               TValue="string[]"
               TItem="ProductDto"
               Query=@_query
               @bind-Value=@Value
               AllowFiltering="true"
               HideSelectedItem="false"
               Placeholder="Products"
               FilterBarPlaceholder="Search"
               [email protected]
               FloatLabelType="FloatLabelType.Auto"
               EnableSelectionOrder="false"
               ShowDropDownIcon="true"
               PopupHeight="350px"
               CssClass="e-outline e-multi-column">


    <SfDataManager Adaptor="Adaptors.CustomAdaptor">
        <MyProductDataAdaptor />
    </SfDataManager>


    <MultiSelectTemplates TItem="ProductDto">
        <HeaderTemplate>
            <table>
                <tr>
                    <th class="e-text-left" width="30px">Id</th>
                    <th width="250px">Description</th>
                </tr>
            </table>
        </HeaderTemplate>


        <ItemTemplate>
            <div>
                <table>
                    <tbody>
                        <tr>
                            <td class="e-text-left" width="30px">@((context).Id)</td>
                            <td width="250px">@((context).Description)</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </ItemTemplate>
    </MultiSelectTemplates>


    <MultiSelectFieldSettings Text="Description" Value="Id" />
    <MultiSelectEvents TValue="string[]" TItem="ProductDto"
                       ValueChange=@onValueChanged
                       DataBound=@onDataBoundHandler />
</SfMultiSelect>


@code
{
    private Query? _query;
    private bool _firstExecution = true;
    private SfMultiSelect<string[], ProductDto> _multiSelectRef = default!;


    [Parameter] public string[]? Value { get; set; }
    [Parameter] public EventCallback<string[]> ValueChanged { get; set; }


    protected override void OnParametersSet()
    {
        base.OnParametersSet();

 if (Value is not null && Value.Any())
        {
            var whereFilters = new List<WhereFilter>();

            foreach (var id in Value)
            {
                whereFilters.Add(new() { Field = "Id", Operator = "equal", value = id });
            }

            _query = new Query().Where(whereFilters).Take(50);
        }
        else
        {
            _query = new Query().Take(10);
        }
    }


    private async Task onValueChanged(MultiSelectChangeEventArgs<string[]> args)
    {
        await ValueChanged.InvokeAsync(args.Value);
    }


    private void onDataBoundHandler(DataBoundEventArgs obj)
    {
        if (_firstExecution)
        {
            _firstExecution = false;

            _query = new Query();
​//_query!.Queries.Where = new List<WhereFilter>();
        }
    }
}


My previous selection is still cleared when I assign a new instance to the Query property. Line:

 _query = new Query();


The closest I got to achieving my goal was cleaning up the Where filters, replacing the new Query() with this line:

_query!.Queries.Where = new List<WhereFilter>();


But now only selected items are displayed when the popup is opened by mouse click and I can only see the other items if I start typing.


This behavior is different from when I make my initial selection.


How can I resolve this last point? Is there a better way to reach my goal?



Regards,

Sérgio Sant'Anna



BC Berly Christopher Syncfusion Team December 21, 2021 04:57 PM UTC

Hi Sergio Sant'Anna, 
  
We have checked the shared code and the previous selection maintained correctly on popup open action. So, we have prepared the sample and attached it below. 
  
  
Still issue persists, share any video demonstration along with issue replication procedure that will help us to check and proceed further from our end. 
  
Regards, 
Berly B.C 



SS Sergio Sant'Anna December 22, 2021 04:03 PM UTC

Hi Berly Christopher,


Thanks for the most complete example. I made some modifications and was able to reproduce exactly the issues I am reporting.


Think of a use case where a user has a Form and makes some selections, saves it, and then can modify it later.


The main modification was to reproduce the selection behavior when initializing the control with a previous selection that has items located on different 'pages' of the remote result.


In this modified example, there are now a total of 1000 items, and I also use two instances of the same control, the first without a pre-existing selection and the other with a previous selection on items: 2, 51, 101, 552 and 905.


My goal is to get both instances to behave exactly the same, when performing basic control tasks like: displaying available items in the popup, searching, modifying the existing selection, or when the selection is cleared and I redo one from the beginning.


The main difference in behavior can already be seen when clicking to open the popup with available items. In the control with pre-selection only selected items are displayed and if the selection is cleared by the X button, when clicking again on the popup no available items are displayed.


To explore other differences, try to start manually selecting the same 4 items in the first instance and after selected, browse both components and you can see the behavior differences in the display of items available in the popups.


Could you please guide me on how I can resolve these issues and achieve these goals?


Regards,

Sérgio Sant'Anna


Attachment: Custom_adaptor_MultiSelect404387905Mod_70960444.zip


BC Berly Christopher Syncfusion Team December 23, 2021 02:10 PM UTC

Hi Sergio Sant'Anna, 
  
We will validate and update the further details in two business days (28th December 2021). 
  
Regards, 
Berly B.C 



BC Berly Christopher Syncfusion Team December 28, 2021 05:01 PM UTC

Hi Sergio Sant'Anna, 
  
We need two more days to validate the issue at our end. So, we will validate and provide the details on 30th December 2021. 
  
Regards, 
Berly B.C 



BC Berly Christopher Syncfusion Team December 30, 2021 04:59 PM UTC

Hi Sergio Sant'Anna, 
  
We have checked the shared sample. In the shared sample, you have invoked the ValueChanged event in the ValueChange event. Due to this, the selected value gets removed from the popup. So, we suggest you to remove that event invoke action to get rid of the reported issue. 
  
Also, you have modified the query on OnParametersSet life cycle method. Due to this, the life cycle gets called on every time component property gets changes. So, we suggest you to use the life cycle which is called once at page load will help you to get rid of the reported issue.  
  
We suggest you to share the use case requirement for changing the query property on DataBound and OnParametersSet method which help us to check and share the possible solution using our component method. 
  
  
Regards, 
Berly B.C 



SS Sergio Sant'Anna January 3, 2022 02:21 PM UTC

Hi Berly,


Thanks for the feedback. Maybe it's a language issue and I'm sorry if I didn't make myself understood. Because I believe I've been sharing my requirements in a lot of detail.


Let's try again.


The use case for changing the query property in the DataBound is that after initializing the control already populated with the previous selection, I need to clear this initial query to allow the user to browse and select any other of the 1000 Products in this example.


I used OnParametersSet because it was also how I could make the control keep the selection after changing the query property in onDataBoundHandler. Doing the same using your OnAfterRender suggestion will clear the previous selection. Uncomment my code in onDataBoundHandler and you will see this behavior.


Another unwanted behavior in this modified code is that it is now not possible to select more items in the second control with pre-selection, which also does not meet what I explained earlier in the paragraph:


"The point is, this selection needs to be saved for later use or review. So I need a way to bring this control already populated with that selection, as if it were in the "same state" as when the initial selection was made and still allow the user to search and make new selections."


It also changed the behavior in the first control without pre-selection, now when you click to open it without typing a search the popup opens with "No Records Found".


Regards,

Sérgio Sant'Anna




BC Berly Christopher Syncfusion Team January 4, 2022 02:38 PM UTC

Hi Sergio, 
  
We will check the reported case and provide further details in two business days (6th January 2022). We appreciate your patience until then. 
  
Regards, 
Berly B.C 



PM Ponmani Murugaiyan Syncfusion Team January 10, 2022 03:48 PM UTC

Hi Sergio,


Currently we are checking the reported query, we will update further details in 2 business days (January 12, 2022). We appreciate your patience until then.


Regards,
Ponmani M




PM Ponmani Murugaiyan Syncfusion Team January 19, 2022 03:10 AM UTC

Hi Sergio, 

Sorry for the delay. 

We would like to know you that with the EnableVirtualization support, if you would like to bind the pre-selected value for the Multiselect component and if it is beyond the taken query of 10 items, then automatically it will load the items in the popup and update the value property. So while scrolling the remaining items will be updated in the popup.  

You can refer the below sample for your requirement to set the pre-defined values to the component with Multiselect custom adaptor. 

<SfMultiSelect ID="Dropdown1" TValue="int[]" TItem="WeatherForecast" Query="Query" @bind-Value="@MultiVal" PopupHeight="150px" EnableVirtualization="true"> 
    <SfDataManager @ref="dataManagerObj" AdaptorInstance="@typeof(CustomAdaptor)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager> 
    <MultiSelectFieldSettings Value="ID" Text="Summary"></MultiSelectFieldSettings> 
</SfMultiSelect> 
 
@code{ 
    //Custom adaptor 
    SfMultiSelect<int[], WeatherForecast> MultiselectObj; 
    SfDataManager dataManagerObj; 
    public int[] MultiVal { get; set; } = new int[] { 1001, 1004, 1008}; 
    public Query Query = new Query().Take(6); 
 

 


Regards, 
Ponmani M 



SS Sergio Sant'Anna January 20, 2022 01:13 PM UTC

Hi Ponmani,


Thanks for the feedback, but unfortunately this proposal doesn't reflect my use case and I can't understand how this meets my original request.


We've had several iterations and in the last few we've come very close to solving the problem. We arrived at this using a code I submitted on Dec 22-2021 that shows exactly my use case and the problem I faced.


Could you please analyze it in more depth and propose a new solution by modifying this sample I sent?


Regards,

Sérgio Sant'Anna



PM Ponmani Murugaiyan Syncfusion Team January 24, 2022 02:59 AM UTC

Hi Sergio,  

Currently we are checking your reported query, we need additional time to investigate further, will update further details in 2 business days. 

Regards,  
Ponmani M 



DR Deepak Ramakrishnan Syncfusion Team January 26, 2022 12:32 PM UTC

Hi Sergio, 
 
We need additional time to validate the requirement . We will update the details in two business days(28th,January 2022) . 
 
 
Thanks, 
Deepak R. 



SS Sergio Sant'Anna February 4, 2022 04:07 PM UTC

Hi,


Any updates on this?


Regards,

Sérgio Sant'Anna



PM Ponmani Murugaiyan Syncfusion Team February 7, 2022 04:27 PM UTC

Hi Sergio, 

Sorry for the inconvenience caused. 

We need additional time to investigate further on this query, we will update further details in 2 business days (February 9, 2022). We appreciate your patience until then. 

Regards, 
Ponmani M 



PM Ponmani Murugaiyan Syncfusion Team February 10, 2022 06:40 PM UTC

Hi Sergio, 

Sorry for the delay. 

Query1: This selection needs to be saved for later use or review. So I need a way to bring this control already populated with that selection, as if it were in the "same state" as when the initial selection was made. 
 
If you would like to maintain the previous selection of the component on state change, we suggest you to enable the property EnablePersistance. This will always persist the value state with previous selection in the component of page reloads. 
 

Query2: But now only selected items are displayed when the popup is opened by mouse click and I can only see the other items if I start typing. 
 
We suggest you to modify the query in focus event or open event to show the entire data to filter the item. Here in the Read method, updated the count variable with take from the query property. If take contains 0 items, then updated the whole data in the count to fetch the all items. 

  public void onFocus() 
    { 
        _query = new Query().Where(new WhereFilter()); 
    } 
 

public override object Read(DataManagerRequest dataManagerRequest, string key = null) 
        { 
            try 
            { 
                 
                var req = (dataManagerRequest == null) ? "null" : Newtonsoft.Json.JsonConvert.SerializeObject(dataManagerRequest); 
 
                System.Diagnostics.Debug.WriteLine("Reading custom adaptor. Key is " + key + ", req: " + req); 
                int count; 
                if (dataManagerRequest.Take != 0) { 
                    count = dataManagerRequest.Take; 
                } else 
                { 
                    count = 1000; 
                } 
 

Modified the sample as per your requirement, please find below: 

Regards, 
Ponmani M 



SS Sergio Sant'Anna February 11, 2022 07:39 PM UTC

Hi Ponmani,


Thanks for the feedback, but unfortunately none of the suggestions are applicable.


Using 'EnablePersistance' doesn't suit me because the previous selection comes from a database and it will be different depending on the user's choice.


The suggested use of 'Focus' creates a side effect in the control that clears selected items only from the screen. Maybe you didn't notice this in your example. And finally, modifying Take to send all items is not a viable option for my API with thousands of records.


I'll try to explain my use case another way, and maybe you have some other suggestion:


I have a CRUD form like any other, with SfTextBoxes, Checkboxes and etc. and also with some of these SfMultiselects. Like any form editing action, all these controls must already appear populated for a user to make changes.


The difficulty is to initialize the SfMultiselect with the proper selections when this control depends on a paged RestAPI data source with thousands of records.


The million dollar question is: How can I initialize this control correctly displaying the 'chips' with the descriptions of the selected items as happens in a fresh selection?


I attached another example code with 3 instances of SfMultiselect that shows the 3 possibilities I need to make it behave the same way.


#1 - Multiselect control initializes without any selection.

#2 - Multiselect control initializes with 3 pre-selected items;

#3 - Multiselect control initializes without any selection, but interactively loads the selection of 2 items when clicking a 'Load Selection' button.


Please do the steps below:


1st - In instance #1, manually select 3 items. For example: #5, #50 and #505.


2nd - In instance #3, click on the Load Selection button. Once items #3 and #303 have been populated, try adding item #305.


3rd - In instance #2 try to select item #505.



What is desired is that instances 2 and 3 behave exactly the same as the first instance in step 1. (open popup on click, display available items, allow selecting new items, etc.).


You will see that changing the selection in one of the instances interferes with the functioning of the others, and also that the control stops behaving as expected in all of them.


Please see if you can achieve the expected behavior and if possible modify my example with such tweaks.



Regards,

Sergio Sant'Anna


Attachment: Blazor_Date_App202202111633_aaebde7d.zip


PM Ponmani Murugaiyan Syncfusion Team February 14, 2022 05:27 PM UTC

Hi Sergio, 

Currently we are checking your requirement, will update further details in 2 business days (February 16, 2022). 

Regards, 
Ponmani M 



PM Ponmani Murugaiyan Syncfusion Team February 16, 2022 05:34 PM UTC

Hi Sergio,  

We need additional time to investigate this query, will update further details in 2 business days (February 18, 2022).  

Regards,  
Ponmani M 



PM Ponmani Murugaiyan Syncfusion Team March 18, 2022 03:46 PM UTC

Hi Sergio,  

Sorry for the delay. 

On further investigation of the reported issue, We suggest you to modify the query in focus event or open event to show the entire data to filter the item. Here in the Read method, updated the count variable with take from the query property. If take contains 0 items, then updated the whole data in the count to fetch the all items as previously suggested. 

Regards, 
Ponmani M 



SS Sergio Sant'Anna March 21, 2022 05:55 PM UTC

Hi Ponmani M,


Thanks for the feedback, but due to the lack of SfMultiselect features for advanced scenarios like this, we developed our own component.


Regards,


Sergio Sant'Anna



PM Ponmani Murugaiyan Syncfusion Team March 22, 2022 05:25 AM UTC

Hi Sergio, 

Thanks for the update. Please get back us if you need further assistance. 

Regards, 
Ponmani M 


Loader.
Up arrow icon