blim8183
blim8183

Reputation: 768

Sorting Autocomplete UI Results based on match location

I'd like to sort my jQuery Autocomplete UI results based on where in the string the match occurs. The results where the match is the first letter should be prioritized above results in which the match is in the middle of the string.

A search for "M" should return:

Matt, Michael, Sam, Tim, Adam, Benjamin

Instead, since it's just returning the items in alphabetical order right now, I'm getting this:

Adam, Benjamin, Matt, Michael, Sam, Tim

Unfortunately, it looks like Autocomplete UI doesn't have any options for doing something like this, instead it just presents the results in the order it received them. Having MySql do the sorting isn't an option since all the possible matches are preloaded so that I'm not making calls to the database with every keystroke. Has anybody done anything like this?

Upvotes: 8

Views: 7840

Answers (3)

Rahul DSouza
Rahul DSouza

Reputation: 56

It does seem to have problems when spaces are present in between words, please try the following as source

    source=[" Family And Community " , 
" Finance And Legal " , 
" Food And Beverages " , 
" Government " , 
" Health And Medicine " , 
" Home And Garden " , 
" Industrial Supplies And Services " ,
 " Non-governmental Organisations (ngos) " , 
" Personal Care " , 
" Public Utilities And Environment " , 
" Real-estate And Insurance " , 
" Religious Organisations And Associations " , 
" Shopping And Specialty Stores " , 
" Sports And Recreation " ,
 " Transportation " , 
" Travel And Tourism " , 
" Farming " , 
" Farming Equipments And Services " , 
" Feed, Seed And Grain " , 
" Fishing " , 
" Fishing Equipments And Services " , 
" Forests " , 
" Timber Equipments And Services " , 
" General Supplies And Services " , 
" Livestock " , 
" Wildlive " , 
" Minerals And Organic Matte " , 
" Accessories " , 
" Detailing And Aesthetics " , 
" Motorcycles " , 
" Motorised Vehicles " , 
" New And Used Dealers " , 
" Parts And Supplies " , 
" Related Services " , 
" Repairs Body Work " , 
" Repairs Mechanical " , 
" Trailers " , 
" Administrative And Specialty Services " , 
" Advertising " , 
" Associations - Organisations " , 
" Communication And Audio-visual " , 
" Consultants " , 
" Document Services " , 
" Employment And Career Resources " , 
" Engineers " , 
" Furniture And Office - Industrial Machines " , 
" Import And Export Services " , 
" Lawyers " , 
" Marketing And Sales " , 
" Office Supplies - General " , 
" Printing, Publishing And Copying " , 
" Shipping, Packaging And Postal Services " , 
" Trade Shows, Expositions And Conventions " , 
" Alterations And Services " , 
" Clothing - General " , 
" Clothes And Fashion Accessories " , 
" Footwear " , 
" Outerwear " , 
" Uniforms And Work Clothing " , 
" Communications Services And Equipments " , 
" Computer Equipments " , 
" Computer Services " , 
" Electronics - Services And Equipments " , 
" Information Systems " , 
" Internet - Communication And Events " , 
" Internet - Development And Services " , 
" Building Materials And Equipments " , 
" Ceramics And Tiles " , 
" Chimneys " , 
" Concrete, Cement And Paving " , 
" Contractor Equipments And Services " , 
" Design And Architecture " , 
" Electrical Products And Services " , 
" Floors, Ceilings And Roofs " , 
" Foundations And Piling " , 
" Hardware - Supplies And Services " , 
" Heavy Construction And Equipments " , 
" Inspectors And Surveyors " , 
" Painting And Plastering " , 
" Plumbing And Piping " , 
" Academic " , 
" Libraries " , 
" Services And Supplies " , 
" Specialised Schools "]

Upvotes: 0

Kent Rauch
Kent Rauch

Reputation: 101

A possible optimization: cull items from the source list as they go into startsWith, and then you don't need to test for repetition when appending things that contain the search string. However, the trade-off is that the source array would need to be regenerated every time the input string changed.

Upvotes: 0

Andrew Whitaker
Andrew Whitaker

Reputation: 126052

You can provide any local filtering logic you'd like by providing the source option a function instead of a simple array. Here's a quick example that will do the basics of what you want:

var source = ['Adam', 'Benjamin', 'Matt', 'Michael', 'Sam', 'Tim'];
$("input").autocomplete({
    source: function (request, response) {
        var term = $.ui.autocomplete.escapeRegex(request.term)
            , startsWithMatcher = new RegExp("^" + term, "i")
            , startsWith = $.grep(source, function(value) {
                return startsWithMatcher.test(value.label || value.value || value);
            })
            , containsMatcher = new RegExp(term, "i")
            , contains = $.grep(source, function (value) {
                return $.inArray(value, startsWith) < 0 &&
                    containsMatcher.test(value.label || value.value || value);
            });

        response(startsWith.concat(contains));
    }
});

Example: http://jsfiddle.net/zkVrs/

Basically, the logic is to build up an array of matches that start with the term, and then concatenate that with matches that contain the term but don't start with it.

Performance could be a problem here, especially with the $.inArray call. Might be a better way to accomplish that portion, but hopefully that will give you a good starting point.

Upvotes: 18

Related Questions