Cameron
Cameron

Reputation: 28853

Search suggestion with AngularJS

I'm trying to replicate the suggestion seen on: https://devart.withgoogle.com/ when you start typing certain words in the search box.

For my HTML I have:

<form ng-controller="SearchCtrl">
    <input name="q" ng-model="query" ng-keypress="querySuggest()" type="text">
    <div class="search__enhance">
        <span class="search__offset" ng-bind="suggestion.query"></span>
        <span class="search__suggestion" ng-bind="suggestion.text"></span>
    </div>
</form>

And then in my controller I have:

myApp.controller('SearchCtrl', function($rootScope, $scope, $state, $location) {

    $scope.querySuggest = function () {

        var haystack = ["ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Small Talk", "Scheme"];

        $scope.suggestion.query = '';

        $scope.suggestion.text = '';

    }

});

So the next bit is to show the results inside the input (splitting what the user has typed and what the suggestion is).

enter image description here

What I'm confused with is how to do the following:

  1. Show the search suggestion (minus the entered query in the search__suggestion span element.
  2. Show the query in the search__offset span element (from what I can tell they don't show the value in the input itself...)
  3. Match the entered query with the haystack array.

Any ideas for these three?

Upvotes: 4

Views: 3453

Answers (1)

Shomz
Shomz

Reputation: 37711

Put a separate element "behind" the actual input. Use that element to show suggestiong which you'll fetch using the onchange listener on the input element. That takes care of #1 and #2.

For #3, you can do a simple matching against the haystack.


Here's a fully working example, use the right arrow to confirm the suggestion:

angular.module('myApp', [])
  .controller('SearchCtrl', function($rootScope, $scope, $location) {

    $scope.suggestion = {};

    var haystack = ["ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Small Talk", "Scheme"];

    $scope.querySuggest = function($event) {
      if ($event.keyCode == 39) {    // confirm suggestion with right arrow
        $scope.query = $scope.suggestion.text;
        return;
      }
      $scope.suggestion.text = '';
      for (var i = 0; i < haystack.length; i++) {
        if ($scope.query && haystack[i].indexOf($scope.query) === 0) {
          $scope.suggestion.text = haystack[i];
          console.log(haystack[i]);
          break;
        }
      }

    }

  });
form {
  position: relative;
}
.search__suggestion {
  font: normal normal normal 14px/normal Arial;
  position: absolute;
  left: 2px;
  top: 3px;
  color: #aaa;
  z-index: -1;
}
input {
  font: normal normal normal 14px/normal Arial;
  background: transparent;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<form ng-app="myApp" ng-controller="SearchCtrl" autocomplete="off">
  <input name="q" ng-model="query" ng-keyup="querySuggest($event)" type="text">
  <div class="search__enhance">
    <span class="search__suggestion" ng-bind="suggestion.text"></span>
  </div>
</form>

Upvotes: 2

Related Questions