Hi,
I am using kendo ui autocomplete widget. In that i am able to select multiple values in the autocomplete. The values have been coming
from database. What i need is i don't want to allow duplicate values. i.e when i select orange from fruits. Then next time orange will
not be visible in the autocomplete. I have tried different methods. How can i able to do this.
I hope you guys understand my question.
Thanks and Regards,
srinivas
I am using kendo ui autocomplete widget. In that i am able to select multiple values in the autocomplete. The values have been coming
from database. What i need is i don't want to allow duplicate values. i.e when i select orange from fruits. Then next time orange will
not be visible in the autocomplete. I have tried different methods. How can i able to do this.
I hope you guys understand my question.
Thanks and Regards,
srinivas
11 Answers, 1 is accepted
0
Peter
Top achievements
Rank 1
answered on 30 Nov 2012, 12:36 PM
We also need this functionality.
0
Burke
Top achievements
Rank 1
answered on 30 Nov 2012, 04:11 PM
Hi srinivas!
Would you mind posting a bit of your code? I'm interested because the AutoComplete doesn't currently support multiple selection AFAIK. Do I misunderstand the question?
If you are saying that you need this functionality, we do have a Facebook style "Multi Select" coming in Q1 next year.
Would you mind posting a bit of your code? I'm interested because the AutoComplete doesn't currently support multiple selection AFAIK. Do I misunderstand the question?
If you are saying that you need this functionality, we do have a Facebook style "Multi Select" coming in Q1 next year.
0
Peter
Top achievements
Rank 1
answered on 30 Nov 2012, 05:29 PM
http://demos.kendoui.com/web/autocomplete/index.html
you can choose Albania twice here.
We want Albania to not be an option the second time around
you can choose Albania twice here.
We want Albania to not be an option the second time around
0
Burke
Top achievements
Rank 1
answered on 30 Nov 2012, 06:58 PM
Peter
In this case, you can get the values from the AutoComplete and then add them to the filter object.
Here is a working example in jsbin.
http://jsbin.com/oqucix/2
In this case, you can get the values from the AutoComplete and then add them to the filter object.
transport: {
parameterMap:
function
(options, operation) {
// get a reference to the autocomplete
var
autoComplete = $(
"#titles"
).data(
"kendoAutoComplete"
);
// split the values into an array
values = autoComplete.value().split(
", "
);
// pop off the last one as its not a selected value
values.pop();
// loop through the selected values and add them to
// the filter criteria to be sent to the server as 'neq' (not equal)
$.each(values,
function
(index, item) {
options.filter.filters.push({ field:
"Name"
, ignoreCase:
true
, operator:
"neq"
, value: item });
});
// convert the options to odata for netflix. for normal json,
// just return options
return
kendo.data.transports.odata.parameterMap(options);
}
}
http://jsbin.com/oqucix/2
0
Peter
Top achievements
Rank 1
answered on 30 Nov 2012, 07:17 PM
in our case where we are not using serverside filtering, can you provide sample code for that case please?
0
Burke
Top achievements
Rank 1
answered on 03 Dec 2012, 05:39 PM
Hi Peter!
I came up with an "interesting" solution for this one. They key here is that we need to make the DataSource read every time the AutoComplete is triggered. The way that this is normally done is to add serverFiltering: true to the DataSource. This appears to have no effect on local data and that makes sense. You don't "server filter" local data.
I figure you have a two options here. Handle the "blur" on the input and then trigger the DataSource to read again passing the filters. However, you also need to account for the minimum value and handle the parsing of multiple values - something the AutoComplete is already doing under the covers.
To leverage that, I created a custom transport on the DataSource which then wraps all the logic from the previous example and creates a new DataSource which is read from and then filtered.
The new AutoComplete ends up looking like this:
And here is working example...
http://jsbin.com/oqucix/4/
I came up with an "interesting" solution for this one. They key here is that we need to make the DataSource read every time the AutoComplete is triggered. The way that this is normally done is to add serverFiltering: true to the DataSource. This appears to have no effect on local data and that makes sense. You don't "server filter" local data.
I figure you have a two options here. Handle the "blur" on the input and then trigger the DataSource to read again passing the filters. However, you also need to account for the minimum value and handle the parsing of multiple values - something the AutoComplete is already doing under the covers.
To leverage that, I created a custom transport on the DataSource which then wraps all the logic from the previous example and creates a new DataSource which is read from and then filtered.
The new AutoComplete ends up looking like this:
// create a datasource bound to the local data
var
countriesDS =
new
kendo.data.DataSource({
data: countries
});
var
getFilters =
function
(filter) {
// create an empty array
var
filters = [];
// add the default autocomplete filter to the filters array
filters.push(filter);
// split the values into an array
values = autoComplete.value().split(
", "
);
// pop off the last one as its not a selected value
values.pop();
// loop through the selected values and add them to
// the filter criteria to be sent to the server
$.each(values,
function
(index, item) {
filters.push({ field:
""
, ignoreCase:
true
, operator:
"neq"
, value: item });
});
return
filters;
};
var
autoComplete = $(
"#auto"
).kendoAutoComplete({
minLength: 3,
separator:
", "
,
dataSource: {
transport: {
read:
function
(options, operation) {
// read from the local datasource
countriesDS.read();
// filter the local datasource
countriesDS.filter({ logic:
"and"
, filters: getFilters(options.data.filter.filters[0]) });
// pass the result of the local data source to the options
// success method
options.success(countriesDS.view());
}
},
serverFiltering:
true
}
}).data(
"kendoAutoComplete"
);
And here is working example...
http://jsbin.com/oqucix/4/
0
Peter
Top achievements
Rank 1
answered on 04 Dec 2012, 01:44 PM
Thanks!
It works for us :)
It works for us :)
0
Gabriel
Top achievements
Rank 1
answered on 17 Jul 2014, 06:09 PM
Hey All,
I'm having an issue with the autocomplete control suggesting duplicate values. I am implementing it for a Search function in a Razor view in an MVC project. The collection I pass to the autocomplete has duplicate values or names that I want to remove. However, whenever I filter them, the autocomplete displays no suggestions as if the Iqueryable object I'm passing to it is empty. I've tried calling distinct, using a lamda expression, and distinct passing a Comparer class all to the same results. I thought you might have a suggestion as to how I can solve this problem. The code I'm using and or was trying and is now commented is posted below.
View:
Controller:
Comparer Class:
Any help appreciated.
Thanks!
Gabe
I'm having an issue with the autocomplete control suggesting duplicate values. I am implementing it for a Search function in a Razor view in an MVC project. The collection I pass to the autocomplete has duplicate values or names that I want to remove. However, whenever I filter them, the autocomplete displays no suggestions as if the Iqueryable object I'm passing to it is empty. I've tried calling distinct, using a lamda expression, and distinct passing a Comparer class all to the same results. I thought you might have a suggestion as to how I can solve this problem. The code I'm using and or was trying and is now commented is posted below.
View:
<
div
class
=
"DCF"
>
<
span
>DCF DB</
span
>
@(Html.Kendo().AutoComplete()
.Name("dcfSearchBox")
.DataTextField("Keyword")
.Filter("contains")
.MinLength(3)
.HtmlAttributes(new { style = "width:250px" })
.DataSource(source =>
{
source.Read(read =>
{
read.Action("DCFSearch", "Search").Data("onAdditionalData");
})
.ServerFiltering(true);
})
)
@(Html.Label("Filter Text"))
@(Html.CheckBox("dcfCheckFilter"))@(Html.TextBox("dcfFilterText"))
</
div
>
<
script
>
function onAdditionalData() {
return {
text: $("#dcfSearchBox").val()
};
}
</
script
>
Controller:
public
JsonResult DCFSearch(
string
text)
{
DCFDBContext dcf =
new
DCFDBContext(
"DCFEntities"
);
var results = dcf.Keywords.Select(row =>
new
SearchViewModel
{
Keyword = row.Name
//,
//Tablename = row.TableName,
//Id = row.IdNumber.ToString()
})
.Where(r => r.Keyword.Contains(text))
.Distinct(
new
DistinctSVMComparer())
.Take(50);
//var filteredResults = results.GroupBy(x => x.Keyword).Select(y => y.First());//.Distinct(new DistinctSVMComparer());
/*if (!string.IsNullOrEmpty(text))
{
results = results.Where(r => r.Keyword.Contains(text)).Distinct().Take(50);
}*/
return
Json(results, JsonRequestBehavior.AllowGet);
}
Comparer Class:
namespace
TestingTelerikMvcApp.Models
{
public
class
SearchViewModel
{
public
string
Keyword {
get
;
set
; }
public
string
Tablename {
get
;
set
; }
public
string
Id {
get
;
set
; }
}
class
DistinctSVMComparer : IEqualityComparer<SearchViewModel>
{
public
bool
Equals(SearchViewModel x, SearchViewModel y)
{
return
x.Keyword != y.Keyword;
}
public
int
GetHashCode(SearchViewModel svm)
{
return
svm.Keyword.GetHashCode();
}
}
}
Any help appreciated.
Thanks!
Gabe
0
Gabriel
Top achievements
Rank 1
answered on 17 Jul 2014, 06:44 PM
UPDATE:
Reducing my view model class to the one column (keyword) and calling .Distinct() is working for removing the duplicates. Also note there was an error in the code I posted in the comparer class comparing != instead of ==, was just doing a crazy test trying to get any results returned to the autocomplete when I try one of the manual filtering options. Those still don't work. I'm not sure why.
Thanks
Gabriel
Reducing my view model class to the one column (keyword) and calling .Distinct() is working for removing the duplicates. Also note there was an error in the code I posted in the comparer class comparing != instead of ==, was just doing a crazy test trying to get any results returned to the autocomplete when I try one of the manual filtering options. Those still don't work. I'm not sure why.
Thanks
Gabriel
0
Hello Gabriel,
Could you please elaborate a bit more on what still does not work? It will be very helpful if you can provide a runnable test project, which reproduces the problem. Thus we will be able to proceed much faster with our investigation.
Regards,
Georgi Krustev
Telerik
Could you please elaborate a bit more on what still does not work? It will be very helpful if you can provide a runnable test project, which reproduces the problem. Thus we will be able to proceed much faster with our investigation.
Regards,
Georgi Krustev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Gabriel
Top achievements
Rank 1
answered on 22 Jul 2014, 02:56 PM
Hey Georgi,
Thanks for the response! I now am properly filtering out duplicate values that I am sending to the autocomplete control. Below is the code that is working. Simply calling .Distinct() is working to remove duplicates. This was the first method I tried which I thought wasn't working but the error was in my test cases. I had cases that had an extra space between to strings, so at first glance I didn't see the difference between the two values and thought there were duplicates, thus the call to .Replace() you see now.
In continuing to problem solve, when the error was in my test cases, I proceeded to try using the above comparer class passed as parameter to .Dinstinct(new DistinctSVMComparer()) and I also tried the above commented line, lamda expression to filter out duplicates from my collection before passing to the autocomplete. Both of these methods resulted in no results/suggestions displayed from the autocomplete control as if I were passing an empty collection. This is still what I don't know why it wouldn't work. Unfortunately I don't have time to provide a complete runnable test project as I cannot provide what I'm working with due to sensitive data, and there is a substantial amount of pieces. I'm using entity framework in an mvc project connected to a sql database. Regardless, I believe the error to be in my code in these errors and not with the Kendo Autocomplete control.
Thanks
Gabriel
Controller:
Thanks for the response! I now am properly filtering out duplicate values that I am sending to the autocomplete control. Below is the code that is working. Simply calling .Distinct() is working to remove duplicates. This was the first method I tried which I thought wasn't working but the error was in my test cases. I had cases that had an extra space between to strings, so at first glance I didn't see the difference between the two values and thought there were duplicates, thus the call to .Replace() you see now.
In continuing to problem solve, when the error was in my test cases, I proceeded to try using the above comparer class passed as parameter to .Dinstinct(new DistinctSVMComparer()) and I also tried the above commented line, lamda expression to filter out duplicates from my collection before passing to the autocomplete. Both of these methods resulted in no results/suggestions displayed from the autocomplete control as if I were passing an empty collection. This is still what I don't know why it wouldn't work. Unfortunately I don't have time to provide a complete runnable test project as I cannot provide what I'm working with due to sensitive data, and there is a substantial amount of pieces. I'm using entity framework in an mvc project connected to a sql database. Regardless, I believe the error to be in my code in these errors and not with the Kendo Autocomplete control.
Thanks
Gabriel
Controller:
public
JsonResult DCFSearch(
string
text)
{
DCFDBContext cares =
new
DCFDBContext(
"CARESEntities"
);
var results = cares.Keywords.Select(row =>
new
SearchViewModel
{
Keyword = row.Keyword.Trim().Replace(
" "
,
" "
)
})
.Where(r => r.Keyword.Contains(text))
.Distinct()
.Take(50);
return
Json(results, JsonRequestBehavior.AllowGet);
}