Skip to content

Commit 530c11c

Browse files
docs(multiseelct): Add info and KB for selected items order (#1153)
Co-authored-by: Dimo Dimov <[email protected]>
1 parent 1b414df commit 530c11c

File tree

2 files changed

+190
-39
lines changed

2 files changed

+190
-39
lines changed
Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
title: Pre-Selecting Items
3-
page_title: MultiSelect Pre-Selecting Items
2+
title: Pre-Select Items
3+
page_title: MultiSelect - Pre-Select Items
44
description: Learn how to pre-select items for the user by exploring a practical example.
55
slug: multiselect-pre-select-items
66
tags: telerik,blazor,multiselect,pre-select
@@ -9,59 +9,82 @@ position: 8
99
---
1010

1111

12-
# Pre-Selecting Items
12+
# Pre-Select MultiSelect Items
1313

14-
This article provides an example that demonstrates how to pre-select items for the end-user. The described approach allows you to pre-select a single item or a set of items if they exist in the data source.
14+
This article provides an example that shows how to pre-select MultiSelect items for the user. The approach allows you to pre-select a single item or a set of items if they exist in the data source.
15+
16+
On page load, the MultiSelect will render the selected items in the order in which these items appear in the `Data` collection. To preserve the order of the initially selected items, [sort the data to match the selected items order]({%slug multiselect-kb-selected-items-order%}).
17+
18+
>caption Pre-select MultiSelect items for the user
1519
16-
>caption Pre-select items for the user
1720
````CSHTML
18-
@* You can pre-select an item or set of items only if they exist in the data source. *@
19-
<div>
20-
<TelerikButton OnClick="@SelectHandler">Pre-select countries</TelerikButton>
21-
<TelerikButton OnClick="@ClearSelectionHandler">Clear selection</TelerikButton>
22-
</div>
23-
<TelerikMultiSelect Data="@Countries"
24-
@bind-Value="@Values"
25-
Placeholder="Enter Balkan country, e.g., Bulgaria"
26-
Width="350px" ClearButton="true" />
27-
@if (Values.Count > 0)
21+
Select IDs
22+
<TelerikNumericTextBox @bind-Value="@Id1" Min="1" Max="10" Width="70px" />
23+
and
24+
<TelerikNumericTextBox @bind-Value="@Id2" Min="1" Max="10" Width="70px" />
25+
26+
<TelerikButton OnClick="@SelectItems">Apply</TelerikButton>
27+
<TelerikButton OnClick="@ClearSelection">Clear Selection</TelerikButton>
28+
29+
<br />
30+
31+
<TelerikMultiSelect Data="@Products"
32+
Value="@SelectedProductIDs"
33+
ValueField="@nameof(Product.Id)"
34+
TextField="@nameof(Product.Name)"
35+
ClearButton="true"
36+
Placeholder="Select Products">
37+
</TelerikMultiSelect>
38+
39+
@if (SelectedProductIDs.Count > 0)
2840
{
41+
<p>Selected Product IDs:</p>
2942
<ul>
30-
@foreach (var item in Values)
43+
@foreach (var id in SelectedProductIDs)
3144
{
32-
<li>@item</li>
45+
<li>@id</li>
3346
}
3447
</ul>
3548
}
49+
3650
@code {
37-
List<string> Countries { get; set; } = new List<string>();
38-
List<string> Values { get; set; } = new List<string>();
39-
void SelectHandler()
51+
private List<Product> Products { get; set; }
52+
private List<int> SelectedProductIDs = new() { 2 };
53+
54+
private int Id1 { get; set; } = 3;
55+
private int Id2 { get; set; } = 5;
56+
57+
private void SelectItems()
4058
{
41-
List<string> PreselectedValues = new List<string>()
42-
{
43-
"Bulgaria", "Croatia"
44-
};
45-
// create a new reference so that the framework can notify the component to update
46-
Values = new List<string>(PreselectedValues);
59+
// reset object reference to trigger re-render
60+
SelectedProductIDs = new List<int>() { Id1, Id2 };
4761
}
48-
void ClearSelectionHandler()
62+
63+
private void ClearSelection()
4964
{
50-
Values = new List<string>();
65+
SelectedProductIDs = new List<int>();
5166
}
67+
5268
protected override void OnInitialized()
5369
{
54-
Countries.Add("Albania");
55-
Countries.Add("Bosnia & Herzegovina");
56-
Countries.Add("Bulgaria");
57-
Countries.Add("Croatia");
58-
Countries.Add("Kosovo");
59-
Countries.Add("North Macedonia");
60-
Countries.Add("Montenegro");
61-
Countries.Add("Serbia");
62-
Countries.Add("Slovenia");
63-
// you can also pre-select items here based on data you fetch, not just on a button click
70+
Products = new List<Product>();
71+
72+
for (int i = 1; i <= 10; i++)
73+
{
74+
Products.Add(new Product()
75+
{
76+
Id = i,
77+
Name = "Product " + i
78+
});
79+
}
80+
6481
base.OnInitialized();
6582
}
83+
84+
public class Product
85+
{
86+
public int Id { get; set; }
87+
public string Name { get; set; }
88+
}
6689
}
67-
````
90+
````
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
title: MultiSelect Reorders and Sorts Selected Items
3+
description: How to disable automatic sorting of Blazor MultiSelect selected items? How to override any reordering of selected MultiSelect values?
4+
type: troubleshooting
5+
page_title: Blazor MultiSelect Reorders and Sorts Selected Items
6+
slug: multiselect-kb-selected-items-order
7+
position:
8+
tags: multiselect
9+
ticketid: 1540543, 1557872
10+
res_type: kb
11+
---
12+
13+
## Environment
14+
15+
<table>
16+
<tbody>
17+
<tr>
18+
<td>Product</td>
19+
<td>MultiSelect for Blazor</td>
20+
</tr>
21+
</tbody>
22+
</table>
23+
24+
25+
## Description
26+
27+
The MultiSelect selected items order changes. The component sorts the list of numbers that represent the selected values. This causes the selected items (tags, chips) to show up in the wrong order. How to override this behavior?
28+
29+
The MultiSelect reorders selected items alphabetically. The items in the initial `Value` collection are in the correct order, but the MultiSelect sorts them. Is there any way to preserve selection order and disable automatic self sorting?
30+
31+
32+
## Cause\Possible Cause(s)
33+
34+
The selected items' order in the MultiSelect `Value` matches the order of these items in the `Data`. This applies to initial page load and when the MultiSelect `Value` changes programmatically.
35+
36+
The MultiSelect creates a collection of its selected items internally, based on `Value` and `Data`. Then, the component uses this internal collection for rendering. That's why the rendered selected items always match the order of the data items. This behavior is related to performance.
37+
38+
39+
## Solution
40+
41+
Sort the MultiSelect `Data`, according to the selected items' order in `Value`. For example, move the selected items to the beginning of the `Data` collection.
42+
43+
Optionally, use the [MultiSelect `OnChange` or `ValueChanged` events]({%slug multiselect-events%}) to reorder the MultiSelect `Data` every time when users select or unselect items. [`Rebind()`]({%slug common-features-data-binding-overview%}#refresh-data) the MultiSelect afterwards to re-render the dropdown.
44+
45+
>caption Reorder MultiSelect Data to match the selected items order in Value
46+
47+
````CSHTML
48+
@* Match the Data order to the Value order *@
49+
50+
<TelerikMultiSelect @ref="@MultiSelectRef"
51+
Data="@Products"
52+
Value="@SelectedProductIDs"
53+
ValueChanged="@( (List<int> newValues) => OnMultiValueChanged(newValues) )"
54+
ValueField="@nameof(Product.Id)"
55+
TextField="@nameof(Product.Name)"
56+
Placeholder="Select Products"
57+
AutoClose="false"
58+
Width="600px">
59+
</TelerikMultiSelect>
60+
61+
@code {
62+
private TelerikMultiSelect<Product, int> MultiSelectRef { get; set; }
63+
64+
private List<Product> Products { get; set; }
65+
66+
private List<int> SelectedProductIDs = new() { 3, 7, 1 };
67+
68+
private async Task OnMultiValueChanged(List<int> newValues)
69+
{
70+
SelectedProductIDs = newValues;
71+
72+
// Optionally, reorder the dropdown items after selection change and rebind.
73+
ReorderItems(Products, newValues);
74+
MultiSelectRef.Rebind();
75+
}
76+
77+
private void ReorderItems(List<Product> products, List<int> selectedIds)
78+
{
79+
var selectedProducts = new List<Product>();
80+
81+
// Obtain the selected Products in the correct order.
82+
foreach (var id in SelectedProductIDs)
83+
{
84+
selectedProducts.Add(Products.Find(x => x.Id == id));
85+
}
86+
87+
Products = Products.Except(selectedProducts).ToList();
88+
// Sort the non-selected Products, otherwise
89+
// the unselected items will remain at the top of the dropdown.
90+
Products.Sort(CompareProducts);
91+
Products.InsertRange(0, selectedProducts);
92+
}
93+
94+
private int CompareProducts(Product x, Product y)
95+
{
96+
return x.Id - y.Id;
97+
}
98+
99+
protected override void OnInitialized()
100+
{
101+
Products = new List<Product>();
102+
103+
for (int i = 1; i <= 10; i++)
104+
{
105+
Products.Add(new Product()
106+
{
107+
Id = i,
108+
Name = "Product " + i
109+
});
110+
}
111+
112+
ReorderItems(Products, SelectedProductIDs);
113+
114+
base.OnInitialized();
115+
}
116+
117+
public class Product
118+
{
119+
public int Id { get; set; }
120+
public string Name { get; set; }
121+
}
122+
}
123+
````
124+
125+
## See Also
126+
127+
* [Data binding a MultiSelect]({%slug multiselect-databind%})
128+
* [Pre-select MultiSelect items]({%slug multiselect-pre-select-items%})

0 commit comments

Comments
 (0)