Skip to content

Commit 70461ff

Browse files
dimodiDimo Dimov
andauthored
Migrate MultiSelect example to v3.0 mostly OnRead changes (#154)
Co-authored-by: Dimo Dimov <dimo@Dimos-MacBook-Pro.local>
1 parent 2f6b10e commit 70461ff

File tree

3 files changed

+50
-34
lines changed

3 files changed

+50
-34
lines changed

multiselect/add-new-item/MultiSelectAndAddButton/MultiSelectAndAddButton/MultiSelectAndAddButton.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Telerik.UI.for.Blazor" Version="2.19.0" />
8+
<PackageReference Include="Telerik.UI.for.Blazor" Version="3.0.1" />
99
</ItemGroup>
1010

1111
</Project>

multiselect/add-new-item/MultiSelectAndAddButton/MultiSelectAndAddButton/Pages/Index.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
}
1515

1616
@code{
17-
List<int> Tags { get; set; }
17+
List<int> Tags { get; set; } = new List<int>();
1818
}

multiselect/add-new-item/MultiSelectAndAddButton/MultiSelectAndAddButton/Shared/MultiSelectWithAdd.razor

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,26 @@
44
@inject IJSRuntime _js
55
@inject MsOptionsService _dataService
66

7-
<p>
8-
Click in the multi select, you can select some of the predefined items, or type a new one - this will give you the Add button.
9-
</p>
10-
11-
<TelerikMultiSelect Data="@Options" @bind-Value="@Tags" AutoClose="false"
12-
TextField="StringRepresentation" ValueField="MyValueField"
13-
OnRead="@ReadItems" Filterable="true"
7+
<ul>
8+
<li>Click in the MultiSelect.</li>
9+
<li>Select predefined items, or type a new one - this will show the Add button.</li>
10+
</ul>
11+
12+
<TelerikMultiSelect TItem="@OptionsModel" TValue="@int"
13+
@bind-Value="@Tags" OnRead="@ReadItems"
14+
OnChange="@RaiseTagsChanged"
15+
TextField="StringRepresentation"
16+
ValueField="MyValueField"
17+
Filterable="true"
18+
AutoClose="false"
19+
Width="300px"
1420
Id="@Id"
15-
OnChange="@RaiseTagsChanged">
21+
@ref="@MultiSelectWithButton">
1622
<FooterTemplate>
1723
@if (_isNewTag && !string.IsNullOrEmpty(_currentFilterValue))
1824
{
19-
<div class="p-3">
20-
<button class="btn btn-secondary" @onclick="@OnCreateRecord">Create '@_currentFilterValue'</button>
25+
<div style="margin:1em;text-align:center;">
26+
<TelerikButton OnClick="@OnCreateRecord">Create '@_currentFilterValue'</TelerikButton>
2127
</div>
2228
}
2329
</FooterTemplate>
@@ -30,14 +36,19 @@
3036
[Parameter]
3137
public EventCallback<List<int>> TagsChanged { get; set; }
3238

33-
ObservableCollection<OptionsModel> Options { get; set; } = new ObservableCollection<OptionsModel>();
34-
39+
TelerikMultiSelect<OptionsModel, int> MultiSelectWithButton { get; set; }
40+
41+
// used to check if the search string exists in the data
42+
List<OptionsModel> Options { get; set; } = new List<OptionsModel>();
43+
3544
// used to get the current user input and to show the Add button
3645
string _currentFilterValue { get; set; }
3746
bool _isNewTag => IsNew();
3847

3948
// used for the hack
40-
bool shouldUpdateValueParam { get; set; }
49+
bool shouldClearInput { get; set; }
50+
bool shouldUpdateTags { get; set; }
51+
4152
string Id { get; set; } = "ms" + Guid.NewGuid().ToString();
4253

4354
// Event for the parent component
@@ -50,17 +61,31 @@
5061
async Task OnCreateRecord()
5162
{
5263
OptionsModel insertedOption = await _dataService.AddOption(_currentFilterValue);
53-
Options.Add(insertedOption); // update the current view-model. Add() works because it is an observable collection
5464

55-
// update the values, needs a new reference, see https://docs.telerik.com/blazor-ui/common-features/observable-data#refresh-data
56-
// continues with a hack in OnRead
65+
// continues with a hack in OnRead and OnAfterRenderAsync
5766
Tags.Add(insertedOption.MyValueField);
58-
shouldUpdateValueParam = true;
67+
shouldClearInput = true;
68+
69+
MultiSelectWithButton.Rebind();
5970

6071
// raises event for parent componets to use
6172
await TagsChanged.InvokeAsync(Tags);
6273
}
6374

75+
protected override async Task OnAfterRenderAsync(bool firstRender)
76+
{
77+
if (shouldUpdateTags)
78+
{
79+
shouldUpdateTags = false;
80+
81+
// hack to refresh the selected values AFTER the MultiSelect is rebound
82+
Tags = new List<int>(Tags);
83+
StateHasChanged();
84+
}
85+
86+
await base.OnAfterRenderAsync(firstRender);
87+
}
88+
6489
// sample check to know whether to show the Add button. You should keep it synchronous - the service
6590
// should have already taken care to return properly filtered data based on the current input (not implemented here)
6691
bool IsNew()
@@ -87,24 +112,15 @@
87112
// in a real case you may want to actually use the current user input and method, see more at
88113
// https://docs.telerik.com/blazor-ui/components/multiselect/events#onread
89114
var currOpts = await _dataService.GetOptions();
90-
Options = new ObservableCollection<OptionsModel>(currOpts);
115+
args.Data = Options = new List<OptionsModel>(currOpts);
91116

92-
// START of the hack for updating the values from an extrenal place
93-
// generally, you should not update the Value here, or any other component parameter
94-
// we do this here to make the component re-render after it has the new data, otherwise
95-
// it could not match the new value we just added to the data source, and would not create a "tag"
96-
if (shouldUpdateValueParam)
117+
// hack for clearing the search textbox and raise another flag for OnAfterRenderAsync
118+
if (shouldClearInput)
97119
{
98-
shouldUpdateValueParam = false;
99-
100-
// to make the framework re-render a component, change the reference to the complex object
101-
// see more at https://docs.telerik.com/blazor-ui/common-features/observable-data#refresh-data
102-
List<int> updatedValues = new List<int>(Tags);
103-
Tags = updatedValues;
120+
shouldClearInput = false;
121+
shouldUpdateTags = true;
104122

105-
// clear the input value now that the user has added the current text to the data source
106-
// the sample JS method is in the index page of the blazor app, move it as necessary
107123
await _js.InvokeVoidAsync("clearInput", Id);
108124
}
109125
}
110-
}
126+
}

0 commit comments

Comments
 (0)