1

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?

1
  • 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? Commented Jun 28, 2015 at 17:53

3 Answers 3

3

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());
    };
});
Sign up to request clarification or add additional context in comments.

1 Comment

So there is no way to link in a pre-existing external controller?
0

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

Comments

0

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

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.