angular.module('plunker', ['ui.bootstrap', 'incSearch', 'movieService'])
  .controller('MainCtrl', function($scope, $q, movieService) {
    $scope.movies = movieService.movies;
    $scope.findMovie = function(value) {
      var deferred = $q.defer();
      if (!value) {
        deferred.reject([]);
      } else {
        var matched = [];
        angular.forEach($scope.movies, function(e) {
          var re = new RegExp(value, 'i');
          if (e.name.match(re) || String(e.id).match(re)) matched.push(e);
        });
        deferred.resolve(matched);
      }
      return deferred.promise;
    }
  })
<!doctype html>
<html ng-app="plunker">

<head>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.js"></script>
  <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  <script src="directives/ui-bootstrap-inc-search.js"></script>
  <script src="services/movieService.js"></script>
  <script src="app.js"></script>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
  <link href="style.css" rel="stylesheet">
</head>

<body ng-controller="MainCtrl">
  <div id="content">
    <div>
    <div class="lead" ng-hide="movie">
      You can search your favorite David Lynch's movie incrementally with ID or NAME.
    </div>
    <div class="lead" ng-show="movie">
      <p>You've selected <b><span ng-bind="movie.name" /></b> !!</p>
      <small>If you want to search again, please click &times; in selected label.</small>
    </div>
    
    <div class="search_area">
        <inc-search 
          ng-model="movie" 
          inc-item-value="name" 
          inc-searcher="findMovie" 
          inc-item-label="this.id + ':' + this.name" 
          inc-selected-label="movie.id + ':' + movie.name" />
    </div>
    
    <table class="table">
      <thead>
        <tr>
          <th>ID</th>
          <th>NAME</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="m in movies">
          <td>{{m.id}}</td>
          <td>{{m.name}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</body>

</html>
angular.module('movieService', []).service('movieService', function() {
  return {
    movies: [
    {id:1, name:"Six Men Getting Sick (Six Times)"},
    {id:2, name:"Absurd Encounter with Fear"},
    {id:3, name:"Fictitious Anacin Commercial"},
    {id:4, name:"The Alphabet"},
    {id:5, name:"The Grandmother"},
    {id:6, name:"The Amputee"},
    {id:7, name:"The Cowboy and the Frenchman"},
    {id:8, name:"Industrial Symphony No. 1"},
    {id:9, name:"Premonition Following An Evil Deed"},
    {id:10, name:"Darkened Room"},
    {id:11, name:"Dumbland"},
    {id:12, name:"Ballerina"},
    {id:13, name:"Absurda"},
    {id:14, name:"Boat"},
    {id:15, name:"Bug Crawls"},
    {id:16, name:"Industrial Soundscape"},
    {id:17, name:"Lamp"},
    {id:18, name:"Out Yonder Neighbor Boy"},
    {id:19, name:"Intervalometer Experiments"},
    {id:20, name:"Scissors"},
    {id:21, name:"Lady Blue Shanghai"},
    {id:22, name:"The 3 Rs"},
    {id:23, name:"Idem Paris"},
    {id:24, name:"Twin Peaks"},
    {id:25, name:"On the Air"},
    {id:26, name:"Hotel Room"},
    {id:27, name:"The Cleveland Show (voice actor only - Gus the Bartender)"},
    {id:28, name:"Louie (actor only)"},
    {id:29, name:"Eraserhead"},
    {id:30, name:"The Elephant Man"},
    {id:31, name:"Dune"},
    {id:32, name:"Blue Velvet"},
    {id:33, name:"Wild at Heart"},
    {id:34, name:"Twin Peaks: Fire Walk with Me"},
    {id:35, name:"Lost Highway"},
    {id:36, name:"The Straight Story"},
    {id:37, name:"Mulholland Drive"},
    {id:38, name:"Inland Empire"},
  ]};
});

#content { margin: 40px 10px;}
.table { margin: 10px;}
.search_area { width: 300px; }
 angular.module('incSearch', [])
  .directive('incSearch', function() {
     return {
      restrict: 'E',
      require: 'ngModel',
      link: function(scope, elem, attrs, ctrl) {

        var incSearcher = $(elem).attr('inc-searcher');
        var incSelectedLabel = $(elem).attr('inc-selected-label');
        var incItemLabel = $(elem).attr('inc-item-label');
        var width = $(elem).attr('width');

        var $selectedLabel = $('<div class="alert alert-success alert-dismissable" style="padding: 6px 25px 6px 6px">')
          .append('<span class="inc-label">')
          .append('<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>')
          .hide();
        var $dropDown = $('<div class="dropdown">');
        var $searchText = $('<input type="text" class="form-control"/>');
        var $dropdownMenu = $('<ul class="dropdown-menu">');
        $(elem)
          .append($selectedLabel)
          .append($dropDown.append($searchText).append($dropdownMenu));

        var deffered = null;

        $searchText
          .bind('keyup', function() {
            var value = $searchText.val();
            var promise = scope[incSearcher](value);

            promise.then(
              function(items) {
                applyItems(items);
              },
              function() {
                $dropDown.removeClass('open');
              }
            );
          })
          .bind('blur', function() {
            if (! $dropdownMenu.is(':hover')) {
              $dropDown.removeClass('open');
            }
          })
          .bind('focus',function() {
            if ($(this).val())  $dropDown.addClass('open');
          });

        $dropdownMenu.on('click', 'a', function() {
          scope[attrs.ngModel] = $(this).data();
          $selectedLabel.find('.inc-label').text(scope.$eval(incSelectedLabel)).end().show();
          $dropDown.removeClass('open').hide();
          $searchText.val('');
          scope.$apply();
        });

        $selectedLabel.on('click', '.close', function() {
          $selectedLabel.hide();
          $dropDown.show();
          scope[attrs.ngModel] = undefined;
          scope.$apply();
        });
        
        scope.$watch(attrs.ngModel, function(value) {
          if (! value) return;
          $selectedLabel.find('.inc-label').text(scope.$eval(incSelectedLabel)).end().show();
          $dropDown.removeClass('open').hide();
          $searchText.val('');
        });

        function applyItems(items) {
          $dropdownMenu.find('li').remove();
          if (0 < items.length) {
            $dropDown.addClass('open');
          } else {
            $dropDown.removeClass('open');
          }
          angular.forEach(items, function(item) {
            item.__incCreateName = function() {
              return eval(incItemLabel);
            };
            var label = item.__incCreateName();
            $dropdownMenu.append($('<li>').append($('<a>').text(label).data(item)));
          });
        }
      }
    }
  });