4
4
@inject IJSRuntime _js
5
5
@inject MsOptionsService _dataService
6
6
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"
14
20
Id =" @Id"
15
- OnChange =" @RaiseTagsChanged " >
21
+ @ref =" @MultiSelectWithButton " >
16
22
<FooterTemplate >
17
23
@if (_isNewTag && ! string .IsNullOrEmpty (_currentFilterValue ))
18
24
{
19
- <div class = " p-3 " >
20
- <button class = " btn btn-secondary " @onclick = " @ OnCreateRecord" >Create '@_currentFilterValue' </button >
25
+ <div style = " margin : 1 em ; text-align : center ; " >
26
+ <TelerikButton OnClick = " @ OnCreateRecord" >Create '@_currentFilterValue' </TelerikButton >
21
27
</div >
22
28
}
23
29
</FooterTemplate >
30
36
[Parameter ]
31
37
public EventCallback <List <int >> TagsChanged { get ; set ; }
32
38
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
+
35
44
// used to get the current user input and to show the Add button
36
45
string _currentFilterValue { get ; set ; }
37
46
bool _isNewTag => IsNew ();
38
47
39
48
// used for the hack
40
- bool shouldUpdateValueParam { get ; set ; }
49
+ bool shouldClearInput { get ; set ; }
50
+ bool shouldUpdateTags { get ; set ; }
51
+
41
52
string Id { get ; set ; } = " ms" + Guid .NewGuid ().ToString ();
42
53
43
54
// Event for the parent component
50
61
async Task OnCreateRecord ()
51
62
{
52
63
OptionsModel insertedOption = await _dataService .AddOption (_currentFilterValue );
53
- Options .Add (insertedOption ); // update the current view-model. Add() works because it is an observable collection
54
64
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
57
66
Tags .Add (insertedOption .MyValueField );
58
- shouldUpdateValueParam = true ;
67
+ shouldClearInput = true ;
68
+
69
+ MultiSelectWithButton .Rebind ();
59
70
60
71
// raises event for parent componets to use
61
72
await TagsChanged .InvokeAsync (Tags );
62
73
}
63
74
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
+
64
89
// sample check to know whether to show the Add button. You should keep it synchronous - the service
65
90
// should have already taken care to return properly filtered data based on the current input (not implemented here)
66
91
bool IsNew ()
87
112
// in a real case you may want to actually use the current user input and method, see more at
88
113
// https://docs.telerik.com/blazor-ui/components/multiselect/events#onread
89
114
var currOpts = await _dataService .GetOptions ();
90
- Options = new ObservableCollection <OptionsModel >(currOpts );
115
+ args . Data = Options = new List <OptionsModel >(currOpts );
91
116
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 )
97
119
{
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 ;
104
122
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
107
123
await _js .InvokeVoidAsync (" clearInput" , Id );
108
124
}
109
125
}
110
- }
126
+ }
0 commit comments