Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I have an simple app with a input box where if a user types something in the input box an alert message is triggered every-time the user types something (using a keyup).

I want to use a directive for the input box (called searchBar) and call a controller function every time something is inputted.

JSFiddle

var app = angular.module('HelloApp', [])

app.directive('searchBar', function() {
  return {
    restrict: 'AE',
    replace: true,
    template: '<input type="text" ng-model="search" placeholder="Enter a search" />',
    link: function(scope, elem, attrs) {
      elem.bind('keyup', function() {
        elem.css('background-color', 'white');
        scope.$apply(function() {
         scope.search(elem);
        });
      });
    }
  };
});


app.controller('searchbarcontroller', ['$scope', function($scope) {
 $scope.search = function(element) {
     alert ("keypressed. Value so far is: " + element.target.val());
}; 

}]);

Here is the html:

<html ng-app="HelloApp">
<body ng-controller = "searchbarcontroller">
  <search-bar/>
</body>
</html>

I am getting the error scope.search is undefined. How can I fix my code to make it work?

share|improve this question
    
search is once your model in your input and once a function, I think you don't want to do that ;) can't you move (and rename!!!) the search function into the directive? – Betty St Jun 28 '15 at 17:53
up vote 2 down vote accepted

Here is a working JSFiddle

HTML:

<div ng-app="HelloApp">
    <div ng-controller="MyCtrl">
        <search-bar/>
    </div>
</div>

JS:

var app = angular.module('HelloApp', []);

app.directive('searchBar', function() {
    return {
        restrict: 'AE',
        replace: true,
        template: '<input type="text" ng-model="searchData" placeholder="Enter a search" />',
        link: function(scope, elem, attrs) {
            elem.bind('keyup', function() {
                elem.css('background-color', 'red');
                scope.$apply(function() {
                    scope.search(elem);
                });
            });
        }
    };
});

app.controller('MyCtrl', function($scope) {
    $scope.search = function(element) {
        console.log(element);
        alert("keypressed. Value so far is: " + element.val());
    };
});
share|improve this answer
    
So there is no way to link in a pre-existing external controller? – BDillan Jun 28 '15 at 17:57
    
Of course you can, answer and fiddle updated. Look – Michelem Jun 28 '15 at 18:03
    
@BDillan yes there is..take a look at mine answer.. – Pankaj Parkar Jun 28 '15 at 18:17

This is a working fiddle: http://jsfiddle.net/36qp9ekL/365/

app.directive('searchBar', function() {
  return {
    restrict: 'AE',
    replace: true,
    template: '<input type="text" ng-model="query" ng-click="search(query)" placeholder="Enter a search" />',
    link: function(scope, elem, attrs) {
      elem.bind('keyup', function() {
        elem.css('background-color', 'white');
        scope.$apply(function() {
         scope.search(elem);
        });
      });
    }
  };
});

Search was once used as a model and then a function. You probably don't need a directive for keyup as angular has an in-built ng-blur. See this: https://docs.angularjs.org/api/ng/directive/ngBlur

share|improve this answer

If you want to reusable then you could use isolated scope here, in only need to pass method to directive serach-method attribute, which will bind that event to be called on keyup so that if user types anything then search method gets called. In that you could pass event object by using which you can eaisily get a value of target element from event object.

Markup

<body ng-controller="searchbarcontroller">
    <search-bar serach-method="search(event)"></search-bar>
</body>

Directive

app.directive('searchBar', function () {
    return {
        restrict: 'AE',
        scope: {
            serachMethod: '&'
        },
        replace: true,
        template: '<input type="text" ng-model="search" placeholder="Enter a search" />',
        link: function (scope, elem, attrs) {
            elem.bind('keyup', function (event) {
                elem.css('background-color', 'white');
                scope.$apply(function () {
                    scope.serachMethod({event: event}); //calling controller method.
                });
            });
        }
    };
});

Controller

$scope.search = function (element) {
    alert("keypressed. Value so far is: " + element.target.value);
};

Working Fiddle here

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.