Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I improve jQuery "Tag-It" autocomplete?

I like jQuery's Tag-It plugin, but if I have it set to autocomplete, it doesn't always work the way I want it to.

Here's an example.

My autocomplete array consists of "Pink Lady Apple", "Granny Smith Apple", "Golden Delicious Apple", and "Apple."

If I type in "Apple" it doesn't suggest Pink Lady, Granny Smith or Golden Delicious. It only suggests Apple. Is there a way that I can alter this so that it also scans tags containing Apple but that don't start with Apple?

like image 269
Jack Avatar asked Dec 28 '22 16:12

Jack


1 Answers

I was facing the same problem, so I used @Ravindra's tip (+1 BTW) to see if I could reverse engineer the plug-in and figure out what the tagSource function is expected to return.

The tagSource function returns a boolean value. True is returned if the tag in the availableTags array is displayed in the autocomplete list. False is returned to denote that the tag should not be displayed.

Here is the default tagSource function, which uses indexOf to determine if the text typed so far matches the beginning of a tag in the availableTags array:

Original, default function:

tagSource: function(search, showChoices) {
    var filter = search.term.toLowerCase();
    var choices = $.grep(this.options.availableTags, function(element) {
       // Only match autocomplete options that begin with the search term.
       // (Case insensitive.)
       return (element.toLowerCase().indexOf(filter) === 0);
    });
    showChoices(this._subtractArray(choices, this.assignedTags()));
}

I copied the function and pasted it into the .tagit function so it was included as one of the parameters passed into the jQuery tagit initialization function. I then modified it to use the match method, which uses pattern matching to return the portion of the string matching the pattern. If the match returns null, don't show it in the list. If it returns anything else, show the tag in the list:

Modified function passed in as argument:

tagSource: function(search, showChoices) {
    var filter = search.term.toLowerCase();
    var choices = $.grep(this.options.availableTags, function(element) {
       // Only match autocomplete options that begin with the search term.
       // (Case insensitive.)
       //return (element.toLowerCase().indexOf(filter) === 0);
       console.info(element.toLowerCase().match(filter) + " : " + element + " : " + filter);
       return (element.toLowerCase().match(filter) !== null);
    });
    showChoices(this._subtractArray(choices, this.assignedTags()));
}

Example:

$('#tagged').tagit({
    onTagRemoved: function() {
        alert("Removed tag");
    },

    availableTags: [ "one" , "two one" , "three" , "four" , "five" ],

    // override function to modify autocomplete behavior
    tagSource: function(search, showChoices) {
        var filter = search.term.toLowerCase();
        var choices = $.grep(this.options.availableTags, function(element) {
           // Only match autocomplete options that begin with the search term.
           // (Case insensitive.)
           //return (element.toLowerCase().indexOf(filter) === 0);
           console.info(element.toLowerCase().match(filter) + " : " + element + " : " + filter);
           return (element.toLowerCase().match(filter) !== null);
        });
        showChoices(this._subtractArray(choices, this.assignedTags()));
    }
});
like image 196
jmort253 Avatar answered Jan 06 '23 03:01

jmort253