In this post we will create a Blazor component to be able to select several options in a form. An example would be if we have a form for entering movie data, and we want to be able to select movie genres (action, drama, comedy, etc.) from a list of genres. We can do this with our component.
Result
Step by Step Video
Summary of the Video
Our component will consist mainly of two columns: In the left column you will find the elements that are not selected, and in the right column are the selected elements. We will also have buttons to select and deselect everything.
At the code level, the component will consist of two lists, selected items and non-selected items. The selection and deselection operations will consist of moving elements from one list to another.
In the end, our component will consist of about 50 lines of code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="multiple-selector"> | |
<ul class="selectable-ul"> | |
@foreach (var item in NoSelected) | |
{ | |
<li @onclick="@(() => Select(item))">@item.Value</li> | |
} | |
</ul> | |
<div class="multiple-selector-buttons"> | |
<button type="button" @onclick="SelectAll">>></button> | |
<button type="button" @onclick="DeselectAll">@removeAllText</button> | |
</div> | |
<ul class="selectable-ul"> | |
@foreach (var item in Selected) | |
{ | |
<li @onclick="@(() => Deselect(item))">@item.Value</li> | |
} | |
</ul> | |
</div> | |
@code { | |
private string removeAllText = "<<"; | |
[Parameter] | |
public List<MultipleSelectorModel> NoSelected { get; set; } = new List<MultipleSelectorModel>(); | |
[Parameter] | |
public List<MultipleSelectorModel> Selected { get; set; } = new List<MultipleSelectorModel>(); | |
private void Select(MultipleSelectorModel item) | |
{ | |
NoSelected.Remove(item); | |
Selected.Add(item); | |
} | |
private void Deselect(MultipleSelectorModel item) | |
{ | |
Selected.Remove(item); | |
NoSelected.Add(item); | |
} | |
private void SelectAll() | |
{ | |
Selected.AddRange(NoSelected); | |
NoSelected.Clear(); | |
} | |
private void DeselectAll() | |
{ | |
NoSelected.AddRange(Selected); | |
Selected.Clear(); | |
} | |
} |
We can see that we have UI with two lists, and that a method is executed when we click on a list item. This to select or deselect the element, as appropriate.
As I mentioned, the selection and deselection operations consist of moving an item from one list to another. For example, to select an item, we move it from the NoSelected list and to the Selected list:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void Select(MultipleSelectorModel item) | |
{ | |
NoSelected.Remove(item); | |
Selected.Add(item); | |
} |
We use a ViewModel (POCO, or Plain Old CLR Object) data type of an individual item. This allows us to have flexibility in implementing new functionalities in our component. For example, if we wanted to add a property that prevents the user from selecting an item, we could place it in that ViewModel:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace BlazorMovies.Client.Helpers | |
{ | |
public struct MultipleSelectorModel | |
{ | |
public MultipleSelectorModel(string key, string value) | |
{ | |
Key = key; | |
Value = value; | |
} | |
public string Key { get; set; } | |
public string Value { get; set; } | |
} | |
} |
Finally, to use our component,we can place it in a form, passing the selected and non-selected elements. In the course, in the context of a movie form, we do the following:
This component handles movie creation and calls a component that contains a movie form:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@page "/movies/create" | |
@inject NavigationManager navigationManager | |
<h3>Create Movie</h3> | |
<MovieForm Movie="Movie" OnValidSubmit="SaveMovie" NotSelectedGenres="NotSelectedGenres" /> | |
@code { | |
private Movie Movie = new Movie(); | |
private List<Genre> NotSelectedGenres = new List<Genre>() | |
{ | |
new Genre(){Id = 1, Name = "Action"}, | |
new Genre(){Id = 2, Name = "Comedy"}, | |
new Genre(){Id = 3, Name = "Drama"} | |
}; | |
private void SaveMovie() | |
{ | |
Console.WriteLine("this works"); | |
// Saving movie… | |
//navigationManager.NavigateTo("movie"); | |
} | |
} |
And in the MovieForm component we do the following (summary with only the relevant parts):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<EditForm Model="Movie" OnValidSubmit="OnValidSubmit"> | |
<div class="form-group"> | |
<label>Genres:</label> | |
<div> | |
<MultipleSelector Selected="Selected" NoSelected="NotSelected"></MultipleSelector> | |
</div> | |
</div> | |
</EditForm> | |
@code { | |
[Parameter] public List<Genre> SelectedGenres { get; set; } = new List<Genre>(); | |
[Parameter] public List<Genre> NotSelectedGenres { get; set; } = new List<Genre>(); | |
private List<MultipleSelectorModel> Selected = new List<MultipleSelectorModel>(); | |
private List<MultipleSelectorModel> NotSelected = new List<MultipleSelectorModel>(); | |
protected override void OnInitialized() | |
{ | |
Selected = SelectedGenres.Select(x => new MultipleSelectorModel(x.Id.ToString(), x.Name)).ToList(); | |
NotSelected = NotSelectedGenres.Select(x => new MultipleSelectorModel(x.Id.ToString(), x.Name)).ToList(); | |
} | |
} |
Summary
- We can use Blazor to create interactive applications with C#
- With the MultipleSelector component we can allow the user to select several elements from a list
Course
This tutorial comes from my Udemy course, where we created an application from scratch with Blazor. Learn how to create your own applications today and publish them with Azure DevOps today!
Link: https://www.udemy.com/course/programming-in-blazor-aspnet-core/?referralCode=8EFA9D9FF38E3065DF0C