Question

I need a simple autocomplete search functionality but also allowing users to type more than one value. I'm using jQuery UI's autocomplete widget (http://jqueryui.com/autocomplete/) and so far I've set the source to only search for the first letter in the suggestions. What I'd like to add now is the ability for users to search for multiple items from the same textbox. (i.e. after a comma suggestions are shown again)

I have been trying to search on how this could be done. The only thing I've managed to find is an option that could be added multiple: true (http://forum.jquery.com/topic/multiple-values-with-autocomplete). Thing is that it's not even listed in the documentation anymore so I don't know if the option has changed or doesn't exist anymore.

This is my code:

    var items = [ 'France', 'Italy', 'Malta', 'England', 
        'Australia', 'Spain', 'Scotland' ];

    $(document).ready(function () {
        $('#search').autocomplete({
            source: function (req, responseFn) {
                var re = $.ui.autocomplete.escapeRegex(req.term);
                var matcher = new RegExp('^' + re, 'i');
                var a = $.grep(items, function (item, index) {
                    return matcher.test(item);
                });
                responseFn(a);
            }
        });
    });

What I tried:

    var items = [ 'France', 'Italy', 'Malta', 'England', 
        'Australia', 'Spain', 'Scotland' ];

    $(document).ready(function () {
        $('#search').autocomplete({
            source: function (req, responseFn) {
                var re = $.ui.autocomplete.escapeRegex(req.term);
                var matcher = new RegExp('^' + re, 'i');
                var a = $.grep(items, function (item, index) {
                    return matcher.test(item);
                });
                responseFn(a);
            },
            multiple: true
        });
    });
Was it helpful?

Solution 2

To solve the issue of multiple strings in the same textbox AND include a regex to only show suggestions matching the start of the string I did the following:

    $('#search').autocomplete({
        minLength: 1,
        source: function (request, response) {
            var term = request.term;

            // substring of new string (only when a comma is in string)
            if (term.indexOf(', ') > 0) {
                var index = term.lastIndexOf(', ');
                term = term.substring(index + 2);
            }

            // regex to match string entered with start of suggestion strings
            var re = $.ui.autocomplete.escapeRegex(term);
            var matcher = new RegExp('^' + re, 'i');
            var regex_validated_array = $.grep(items, function (item, index) {
                return matcher.test(item);
            });

            // pass array `regex_validated_array ` to the response and 
            // `extractLast()` which takes care of the comma separation

            response($.ui.autocomplete.filter(regex_validated_array, 
                 extractLast(term)));
        },
        focus: function () {
            return false;
        },
        select: function (event, ui) {
            var terms = split(this.value);
            terms.pop();
            terms.push(ui.item.value);
            terms.push('');
            this.value = terms.join(', ');
            return false;
        }
    });

    function split(val) {
        return val.split(/,\s*/);
    }

    function extractLast(term) {
        return split(term).pop();
    }

OTHER TIPS

Try this:

  function split( val ) {
    return val.split( /,\s*/ );
  }

  function extractLast( term ) {
     return split( term ).pop();
   }

   $( "#search" )
        .autocomplete({
             minLength: 0,
             source: function( request, response ) {
                 response( $.ui.autocomplete.filter(
                     items, extractLast( request.term ) ) );
             },
             focus: function() {
                 return false;
             },
            select: function( event, ui ) {
                var terms = split( this.value );
                terms.pop();
                terms.push( ui.item.value );
                terms.push( "" );
                this.value = terms.join( ", " );
                return false;
            }
        });

SEE DEMO

If you want to implement the focus function instead of returning false, it's:

focus: function (event, ui) {
    var terms = split(this.value);
    terms.pop();
    terms.push(ui.item.value);
    this.value = terms.join(', ');
    return false;
},

If you do this though, you should probably extract commas from the values.

Also, you can replace lines 7-10 with a call to extractLast. And then you can get rid of your other extractLast because you already called it on term.

With all my changes:

$('#search').autocomplete({
    minLength: 1,
    source: function (request, response) {
        var term = extractLast(request.term),
            re = $.ui.autocomplete.escapeRegex(term),
            matcher = new RegExp('^' + re, 'i'),
            regex_validated_array = $.grep(items, function (item, index) {
                return matcher.test(item);
            }),
            mapped_array = regex_validated_array.map(function (item) {
              return value.replace(/,/g, '');
            });
        response($.ui.autocomplete.filter(mapped_array, term));
    },
    focus: function () {
        var terms = split(this.value);
        terms.pop();
        terms.push(ui.item.value);
        this.value = terms.join(', ');
        return false;
    },
    select: function (event, ui) {
        var terms = split(this.value);
        terms.pop();
        terms.push(ui.item.value);
        terms.push('');
        this.value = terms.join(', ');
        return false;
    }
});

function split(val) {
    return val.split(/,\s*/);
}

function extractLast(term) {
    return split(term).pop();
}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top