We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

DropDown with autocomplete and custom sorting

Hi
I would like to implement an DropDown list for countries, where each entry is the iso2 cost of the country , followed by its name , e.g.
..
..
CH (Switzerland)
CL (Chile)
CO (Colombia)
...
...
...
The iso code is what my users are using most of the time, therefor it is very fast, but sometime they dont know the iso code, therefore I need to show the full name.
When the user types C the dropdown options should filter on all countries iso codes starting with C ( top of the list) or containing a c in the country name (bottom of the list )
When the user then types an H the dropdown should show CH (Switzerland) followed by all countries containing ch
I would need some kind of autocomplete combine with a custom sorting.
How to achieve this with the dropdown and /or autocomplete ?

3 Replies

PO Prince Oliver Syncfusion Team September 28, 2017 12:30 PM UTC

Hi Frank, 

Thank you for contacting Syncfusion forums. 

In Autocomplete control, we achieve your requirement by setting filterType property to “contains”. You can search in the input box and matching values containing the key will be displayed in the popup. Kindly refer to the following API documentation link for more information: https://help.syncfusion.com/api/js/ejautocomplete#members:filtertype 

$('#autocomplete').ejAutocomplete({ 
    dataSource: states, 
    fields: { key: "index" ,text: "countryName" }, 
    watermarkText: "Select a Code", 
    width: "100%", 
    filterType: 'contains', 
    showPopupButton : true 
}); 
  
In DropDownList control, we need to set enableFilterSearch to true, to use filter search in the control. Kindly refer to the following API documentation for more information: https://help.syncfusion.com/api/js/ejdropdownlist#members:enablefiltersearch 

$('#dropdownlist').ejDropDownList({ 
    dataSource: states, 
    width: "100%", 
    watermarkText: "Select a Code", 
    fields: { text: "countryName", value: "index" }, 
    enableFilterSearch: true  
}); 


By default, the filterType will be in “contains” in DropDownList control. Kindly refer to the following UG link for more information on filter search: https://help.syncfusion.com/js/dropdownlist/functionalities#filter-search 
 
We have prepared a sample for your reference, kindly refer to the following Playground link: http://jsplayground.syncfusion.com/i0ov0zl2 
 
Regards, 
Prince 



FR Frank September 28, 2017 06:59 PM UTC

Hi Prince 

thanks for the quick reply!

This does the trick for the filtering, however not quite yet for the sorting

in your example if you type G

the order of the filtered results should be

GB (United Kingdom)

DE (Germany)

i.e the sort order should first show the matches on the iso code ( sorted alphabetically) and then the matches on the country name

In select2 one can achieve this with a custom filter and a custom sort function. In the custom filter function one would determine the kind of match ( iso code or country name) and then in the custom sorter function use this to make the iso match come before the country match 

something like this

customFilter(params, data) {
if (!params.term) return data
let newterm = params.term.toUpperCase()
let newtxt = data.text.toUpperCase()
let index = newtxt.indexOf(newterm)
//console.log("matcher",newterm,newtxt,index)
if (index == 0) {
data.matchtype = 1
return data
}
else if (index > 0) {
data.matchtype = 0
return data
}
else {
return null
}
}

// this sorts the results so that matches on the iso2 code come frist
customSort(data): any {
return data.sort((a, b) => {
if (a.matchtype > b.matchtype) return -1
if (a.matchtype == b.matchtype) {
if (a.text > b.text) return 1
if (a.text == b.text) return 0
return -1
}
return 1
})
}

is this possible with the dropdownlist control ?




PO Prince Oliver Syncfusion Team September 29, 2017 08:54 AM UTC

Hi Frank, 

Thank you for your update. 

To use your custom sorting in our DropDownList control, you need to override the internal _filterSearch method and perform your custom sorting and then bind the sorted list to the DropDownList control. Kindly refer to the following code snippet. 

<script type="text/javascript" class="jsScript"> 
    ej.DropDownList.prototype._filterSearch = function (searchQuery, args) { 
        var flag = false;  
        this.resultList = args.result ? args.result : ej.DataManager(this._rawList).executeLocal(searchQuery); 
        if (this.resultList.length == 0) { 
            flag = true; 
            this.resultList.push(this._getLocalizedLabels("emptyResultText")); 
        } 
        this.resultList = customSort(this.resultList); 
        this.popupListItems = this.resultList; 
        this.ultag.empty(); 
        this._isPlainType(this.popupListItems) ? this._plainArrayTypeBinding(this.resultList) : 
        this._objectArrayTypeBinding(this.resultList, "search"); 
        if (flag && this.ultag.find("li").length == 1) { 
            this.ultag.find("li").eq(0).addClass("e-nosuggestion"); 
        } 
        if (this.model.showCheckbox && !flag) { 
            this._appendCheckbox( this._getLi()); 
        } 
        this._onSearch = true; 
        var value = this.value(), visibleText = this._visibleInput[0].value; 
        this._setValue(this.value()); 
        var checkVal = typeof this.model.value === "function" ? this.model.value() : this.model.value; 
        if(checkVal != value){ 
            this.element[0].value = value; 
            this._visibleInput[0].value = visibleText; 
            this.model.text = visibleText == "" ? null : visibleText; 
            if (this.value() != value && !(this.value() == null && value =="" )) { 
                this._updateValue(value); 
            } 
        } 
        this._onSearch = false; 
        this._updateSelectedIndexByValue(this.value()); 
        this._refreshScroller(); 
        this._setListPosition(); 
    }; 
     
 function customSort(data){ 
    return data.sort((a, b) => { 
        if (a.index > b.index) return -1 
        if (a.index == b.index) { 
        if (a.countryName > b.countryName) return 1 
        if (a.countryName == b.countryName) return 0 
        return -1 
        } 
        return 1 
    }); 
 } 
</script> 

We have modified the playground sample as per your requirement, kindly refer to the following link: http://jsplayground.syncfusion.com/r2dls3ja 

Regards, 
Prince 


Loader.
Up arrow icon