New to Telerik UI for Blazor? Start a free 30-day trial
Add New Item to MultiSelect
Updated over 6 months ago
Environment
| Product | MultiSelect for Blazor |
Description
How to allow the user to add new items to the Multiselect, and select them automatically?
Solution
The example below shows how to add new items from outside the MultiSelect. It follows this algorithm:
- Add the new item to the
Dataand/or the remote data source. - Select the new item by adding it to the
Valuecollection. Let's assume theValuecollection isList<int> SelectedItems Rebind()the MultiSelect.- (
Datascenarios only) Refresh theSelectedItemsinstance, so that the component can detect the update. - (
OnReadscenarios only) Raise a boolean flag in theOnReadhandler. - (
OnReadscenarios only) Check the boolean flag inOnAfterRenderAsyncand refresh theSelectedItemsinstance
There is also a related example in GitHub. It shows how to add new items from inside the MultiSelect dropdown.
Add and select new MultiSelect items
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<h1>Add and select new MultiSelect items on the fly</h1>
<p>
<TelerikTextBox @bind-Value="@NewText" Width="200px" PlaceHolder="type new item" />
<TelerikButton OnClick="@AddItem">Add and Select Item</TelerikButton>
</p>
<h2>Bind MultiSelect with Data parameter</h2>
<TelerikMultiSelect @ref="@MultiSelect1"
Data="@MultiSelectData"
@bind-Value="@SelectedItems"
TextField="@nameof(SampleModel.Text)"
ValueField="@nameof(SampleModel.ID)"
Width="300px" />
<h2>Bind MultiSelect with OnRead event</h2>
<TelerikMultiSelect @ref="@MultiSelect2"
TItem="@SampleModel"
TValue="@int"
OnRead="@OnReadHandler2"
@bind-Value="@SelectedItems"
TextField="@nameof(SampleModel.Text)"
ValueField="@nameof(SampleModel.ID)"
Width="300px" />
@code{
TelerikMultiSelect<SampleModel, int> MultiSelect1 { get; set; }
TelerikMultiSelect<SampleModel, int> MultiSelect2 { get; set; }
List<int> SelectedItems { get; set; } = new List<int>() { 1 };
bool ShouldRaiseFlag2 { get; set; } = true;
bool ShouldRefreshSelectedItems2 { get; set; }
string NewText { get; set; }
async Task AddItem()
{
// simulate network delay
await Task.Delay(100);
// create new item instance
int newId = MultiSelectData.Count + 1;
SampleModel newItem = new SampleModel() { ID = newId, Text = $"{NewText} {newId}" };
// add new item to data
MultiSelectData.Add(newItem);
// add new item to selection
SelectedItems.Add(newId);
// rebind MultiSelects
MultiSelect1.Rebind();
MultiSelect2.Rebind();
// refresh selection instance for MultiSelect 1
SelectedItems = new List<int>(SelectedItems);
// flag for refresh selection instance for MultiSelect 2
ShouldRaiseFlag2 = true;
}
async Task OnReadHandler2(MultiSelectReadEventArgs args)
{
// simulate network delay
await Task.Delay(100);
DataSourceResult result = MultiSelectData.ToDataSourceResult(args.Request);
args.Data = result.Data;
args.Total = result.Total;
if (ShouldRaiseFlag2)
{
ShouldRaiseFlag2 = false;
// flag for refresh selection instance for MultiSelect 2
ShouldRefreshSelectedItems2 = true;
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// (OnRead binding only)
// refresh selection instance for MultiSelect 2
// works also for selecting initial items
if (ShouldRefreshSelectedItems2)
{
ShouldRefreshSelectedItems2 = false;
SelectedItems = new List<int>(SelectedItems);
StateHasChanged();
}
await base.OnAfterRenderAsync(firstRender);
}
List<SampleModel> MultiSelectData { get; set; } = new List<SampleModel> {
new SampleModel { ID = 1, Text = "foo" },
new SampleModel { ID = 2, Text = "bar" },
new SampleModel { ID = 3, Text = "baz" }
};
public class SampleModel
{
public int ID { get; set; }
public string Text { get; set; }
}
}