Skip to content

Commit 2a32849

Browse files
committed
Sync with Kendo UI Professional
1 parent 6b4ebab commit 2a32849

File tree

4 files changed

+791
-0
lines changed

4 files changed

+791
-0
lines changed
Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
---
2+
title: Cascading AutoComplete
3+
description: An example on how to implement cascading Telerik UI for {{ site.framework }} AutoComplete control.
4+
type: how-to
5+
page_title: Cascading AutoComplete
6+
slug: autocomplete-cascading
7+
tags: autocomplete, cascading, model, binding, telerik, core, mvc
8+
res_type: kb
9+
---
10+
11+
## Environment
12+
13+
<table>
14+
<tr>
15+
<td>Product</td>
16+
<td>{{ site.product }} AutoComplete</td>
17+
</tr>
18+
<tr>
19+
<td>Progress {{ site.product }} version</td>
20+
<td>Created with the 2023.2.718 version</td>
21+
</tr>
22+
</table>
23+
24+
## Description
25+
26+
How can I implement a cascading Telerik UI for {{ site.framework }} AutoComplete?
27+
28+
## Solution
29+
30+
The following example consists of two AutoComplete editors that bind to Model properties - `OrganizarionName` and `OrganizationNumber`. When the user types the name of an organization in the first AutoComplete, if the searched name appears as an option and the user selects it, then the second AutoComplete is filtered automatically based on the selected option in the first one and the respective option (the organization number) is selected. Also, when the user types an organization number (the second AutoComplete), the organization name is selected automatically in the first AutoComplete editor.
31+
32+
1. Define the two AutoCompletes bound to the Model properties and configure them to use [server filtering](https://demos.telerik.com/{{ site.platform }}/autocomplete/serverfiltering).
33+
34+
```View
35+
@model OrganizatioViewModel
36+
37+
<form id="exampleForm" class="k-form k-form-vertical" method="post">
38+
<label for="OrganizationID" class="k-form-label">Name:</label>
39+
@(Html.Kendo().AutoCompleteFor(m => m.OrganizationID)
40+
.DataTextField("Name")
41+
.Filter("contains")
42+
.MinLength(1)
43+
.DataSource(source =>
44+
{
45+
source.Read(read =>
46+
{
47+
read.Action("GetOrganizations", "Home");
48+
})
49+
.ServerFiltering(true);
50+
})
51+
)
52+
53+
<label asp-for="OrganizationNumber" class="form-label">Number:</label>
54+
@(Html.Kendo().AutoCompleteFor(m => m.OrganizationNumber)
55+
.DataTextField("Number")
56+
.Filter("contains")
57+
.MinLength(1)
58+
.DataSource(source =>
59+
{
60+
source.Read(read =>
61+
{
62+
read.Action("GetOrganizationNumbers", "Home");
63+
})
64+
.ServerFiltering(true);
65+
})
66+
)
67+
<div class="k-form-buttons">
68+
<button class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md" type="submit">Submit</button>
69+
</div>
70+
</form>
71+
```
72+
{% if site.core %}
73+
```TagHelper
74+
@addTagHelper *, Kendo.Mvc
75+
76+
@model OrganizatioViewModel
77+
78+
<form id="exampleForm" class="k-form k-form-vertical" method="post">
79+
<label for="OrganizationID" class="k-form-label">Name:</label>
80+
<kendo-autocomplete name="OrganizationID"
81+
dataTextField="Name"
82+
filter="FilterType.Contains"
83+
min-length="1">
84+
<datasource type="DataSourceTagHelperType.Custom" server-filtering="true">
85+
<transport>
86+
<read url="@Url.Action("GetOrganizations", "Home")"/>
87+
</transport>
88+
</datasource>
89+
</kendo-autocomplete>
90+
91+
<label asp-for="OrganizationNumber" class="form-label">Number:</label>
92+
<kendo-autocomplete name="OrganizationNumber"
93+
dataTextField="Number"
94+
filter="FilterType.Contains"
95+
min-length="1">
96+
<datasource type="DataSourceTagHelperType.Custom" server-filtering="true">
97+
<transport>
98+
<read url="@Url.Action("GetOrganizationNumbers", "Home")"/>
99+
</transport>
100+
</datasource>
101+
</kendo-autocomplete>
102+
<div class="k-form-buttons">
103+
<button class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md" type="submit">Submit</button>
104+
</div>
105+
</form>
106+
```
107+
{% endif %}
108+
```Controller
109+
public class HomeController : Controller
110+
{
111+
public IActionResult Index()
112+
{
113+
return View(new OrganizatioViewModel());
114+
}
115+
116+
public async Task<JsonResult> GetOrganizations(string text)
117+
{
118+
var organizations = await _organizationsDataService.GetAsync();
119+
if (!string.IsNullOrEmpty(text))
120+
{
121+
var filteredData = organizations.Where(p => p.Name.ToLower().Contains(text.ToLower())).ToList();
122+
return Json(filteredData);
123+
}
124+
return Json(organizations);
125+
}
126+
127+
public async Task<JsonResult> GetOrganizationNumbers(string text)
128+
{
129+
var organizations = await _organizationsDataService.GetAsync();
130+
if (!string.IsNullOrEmpty(text))
131+
{
132+
int organizationNumber = int.Parse(text);
133+
var filteredData = organizations.Where(p => p.Number == intOrganizationNumber).ToList();
134+
return Json(filteredData);
135+
}
136+
return Json(organizations);
137+
}
138+
}
139+
```
140+
```Model
141+
public class OrganizatioViewModel
142+
{
143+
public int? OrganizationID { get; set; }
144+
public int? OrganizationNumber { get; set; }
145+
}
146+
```
147+
148+
1. Use the [`Data()`](https://docs.telerik.com/{{ site.platform }}/api/kendo.mvc.ui.fluent/crudoperationbuilder#datasystemstring) method of the DataSource to pass the selected option of the AutoComplete through the Read request of the cascaded AutoComplete. For example, when the user selects an organization name (the first AutoComplete), the name will be sent to the server through the Read request of the OrganizationNumber AutoComplete.
149+
150+
```View
151+
@(Html.Kendo().AutoCompleteFor(m => m.OrganizationID)
152+
...
153+
.DataSource(source =>
154+
{
155+
source.Read(read =>
156+
{
157+
read.Action("GetOrganizations", "Home").Data("onAdditionalData1");
158+
})
159+
.ServerFiltering(true);
160+
})
161+
)
162+
163+
@(Html.Kendo().AutoCompleteFor(m => m.OrganizationNumber)
164+
...
165+
.DataSource(source =>
166+
{
167+
source.Read(read =>
168+
{
169+
read.Action("GetOrganizationNumbers", "Home").Data("onAdditionalData2");
170+
})
171+
.ServerFiltering(true);
172+
})
173+
)
174+
```
175+
{% if site.core %}
176+
```TagHelper
177+
<kendo-autocomplete name="OrganizationID">
178+
<datasource type="DataSourceTagHelperType.Custom" server-filtering="true">
179+
<transport>
180+
<read url="@Url.Action("GetOrganizations", "Home")" data="onAdditionalData1"/>
181+
</transport>
182+
</datasource>
183+
</kendo-autocomplete>
184+
185+
<kendo-autocomplete name="OrganizationNumber">
186+
<datasource type="DataSourceTagHelperType.Custom" server-filtering="true">
187+
<transport>
188+
<read url="@Url.Action("GetOrganizationNumbers", "Home")" data="onAdditionalData2"/>
189+
</transport>
190+
</datasource>
191+
</kendo-autocomplete>
192+
```
193+
{% endif %}
194+
```Scripts
195+
<script>
196+
function onAdditionalData1() {
197+
let selectedOrganizationNumber = $("#OrganizationNumber").data("kendoAutoComplete").value(); // Get the currently selected option of the OrganizationNumber AutoComplete, if any
198+
return {
199+
text: $("#OrganizationID").val(), // Pass the search entry of the AutoComplete (the ServerFiltering() is enabled).
200+
Number: selectedOrganizationNumber != null ? selectedOrganizationNumber : "" // Pass the selected OrganizationNumber to the server
201+
};
202+
}
203+
function onAdditionalData2() {
204+
let selectedOrganization = $("#OrganizationID").data("kendoAutoComplete").value();
205+
return {
206+
text: $("#OrganizationNumber").val(),
207+
Name: selectedOrganization != null ? selectedOrganization : "" // Pass the selected OrganizationName to the server.
208+
};
209+
}
210+
</script>
211+
```
212+
213+
1. Filter the data server-side based on the selected AutoComplete option.
214+
215+
```Controller
216+
public class HomeController : Controller
217+
{
218+
219+
public async Task<JsonResult> GetOrganizations(string text, string Number)
220+
{
221+
var organizations = await _organizationsDataService.GetAsync();
222+
if (!string.IsNullOrEmpty(Number))
223+
{
224+
int organizationNumber = int.Parse(Number);
225+
var filteredData = organizations.Where(p => p.Number == organizationNumber).ToList();
226+
return Json(filteredData);
227+
}
228+
if (!string.IsNullOrEmpty(text))
229+
{
230+
var filteredData = organizations.Where(p => p.Name.ToLower().Contains(text.ToLower())).ToList();
231+
return Json(filteredData);
232+
}
233+
return Json(organizations);
234+
}
235+
236+
public async Task<JsonResult> GetOrganizationNumbers(string text, string Name)
237+
{
238+
var organizations = await _organizationsDataService.GetAsync();
239+
if (!string.IsNullOrEmpty(Name))
240+
{
241+
var filteredData = organizations.Where(p => p.Name == Name).ToList();
242+
return Json(filteredData);
243+
}
244+
if (!string.IsNullOrEmpty(text))
245+
{
246+
int organizationNumber = int.Parse(text);
247+
var filteredData = organizations.Where(p => p.Number == intOrganizationNumber).ToList();
248+
return Json(filteredData);
249+
}
250+
return Json(organizations);
251+
}
252+
}
253+
```
254+
255+
1. Handle the `Select` event of each AutoComplete component and select the value in the other AutoComplete based on the selected option.
256+
257+
```View
258+
@(Html.Kendo().AutoCompleteFor(m => m.OrganizationID)
259+
.Events(ev => ev.Select("onSelectOrganizationName"))
260+
...
261+
)
262+
263+
@(Html.Kendo().AutoCompleteFor(m => m.OrganizationNumber)
264+
.Events(ev => ev.Select("onSelectOrganizationNumber"))
265+
...
266+
)
267+
```
268+
{% if site.core %}
269+
```TagHelper
270+
<kendo-autocomplete name="OrganizationID" on-select="onSelectOrganizationName">
271+
...
272+
</kendo-autocomplete>
273+
274+
<kendo-autocomplete name="OrganizationNumber" on-select="onSelectOrganizationNumber">
275+
...
276+
</kendo-autocomplete>
277+
```
278+
{% endif %}
279+
```Scripts
280+
<script>
281+
function onSelectOrganizationName(e) {
282+
let selectedOption = e.sender.value(); // Get the selected organization name.
283+
var organizationNumbersControl = $("#OrganizationNumber").data("kendoAutoComplete"); // Get a reference to the 2nd AutoComplete that holds the organization number.
284+
setTimeout(function () {
285+
if (selectedOption != null && organizationNumbersControl.value() != selectedOption) {
286+
organizationNumbersControl.dataSource.fetch(function () { // Make a request to the server to get the Organization numbers data
287+
let data = this.data(); // The server returns the filtered data.
288+
if (data.length == 1) {
289+
organizationNumbersControl.value(data[0].Number); // Set the organization number value.
290+
organizationNumbersControl.trigger("change");
291+
}
292+
});
293+
}
294+
}, 100);
295+
}
296+
297+
function onSelectOrganizationNumber(e) {
298+
let selectedOption = e.sender.value();
299+
var organizationNamesControl = $("#OrganizationID").data("kendoAutoComplete");
300+
setTimeout(function () {
301+
if (selectedOption != null && organizationNamesControl.value() != selectedOption) {
302+
organizationNamesControl.dataSource.fetch(function () {
303+
let data = this.data();
304+
if (data.length == 1) {
305+
organizationNamesControl.value(data[0].Name);
306+
organizationNamesControl.trigger("change");
307+
}
308+
});
309+
}
310+
}, 100);
311+
}
312+
</script>
313+
```
314+
315+
## More {{ site.framework }} Grid Resources
316+
317+
* [{{ site.framework }} AutoComplete Documentation]({%slug htmlhelpers_autocomplete_aspnetcore%})
318+
319+
* [{{ site.framework }} AutoComplete Demos](https://demos.telerik.com/{{ site.platform }}/autocomplete/index)
320+
321+
{% if site.core %}
322+
* [{{ site.framework }} AutoComplete Product Page](https://www.telerik.com/aspnet-core-ui/autocomplete)
323+
324+
* [Telerik UI for {{ site.framework }} Video Onboarding Course (Free for trial users and license holders)]({%slug virtualclass_uiforcore%})
325+
326+
* [Telerik UI for {{ site.framework }} Forums](https://www.telerik.com/forums/aspnet-core-ui)
327+
328+
{% else %}
329+
* [{{ site.framework }} AutoComplete Product Page](https://www.telerik.com/aspnet-mvc/autocomplete)
330+
331+
* [Telerik UI for {{ site.framework }} Video Onboarding Course (Free for trial users and license holders)]({%slug virtualclass_uiformvc%})
332+
333+
* [Telerik UI for {{ site.framework }} Forums](https://www.telerik.com/forums/aspnet-mvc)
334+
{% endif %}
335+
336+
## See Also
337+
338+
* [Client-Side API Reference of the AutoComplete for {{ site.framework }}](https://docs.telerik.com/kendo-ui/api/javascript/ui/autocomplete)
339+
* [Server-Side API Reference of the AutoComplete for {{ site.framework }}](https://docs.telerik.com/{{ site.platform }}/api/autocomplete)
340+
* [Telerik UI for {{ site.framework }} Breaking Changes]({%slug breakingchanges_2023%})
341+
* [Telerik UI for {{ site.framework }} Knowledge Base](https://docs.telerik.com/{{ site.platform }}/knowledge-base)
342+

0 commit comments

Comments
 (0)