Custom dropdown/auto-complete with AngularJS

Update (2015-09-17): Check out new Version 2 of this control.

I’ll admit it, I’m a big fan of AngularJS; it’s a great framework. If you consider yourself a serious front-end developer, you should really know about AngularJS. In our day to day work, we frequently find challenging requirements and problems that need to be solved efficiently and, why not, elegantly. And frameworks such as AngularJS help us achieve just that, and even turn our solutions into generic pieces of work that we can put in our tool box and use here and there across different projects. This time I will talk briefly about one such case. Hopefully it can be of use to someone else, too.

The problem

We all need to use an auto-complete box once in a while. There are many good solutions out there that are easy to use. But… they are usually limited to working with strings. On the other hand, regular select elements are great when you want to display names but use Id’s (or some sort of unique value) for your model and your business rules. But… they are pretty inflexible and “boring”. So, I needed and auto-complete box that worked also well with complex objects, and could integrate seamlessly with AngularJS.

The solution

Create an AngularJS directive from scratch. At least that was the only option I saw. And it didn’t turn out too bad after all. So here it is, Custom Select (sorry for the totally uncreative name).


<div custom-select ng-model="fruit" ng-options="f for f in fruits">
</div>

You may have noticed that the attributes look very similar to those of a regular AngularJS select directive (except for the additional custom-select attribute). Assuming you setup the appropriate values in your scope, you’ll get something like this.

Untitled

If you want to use JSON objects and have a display property and another property that gets saved to your model, you could use something like this:


<div custom-select ng-model="state" ng-options="s.id as s.name for s in states">
</div>

The end result would look very similar, but will work slightly different.

As a bonus, you could use a custom template for your dropdown items. Here’s an example:


<div custom-select ng-model="person" ng-options="t as t.name for t in people">

<div class="pull-left" style="width: 40px">
        <img ng-src="{{ t.picture }}" style="width: 30px" />
    </div>


<div class="pull-left">
        <strong>{{ t.name }}</strong>
        <span>{{ t.phone }}</span>
    </div>


<div class="clearfix"></div>

</div>

And the end result:
Untitled

If you liked it, you can grab the source code and the examples from Github.