Search Part VI: Autocomplete
Highlighting
by rocketegg0
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.1/angular-sanitize.min.js"></script>
<div ng-controller="MyCtrl">
<h2>Part 6: Autocomplete</h2>
<div>Search: <input type="text" ng-model="textIn"></input></div>
<div>Limit: <input type="number" ng-model="limit"></input>
<p>Use 0 for unlimited</p>
</div>
<div>Use BFS: <input type="radio" ng-model="bfs" ng-value=
"true"></input>
Use DFS: <input type="radio" ng-model="bfs" ng-value="false"></input>
</div>
<div>
<table>
<caption>Search Results ({{ results.length }})</caption>
<tr>
<th>Words</th>
</tr>
<tr ng-repeat="word in results">
<td><a ng-href="#{{word}}" ng-click="select(word)">{{::word}}</a></td>
</tr>
</table>
<table>
<tr>
<td>
<p><strong>{{textIn}}<strong></p>
<p><em>{{dictionary[textIn.toUpperCase()]}}</em></p>
</td>
</tr>
</table>
</div>
</div>
CSS
h2 {
font-size: 150%;
}
table {
margin-top: 10px;
border: 1px solid #ccc;
width: 100%;
}
table th {
font-weight: bold;
}
em {
font-style:italic;
}
strong {
font-weight: bold;
}
}
JavaScript
var myApp = angular.module('myApp',['ngSanitize']);
myApp.controller('MyCtrl', function($scope, $http) {
// Compute unique hash words
var toHash = function(dict) {
return Object.keys(dict.split(' ').reduce(function(memo, word) {
if (!memo.hasOwnProperty(word)) { memo[word] = true; }
return memo;
}, {})).sort();
};
// Compute prefix trie
var toTrie = function(words) {
var root = new Node();
words.forEach(function(word) {
root.insert(word.toLowerCase());
});
return root;
};
$scope.select = function(word) { $scope.textIn = word; };
$scope.autocomplete = function(textIn) {
if (!textIn || textIn.length < 2) {
return [];
}
var node = $scope.root;
var path = '';
var chars = textIn.split('').map(function(c) { return c.toLowerCase(); })
for (var i = 0; i < chars.length; i++) {
if (node && node.children.hasOwnProperty(chars[i])) {
node = node.children[chars[i]];
path += chars[i];
} else {
return [];
}
}
if (!node.hasChildren()) {
return [path];
}
$scope.current_node = node;
var results = [];
if ($scope.bfs) {
node.traverseBFS(results, path.substr(0, path.length-1), $scope.limit);
} else {
node.traverseDFS(results, path, $scope.limit);
}
return results;
};
/* load dictionary */
$scope.limit = 10;
$scope.bfs = true;
$http.get("https://raw.githubusercontent.com/adambom/dictionary/master/dictionary.json").then(function(response) {
$scope.dictionary = response.data;
$scope.root = toTrie(Object.keys($scope.dictionary));
$scope.$watch('textIn', function(newText) {
$scope.results = $scope.autocomplete(newText);
});
$scope.$watch('limit', function(newLimit) {
...