autocomplete.js

angular.module('homepage').
directive('autocomplete', function($timeout) {
    return {
        controller: 'autocompleteController',
        restrict: 'E',
        replace: true,
        scope: {
            choices: '=',
            enteredtext: '=',
            minlength: '=',
            result: '=',
            type: '=',
            onselect: '&'
        },
        templateUrl: 'components/common-components/autocomplete/autocomplete.html'
    };
}).
controller('autocompleteController', function($scope, $timeout) {
    $scope.filteredChoices = [];
    $scope.isVisible = {
        suggestions: false
    };

    $scope.filterItems = function () {
        if($scope.enteredtext && $scope.minlength <= $scope.enteredtext.length) {
            $scope.filteredChoices = querySearch($scope.enteredtext);
            $scope.isVisible.suggestions = $scope.filteredChoices.length > 0 ? true : false;
        }
        else {
            $scope.isVisible.suggestions = false;
        }
    };

    /**
    * Takes one based index to save selected choice object
    */
    $scope.selectItem = function (index) {
        $scope.result = {'chosen': $scope.choices[index - 1], 'type': $scope.type};
        $scope.enteredtext = $scope.result.chosen.label;
        $scope.isVisible.suggestions = false;
        $timeout(function () {
            $scope.$apply();
            if($scope.onselect) {
                $scope.onselect();
            }
        });
    };

    /**
    * Search for states... use $timeout to simulate
    * remote dataservice call.
    */
    function querySearch (query) {
        if(!$scope.choices) return [];
        // returns list of filtered items
        return  query ? $scope.choices.filter( createFilterFor(query) ) : [];
    }

    /**
    * Create filter function for a query string
    */
    function createFilterFor(query) {
        var lowercaseQuery = angular.lowercase(query);

        return function filterFn(item) {
            // Check if the given item matches for the given query
            var label = angular.lowercase(item.label);
            return (label.indexOf(lowercaseQuery) === 0);
        };
    }
});