24

I want to implement a search box in my angularJs application. As soon as user starts typing some name in the search box , some REST service should be called and it should fetch all the names which matches the name typed in the search text box. Note that there is no button , the result should come automatically as soon as user starts typing. The REST service is already there. I just need to invoke the REST service when the user starts typing and return the result as a list. For ex:- If I type James then all the user whose name starts with James should come as a list in the search box.

Once the list of name comes , the user can click on one of the name and his information should be loaded in the current page.

How can I implement such type-on search box in angular js? Is there any directive for it? Can anyone please give me some direction.

1

5 Answers 5

31

You should define a directive that listen onkeypress.

app.directive('myOnKeyDownCall', function () {
    return function (scope, element, attrs) {
        element.bind("keydown keypress", function (event) {            
                scope.$apply(function (){
                    scope.$eval(attrs.ngEnter);
                });
                event.preventDefault();
        });
    };
});

HTML

 <input type="text" my-on-key-down-call="callRestService()">   

CONTROLLER

$scope.callRestService= function() {
  $http({method: 'GET', url: '/someUrl'}).
    success(function(data, status, headers, config) {
         $scope.results.push(data);  //retrieve results and add to existing results
    })
}

Would be nice to wait until 3 keys has been typed, for that in directive:

var numKeysPress=0;
element.bind("keydown keypress", function (event) {   
         numKeysPress++;
             if(numKeysPress>=3){
                scope.$apply(function (){
                    scope.$eval(attrs.myOnKeyDownCall);
                });
                event.preventDefault();
              }
        });

Perhaps, exists typeahead directive from angular-ui that you can use: angular-ui typeahead I hope it helps you

Sign up to request clarification or add additional context in comments.

5 Comments

I found the typehead link very useful. Thanks @Jorge!!
scope.$eval(attrs.ngEnter); <-- Does not make sense. Did you mean "attrs.myOnKeyDownCall" ?
Just a little improvement for the matter of the future readers. The numKeyPress logic makes that if the user presses three times, for example, the "Ctrl" key, the REST service is called, instead I would propose: if(element.val().length >= 3) {/*eval stuff*/}
event.preventDefault() prevent character user input from showing.
grabber You probably misspelled directive name
5

Found this to be a simplification of the accepted answer.

// Directive
app.directive('search', function () {
    return function ($scope, element) {
        element.bind("keyup", function (event) {
          var val = element.val();
          if(val.length > 2) {
            $scope.search(val);
          }
        });
    };
});

// In Controller
$scope.search= function(val) {
  // fetch data
}

// HTML
<input type="text" search>

Comments

4

Not sure if you already solved this, but I recommend looking at this tutorial: http://angular.github.io/angular-phonecat/step-12/app/#/phones Essentially it does what you're interested in, but instead it filters out the results while typing. If you got this working, I'm interested in how you did it. I'm trying this as well.

Comments

4

Why so much drama, directives, and Glyptodon blood?

Since angular already has

ng-keypress
ng-keyup
ng-keydown

Use any of those to invoke REST service just as you would with ng-click.

HTML

<input type="search" ng-model="vm.query" ng-keyup="vm.search()" />

JS

vm.search = search;

function search() {
  // Call your cool REST service and attach data to it
  vm.data = MyCoolService.myGetFunctionWhatever();
  // You can use vm.query ng-model to limit search after 2 input values for example
  //     if(vm.query.length > 2) do your magic
};

Comments

2

Bootstrap's "Typeahead, Asynchronous results" does exactly what you want, easily. Go to https://angular-ui.github.io/bootstrap/ then scroll down near to the bottom of the page. I used it in my CRUDiest movies database project: https://crudiest-firebase.firebaseapp.com/#/movies

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.