Hi there,
I have a textbox where the user can enter multiple partnumbers (as comma separated) and the partnumber should have the autocomplete feature enabled for every selection. This was possible with the kendo autocomplete feature easily. But in my case, there were around 2 lakh partnumbers in the DB and so, the page was stuck up, when it tries to load the data. So, instead we wanted to only pull the top 20 matching partnumbers in the autocomplete functionality.
With this being said, we should be making Server Filtering instead of getting all the data in one shot. I did see multiple similar examples, but nothing was working in my case, as I was trying to fetch the data from the DB using stored procedure call. Below is my code.
$("#txtPartNumbers").kendoAutoComplete({
dataSource: {
type: "odata",
serverFiltering: true,
transport: {
read: {
url: ApiBaseUrl.val + 'mycontroller/getParts',
type: "get",
dataType: "json",
data: { partNumber: 200, maxCount = 20}
}
}
},
filter: "startswith",
placeholder: "Select Inventory Parts..",
minLength: 3,
separator: ", "
});
partNumber (is the search text) and maxCount(20 in my case) are the parameters that I used to pass to the controller method and then to the stored procedure.
Appreciate your help on this.
Thanks!
Regards
Neelima
For those who're wondering how to catch KendoUI autocomplete filter on server side webapi2 controller without having to deal with filter.filters[0] query string prarameters.
This is how I've solved it:
JS:
$(
"#values"
).kendoAutoComplete({
minLength: 3,
enforceMinLength:
true
,
dataTextField:
"value"
,
dataValueField:
"id"
,
dataSource: {
type:
"json"
,
severFiltering:
true
,
serverPaging:
true
,
transport: {
read:
"/api/values"
,
parameterMap:
function
(data, type) {
return
{ filter: $(
'#values'
).val() };
}
}
},
filtering:
function
(e) {
if
(!e.filter.value) {
e.preventDefault();
}
}
});
The trick here is to use parameterMap to change request url.
WebApi2:
public
class
ValuesController : ApiController
{
// GET api/values
[HttpGet]
[Route(
"api/values"
, Name =
"r2"
, Order = 2)]
public
IEnumerable<ValueModel> Get()
{
//var filters = new AutoCompleteFilters(Request.GetQueryNameValuePairs());
return
new
List<ValueModel>() {
new
ValueModel() { id = 1, value =
"item 1"
},
new
ValueModel() { id = 2, value =
"item 2"
},
new
ValueModel() { id = 3, value =
"item 3"
},
};
}
//GET api/values?filter=item
//GET api/values/ite
[HttpGet]
[Route(
"api/values/{filter?}"
, Name =
"r1"
, Order = 1)]
public
IEnumerable<ValueModel> Get(
string
filter)
{
return
new
List<ValueModel>() {
new
ValueModel() { id=1, value=
"item 1"
},
new
ValueModel() { id=2, value=
"item 2"
},
new
ValueModel() { id=3, value=
"item 3"
},
}.Where(m => m.value.StartsWith(filter, StringComparison.CurrentCultureIgnoreCase));
}
}
The trick on WebApi2 is to use "named" Route attributes with optional {filter?} parameter
This solution allows either :
http://localhost:11989/api/values?filter=item
or
http://localhost:11989/api/values/ite
What is cool in case your api is exposed to third-party applications.
Happy coding!
Hi
I want to add the results from an AutoComplete, into the Multiselect on the fly (ie as you select it in autocomplete, it adds it to multi-select)
Are there any examples of this?
I can't work out how to set the width of the autocomplete input. Using PopupSettings I can set the width of the pop out box, is there an equivalent way of setting the width of the component itself ? Thanks.
<label class="k-form-field">
<span>Select Product</span>
<kendo-autocomplete
[popupSettings]="{width: 500}"
[data]="listItems"
[valueField]="'AltProductDescription'"
[filterable]="true"
[placeholder]="'e.g. Seed'"
(valueChange)="valueChange($event)"
(filterChange)="filterChange($event)"
>
</kendo-autocomplete>
This issue is occurring in Chrome, I have not tried other browsers.
The issue can be observed in demo http://demos.telerik.com/kendo-ui/autocomplete/serverfiltering
Note the minLength: 3 setting.
Type in "che" per the hint. Developer tools network activity will show the $filter parameter as [ substringof('che',tolower(ProductName)) ]. All fine and good.
Now clear "che" by clicking on clear (x). The network activity tab will show a Products call back with a $filter parameter [ substringof('',tolower(ProductName)) ]. The minLength setting was obviously ignored and the filter actually pulls _all_ the data from the remote source. In the example it is 77 items. For real world scenarios an unfiltered query could return an application destroying amount of data. Despite pulling all the data, no suggestions are shown -- I presume because at this point the minLength is honored and thus no suggestions
Q: How can I prevent an unfiltered query when clear clicked ?
Q: How can I force the autocomplete data source to have no items when clear is clicked ?
Thanks, Richard
At the first rendering of a page I would like to specify and process the selection of a default autocomplete value. I thought this code might work, it doesn't:
$(document).ready(
function
() {
var
ac = $(
"#autoComplete"
).data(
"kendoAutoComplete"
);
var
target =
"170035"
;
ac.search(target)
.then(ac.select(target))
.then(ac.trigger(
"change"
))
;
})
AutoComplete search() does not return a promise. A promise would be needed for the .then() chaining I want to do. For comparison, DataSource read() does return a promise and can be part of a chain.
Q: Can you suggest a different approach for search and select ?
Thanks, Richard
Hi Masters,
How can I set enforceMinLength = true from Angular html models?
It doesn't look like it's working like this:
<input kendo-auto-complete ng-model="customerName" k-min-length="3" enforceMinLength="true" k-data-source="repos" style="width: 100%;" />
I have an AutoComplete being populated when I select a value from a dropdownlist. Its fine the first time I select a value from a dropdownlist, but when I change my mind and select a different value the AutoComplete overlaps itself, and then gets a blue border..How do I stop the Autocomplete from overlapping itself, when I select a different value from the dropdownlist?
Here is the code
<!DOCTYPE html>
<
html
>
<
head
>
<
meta
charset
=
"utf-8"
>
<
title
>Untitled</
title
>
<
link
rel
=
"stylesheet"
href
=
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
>
<
link
rel
=
"stylesheet"
href
=
"https://kendo.cdn.telerik.com/2017.3.913/styles/kendo.common-bootstrap.min.css"
>
<
link
rel
=
"stylesheet"
href
=
"https://kendo.cdn.telerik.com/2017.3.913/styles/kendo.blueopal.min.css"
>
<
script
src
=
"https://code.jquery.com/jquery-1.12.3.min.js"
></
script
>
<
script
src
=
"https://kendo.cdn.telerik.com/2017.3.913/js/kendo.all.min.js"
></
script
></
head
>
<
body
>
<
div
class
=
"container"
>
<
div
class
=
"form-horizontal"
>
<
div
class
=
"row"
>
<
div
class
=
"col-md-5"
>
<
div
class
=
"form-group"
>
<
input
id
=
"txtState"
/>
</
div
>
</
div
>
</
div
>
<!-- End txtState -->
<
div
class
=
"row"
>
<
div
class
=
"col-md-5"
>
<
div
class
=
"form-group"
>
<
input
id
=
"txtCounty"
/>
</
div
>
</
div
>
</
div
>
<!-- End txtState -->
</
div
>
<!-- End form horizontal -->
</
div
>
<
script
>
$(document).ready(function(){
var stateData = [
{"StateID" : 1, "StateName": "Oklahoma"},
{"StateID" : 2, "StateName": "Texas"}
];
LoadStates(stateData);
LoadCounty(0);
});
function LoadStates(stateData){
var countyData1 = [
{"CountyID" : 1, "CountyName": "CountyA"},
{"CountyID" : 2, "CountyName": "CountyB"},
{"CountyID" : 3, "CountyName": "CountyC"},
{"CountyID" : 4, "CountyName": "CountyD"}
];
var countyData2 = [
{"CountyID" : 5, "CountyName": "CountyE"},
{"CountyID" : 6, "CountyName": "CountyF"},
{"CountyID" : 7, "CountyName": "CountyG"},
{"CountyID" : 8, "CountyName": "CountyH"}
];
$("#txtState").kendoDropDownList({
dataSource: stateData,
index: 0,
dataTextField: "StateName",
dataValueField: "StateID",
animation: false,
optionLabel: "State",
change: function (e) {
var dataItem = e.sender.dataItem();
if(dataItem.StateID === 1){
$("#txtCounty").removeAttr('style');
LoadCounty(countyData1);
}
else
{
$("#txtCounty").removeAttr('style');
LoadCounty(countyData2);
}
}
});
}
function LoadCounty(countyData){
$("#txtCounty").kendoAutoComplete({
dataSource: countyData,
dataTextField: "CountyName",
dataValueField: "CountyID",
filter: "startswith",
placeholder: "Type County...",
select: function (e) {
var DataItem = this.dataItem(e.item.index());
currentSelectedItem = DataItem.CountyID;
}
});
}
</
script
>
</
body
>
</
html
>
I have an autocomplete on a page, and I would like the autocomplete to re-query the data source every time it is used. For example, if someone loads up the page and they use the autocomplete control, everything is good. But, if the underlying data in the database changes after the page is loaded, and after this initial query, any new rows are not reflected in the autocomplete control. The control appears to hold on to the data that it got from the first query and not go back to the data source.
If I refresh the page then it is ok, the new rows appear, but my users expect the autocomplete to always reflect that is in the database even if the data changes after the page is loaded and after the autocomplete control has queried the database already.
Does anyone know how this can be achieved? I have tried various combinations of ServerFiltering and specifying the Action Type as "Post" (as suggested by various internet articles), without getting the desired results.
I believe my code is fairly normal, nothing unusual going on here I think (apart from the dodgy formatting):
@(Html.Kendo().AutoComplete()
.Name("newWorkOrderAutoComplete")
.DataTextField("WorksOrderNumber")
.MinLength(2)
.HtmlAttributes(new { style = "width: 250px" })
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetWorkOrderHeaders", "Kitting").Type(HttpVerbs.Post);
})
.ServerFiltering(false);
})
.IgnoreCase(true)
.Suggest(true)
.Animation(a =>
{
a.Open(open =>
{
open.Duration(300);
open.Zoom(ZoomDirection.In);
});
a.Close(close =>
{
close.Duration(300);
close.Zoom(ZoomDirection.Out);
});
})
)
Thanks in advance,
Peter