This is a migrated thread and some comments may be shown as answers.

Not allowing duplicate values

11 Answers 891 Views
AutoComplete
This is a migrated thread and some comments may be shown as answers.
srinivas
Top achievements
Rank 1
srinivas asked on 27 Oct 2012, 03:48 AM
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

11 Answers, 1 is accepted

Sort by
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.

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
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.

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);
   }
}
Here is a working example in jsbin.

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:

// 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 :)
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:
<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
0
Georgi Krustev
Telerik team
answered on 22 Jul 2014, 02:23 PM
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
 
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:
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);
        }
Tags
AutoComplete
Asked by
srinivas
Top achievements
Rank 1
Answers by
Peter
Top achievements
Rank 1
Burke
Top achievements
Rank 1
Gabriel
Top achievements
Rank 1
Georgi Krustev
Telerik team
Share this question
or