@@ -309,4 +309,156 @@ else if (!string.IsNullOrEmpty(orderStatusMessage))
309309 }
310310}
311311````
312+ ```` MultiSelect
313+ @using System.Collections.ObjectModel
314+
315+ <TelerikMultiSelect Value="@CurrentOrder.Categories" Data="@Categories" Placeholder="Select Categories"
316+ TextField="CategoryName" ValueField="CategoryId" Filterable="true"
317+ ValueChanged="@( (List<int> c) => CategorySelected(c) )">
318+ </TelerikMultiSelect>
319+
320+ <TelerikMultiSelect Value="@CurrentOrder.Products" Data="@CurrentProducts" Placeholder="Select Products" Filterable="true"
321+ TextField="ProductName" ValueField="ProductId" Enabled="@( CurrentOrder.Categories.Count > 0 )"
322+ ValueChanged="@( (List<int> p) => ProductSelected(p) )">
323+ </TelerikMultiSelect>
324+
325+ @* This sample has only two dropdowns as even dummy data becomes rather long for a multiselect scenario, even for a demo
326+ The last item could use @bind-Value instead of a handler, this just showcases the main concept. *@
327+
328+ <TelerikButton Enabled="@( CurrentOrder.Products.Count > 0 )" OnClick="@SendOrder">Send Order</TelerikButton>
329+
330+ @if (CurrentOrder.Products.Count > 0)
331+ {
332+ <h5>Order Summary</h5>
333+ <ul>
334+ @foreach (var item in CurrentOrder.ChosenProducts)
335+ {
336+ <li>@item.ProductName from category @item.CategoryId</li>
337+ }
338+ </ul>
339+ }
340+ else if (!string.IsNullOrEmpty(orderStatusMessage))
341+ {
342+ <div class="alert alert-success">@orderStatusMessage</div>
343+ }
344+
345+ @code{
346+ // data sources
347+ List<Category> Categories { get; set; }
348+ List<Product> AllProducts { get; set; }
349+ ObservableCollection<Product> CurrentProducts { get; set; } = new ObservableCollection<Product>();
350+ // model
351+ Order CurrentOrder { get; set; } = new Order();
352+
353+ string orderStatusMessage { get; set; } // UI related for the sample
354+
355+ // generate data we will be using in this example
356+ protected override void OnInitialized()
357+ {
358+ base.OnInitialized();
359+
360+ Categories = Enumerable.Range(1, 6).Select(x => new Category
361+ {
362+ CategoryId = x,
363+ CategoryName = $"Category {x}"
364+ }).ToList();
365+
366+ AllProducts = Enumerable.Range(1, 50).Select(x => new Product
367+ {
368+ ProductId = x,
369+ ProductName = $"Product {x}",
370+ CategoryId = (int)Math.Ceiling((double)x % 7)
371+ }).ToList();
372+ }
373+
374+ //ValueChanged handlers - implementation of cascading dropdowns
375+ void CategorySelected(List<int> categories)
376+ {
377+ if (categories.Count == 0) // the user deselected all
378+ {
379+ //reset the "form" / process
380+ CurrentOrder = new Order();
381+ return;
382+ }
383+
384+ // cascade the selection by filtering the data for the next dropdown
385+ CurrentProducts.Clear();
386+ foreach (var item in categories)
387+ {
388+ var productForCategory = AllProducts.Where(p => p.CategoryId == item);
389+ foreach (var p in productForCategory)
390+ {
391+ CurrentProducts.Add(p);
392+ }
393+ }
394+ CurrentProducts.OrderBy(p => p.ProductId);
395+
396+
397+ // get the selected models from the data source and use them
398+ CurrentOrder.Categories.Clear();
399+ CurrentOrder.ChosenCategories.Clear();
400+ foreach (var item in categories)
401+ {
402+ Category SelectedCategory = Categories.Where(c => c.CategoryId == item).First();
403+ CurrentOrder.Categories.Add(item);
404+ // business logic
405+ CurrentOrder.ChosenCategories.Add(SelectedCategory);
406+ }
407+ }
408+
409+ void ProductSelected(List<int> products)
410+ {
411+ if (products.Count == 0) // the user deselected all
412+ {
413+ //reset the "form" / process
414+ CurrentOrder.Products = new List<int>();
415+ CurrentOrder.ChosenProducts = new List<Product>();
416+ return;
417+ }
418+
419+
420+ // get the selected models from the data source and use them
421+ CurrentOrder.Products.Clear();
422+ CurrentOrder.ChosenProducts.Clear();
423+ foreach (var item in products)
424+ {
425+ Product SelectedProduct = AllProducts.Where(p => p.ProductId == item).First();
426+ CurrentOrder.Products.Add(item);
427+ // business logic
428+ CurrentOrder.ChosenProducts.Add(SelectedProduct);
429+ }
430+ }
431+
432+ // sample notification of success and resetting of the process, data classes
433+ async void SendOrder()
434+ {
435+ CurrentOrder = new Order();
436+ orderStatusMessage = "Thank you for your order!";
437+ await Task.Delay(2000);
438+ orderStatusMessage = "";
439+ StateHasChanged();
440+ }
441+
442+ public class Category
443+ {
444+ public int CategoryId { get; set; }
445+ public string CategoryName { get; set; }
446+ }
447+
448+ public class Product
449+ {
450+ public int CategoryId { get; set; }
451+ public int ProductId { get; set; }
452+ public string ProductName { get; set; }
453+ }
454+
455+ public class Order
456+ {
457+ public List<int> Categories { get; set; } = new List<int>();
458+ public List<int> Products { get; set; } = new List<int>();
459+ public List<Category> ChosenCategories { get; set; } = new List<Category>();
460+ public List<Product> ChosenProducts { get; set; } = new List<Product>();
461+ }
462+ }
463+ ````
312464
0 commit comments