<!DOCTYPE html>
<html ng-app="SimpleApp">
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body ng-controller="simpleCtrl">
<typeahead list='testData' dont-close-on-select=true list-template='basic'></typeahead>
<typeahead list='testData' dont-close-on-select=true list-template='styling'></typeahead>
<div ng-repeat="item in selectedElements">{{item.index}}</div>
<typeahead list='testData' dont-close-on-select=true list-template='hide'></typeahead>
<script data-require="lodash.js@*" data-semver="3.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0-rc.0/angular.js"></script>
<script src="script.js"></script>
</body>
</html>
<!--TODO
local vs remote data
query the service, if there are more than X items to be loaded keep in on the server we will ask for them in bunches
if there are less than X we will take them all now
-->
angular.module('SimpleApp', [])
// Attribute Isolated Scope
.controller('simpleCtrl', function($scope, $parse) {
$scope.testData = [{
"index": 0,
"isActive": false,
}, {
"index": 1,
"isActive": true,
}];
$scope.basic = '<li>{{item.index}}</li>';
$scope.styling = '<li style="background-color: darkgrey" ng-style="{\'color\': isActive?\'red\':\'blue\'}">{{item.index}}</li>';
$scope.hide = '<li ng-hide="isActive" style="background-color: darkgrey; color: red">{{item.index}}</div><div ng-show="isActive" style="background-color: darkgrey; color: blue">{{item.index}}</li>';
})
.directive('typeahead', ['$parse', '$interpolate', '$compile',
function($parse, $interpolate, $compile) {
'use strict';
return {
restrict: 'E',
templateUrl: 'template.html',
scope: {
list: '=',
dontCloseOnSelect: '=',
listTemplate: '='
},
link: function(scope, elm, attr) {
scope.inputHasFocus = false;
scope.visibleList = scope.list;
scope.selecting = false;
scope.createListItem = function (template, listElm) {
scope.$apply(function() {
var listElm = angular.element(listElm);
console.log('compiled', template, $compile(scope.listTemplate)(scope));
listElm.append($compile(template)(scope));
});
}
setTimeout(function() {
var spanList = elm.find('li');
for (var index = 0; index < scope.list.length; index++) {
scope.createListItem(scope.listTemplate, spanList[index])
}
console.log(' ')
}, 0);
scope.registerInputChange = function() {
scope.visibleList = _.filter(scope.list, function(element) {
return element.index === parseInt(scope.filterInput);
});
};
scope.inputLosesFocus = function() {
if (!scope.selecting) {
scope.inputHasFocus = false;
scope.savedInput = scope.filterInput;
scope.filterInput = "";
} else {
scope.selecting = false;
elm.find('input')[0].focus();
}
};
scope.selectItem = function(item) {
if (scope.dontCloseOnSelect) {
scope.selecting = true;
}
console.log(item);
};
}
};
}
])
<!DOCTYPE html>
<div class='typeaheadContainer'>
<div class="typeaheadContainer">
<input ng-model='filterInput' ng-model-options='{ debounce: 150 }' ng-change='registerInputChange()' ng-focus='inputHasFocus = true;' ng-blur='inputLosesFocus()'>
<ul ng-show='filterInput || inputHasFocus'>
<li class='list'
ng-repeat='item in visibleList'
ng-mousedown='selectItem(item)'>
</li>
</ul>
</div>
</div>
ul {
list-style-type: none;
padding: 0px;
margin: 0px;
max-height: 205px;
overflow-y: scroll;
overflow-x: hidden;
max-width: 200px;
}