Search code examples
ajaxbootstrap-typeahead

bootstrap-typeahead's displayfield using multiple values


I'm sorry if this is a duplicate question but I do not understand the answers of other people. I'm using Twitter Bootstrap Ajax Typeahead Plugin (https://github.com/biggora/bootstrap-ajax-typeahead/) to search emails from data that comes from an SQL query. This is the code I use with a php file, where I use people's emails as valueField and people's names as displayField and it works well.

inputSearch.typeahead({ 
  ajax: {
     url: urlAjax + '?requete=rechercheannuaire',
     displayField: "description",
     valueField: "id",
     triggerLength: 2,
     method: "get",
     loadingClass: "loading-circle",
     preProcess: function(data){
        if(data.type === "error")
        {
           return false;
        }

        return data.datas;    
     }
  },
  onSelect: function(data){
    //alert("assez tot");
    data.text = data.value;
    //console.log(data);
    $("#chercherinvite").val(data.text);

        return data; 
  }

});

The problem is that I have to be able to search "Dujardin" as well as "Du Jardin" and I cannot find a way to assign multiple values to displayField. If someone could explain how typeahead works, I'd be thankfull, I don't understand the documentation.


Solution

  • According to the plugin documentation, you cannot assign multiple values to the displayField option. However, it is possible for you to re-write events.

    After a quick lookup into the source code of bootstrap-ajax-typeahead, we can figure out that the "matcher" event is used as the filter for displaying - or not - values to the user.

    To allow to match both "Du jardin" and "Dujardin", we have to manipulate strings. Here, I suggest you to :

    1. Remove any diacritic character
    2. Remove any non-word character (all except [A-Za-z0-9_])
    3. Remove any underscore
    4. Set the string to lowercase

    To do #1, I suggest you to use this fantastic script by rdllopes.

    I wrote a POC. Here is the JSON source (called "source.json"):

    [
        { "id": 1, "name": "[email protected] - Jean Du Pont"},
        { "id": 2, "name": "[email protected] - Jean Dupont"},
        { "id": 3, "name": "[email protected] - Jéan Dupônt"},
        { "id": 4, "name": "[email protected] - Michel Bridge"}
    ]
    

    And here is the script that I used for matching elements :

    $('#search').typeahead({
        // Our source is a simple JSON file
        ajax: 'source.json',
    
        // Display field is a list of names
        displayField: 'name',
    
        // And value field a list of IDs
        valueField: 'id',
    
        matcher: function(item)
        {
            // For both needle and haystack, we :
            // 1. Remove any diacritic character
            // 2. Remove any non-word character (all except [A-Za-z0-9_])
            // 3. Remove any underscore
            // 4. Set the string to lowercase
            var needle = removeDiacritics(this.query).replace(/[^\w]/gi, '').replace('_', '').toLowerCase();
            var haystack = removeDiacritics(item).replace(/[^\w]/gi, '').replace('_', '').toLowerCase();
    
            // Does the needle exists in haystack?
            return ~haystack.indexOf(needle);
        }
    });