Advanced live-search with AngularJS

04 February 2014   11 comments   Javascript

Powered by Fusion×

For people familar with AngularJS, it's almost frighteningly easy to make a live-search on a repeating iterator.

Here's such an example:

Out of the box it just works. If nothing is typed into the search field it returns everything.

A big problem with this is that the pattern matching isn't very good. For example, if you search for ter you get Teresa and Peter.
More realistically you want it to only match with a leading word delimiter. In other words, if you type ter you want it only to match Teresa but not Peter because Peter doesn't start with ter.
So, to remedy that we construct a regular expression on the fly with a leading word delimiter. I.e. \bter.

Here's an example of that:

Now, there's a problem. For every item in the list the regular expression needs to be created and compiled which, when the list is very long, can become incredibly slow.
To remedy that we use $scope.$watch to create a local regular expression which only happens once per update to $

Here's an example of that:

That, I think, is a really good pattern. Unfortunately we've left the simplicity but we now have something snappier.

Unfortunately the example is a little bit contrived because the list of names it filters on is so small but the list could be huge. It could also be that we want to make a more advanced regular expression. For example, you might want to allow multiple words to match so as ter ma should match Teresa Mayers, John Mayor and Maria Connor. Then you could make a regular expression with something like \b(ter|ma).

For seasoned Angularnauts this is trivial stuff but it really helped me make an app much faster and smoother. I hope it helps someones else doing something similar.


Obviously there is some discrepancy in what people think find-when-typing dialogs should do. ;D
I for instance find it very good that 'ter' gives you 'Teresa' AND 'Peter'! I'd rather state it explicitly when I want the start or end of a term by 'ter*' or '*ter'. But I'd say hits at the beginning should be sorted upfront.

On the other hand I think broaden the search with an extra word is the opposite of what I'd expect!: Just like the Firefox Awesome bar each word sorts again in the former hits to shorten the list further.
Peter Bengtsson
Right you are. I hope the point of the tip still comes through; that you can make a local regex with $scope.$watch
Oh yes of course! The simplicity of the whole thing is very enlightening! Thx for sharing!
Peter Bengtsson
Perhaps the ideal thing is to do two rounds of searching. If nothing is found when searching for "cus" then desperately return all things that have it anywhere in the string like "Circus".

Also, my thinking with the preference for `\d(...)` as in this blog is that for a live-search you kind of expect it to work similar to a autocomplete functionality.
I can't take any coding advice seriously from a person with a site that sucks so bad on mobile.
Peter Bengtsson
Sorry. I upgraded to the latest bootstrap. It should be a bit better now.
Wee Horse
Really annoying comment there joebob - Not everyone is a front end responsive mobile first UX developer. Some people focus on other things.
Hi can anyone please get me the solution with coding example for the below problem.

For example, you might want to allow multiple words to match so as ter ma should match Teresa Mayers, John Mayor and Maria Connor.
a solution is given above like make a regular expression with something like \b(ter|ma). but can you give an example with complete code
Emil Georgiev
To construct "\b(ter|ma)" from search string "ter ma" do the following:

  var search = 'ter ma';
  '\\b(' + search.trim().split(/\s+/).join('|') + ')'

Working example is here:
Ian M
What I would really like to do is have this working with a controller and a shared service, so that I can have the search on one view and the results on another.... can't seem to get the results page to bind or recognize angular directives....

Your email will never ever be published

Related posts

Sorting mixed type lists in Python 3 18 January 2014
What's the average number of domains a website depends on? 24 February 2014
Related by keywords:
What stumped me about AngularJS 12 May 2013
Buggy - A sexy Bugzilla offline webapp 13 March 2014
Do you like angular-classy? 29 April 2014
GitHub PR triage across multiple projects 28 April 2014
\b in Python regular expressions 14 June 2005
Gmail spam filter 13 January 2005
Python regular expression tester 19 September 2005
Anti-spamming email harvesting 26 February 2004
Recon - Regular Expression Test Console 14 January 2004
\B in Python regular expressions 23 July 2005