0

I am beginner with angular. Please help me fix this plunk

I am trying to use only one call back for onSelect callback of jquery UI datepicker widget which is in my controller instead of repeating the callback function in each directive (yes I do have multiple directives for sake of experiment).

But I get this error

Uncaught TypeError: Cannot use 'in' operator to search for 'onSelect' in 19/10/2016

Here is my code

HTML

<html ng-app="myApp">
    <head>
        <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css"/>
        <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
        <script src="script.js"></script>
    </head>
    <body ng-controller="myController">
        <input type="text" my-datepicker ng-model="date" date="date" on-select="onSelect()"/>
        <input type="button" ng-click="submitDate()" value="Submit"/>
    </body>
</html>

JS

var app = angular.module('myApp', []);
app.controller('myController', ['$scope', function($scope){
    $scope.date = "frommyController";
    $scope.submitDate = function(){
        console.log($scope.date);
    };
    $scope.onSelect = function(value, picker){
        scope.date = value;
        scope.$parent.$digest();
    }
}]);
app.directive('myDatepicker', function(){
    return {
        scope: {
            date: "=",
            onSubmit: "&onSelect"
        },
        restrict: 'EA',
        require: "ngModel",
        link: function(scope, element, attributes, modelController){
            scope.date = "fromdirevtive";
            element.datepicker({
                changeMonth: true,
                changeYear: true,
                dateFormat: "dd/mm/yy",
                onSelect: scope.onSubmit
            });
        }
    }
})

can someone help me understanding what wrong am I doing here?

2
  • don't fotgot to appricate my work. Commented Oct 5, 2016 at 10:52
  • @chiragpatel thanks for your help chirag. I understood that since this callback is supposed to be called from outer environment and not by angular. This is not achievable. Commented Oct 5, 2016 at 11:50

3 Answers 3

1

I have a created a new plunkr using your plunkr. Refer this plunker for solution.

Issues found with your plunkr:

  1. The method signature was incorrect in index.html.
  2. The way on invoking a callback with & binding in angular directive.

I have just corrected the above issues. Also instead of using the link function I have used a controller for the directive since it gives me more control in terms of interaction with the directive.

The correct way of invoking a callback in angular directive is by passing an object as the argument. The keys of the object should be the parameters of the callback function. Refer line number 27 of app.js

Code - app.js

var app = angular.module('myApp', []);
app.controller('myController', ['$scope',
  function($scope) {
    $scope.date = "frommyController";
    $scope.submitDate = function() {
      console.log($scope.date);
    };
    $scope.onSelect = function(value, picker) {
      console.log(value);
      console.log(picker);
      $scope.date = value;
      $scope.$parent.$digest();

    }
  }
]);
app.directive('myDatepicker', function() {
  return {
    scope: {
      date: "<",
      onSelect: "&"
    },
    restrict: 'EA',
    require: "ngModel",
    controller: function($scope, $element) {
      vm = this;
      vm.$scope = $scope;
      vm.onSelect = function(value, picker) {
        vm.$scope.onSelect({
          value: value,
          picker: picker
        })
      }

      $element.datepicker({
        changeMonth: true,
        changeYear: true,
        dateFormat: "dd/mm/yy",
        onSelect: vm.onSelect
      });

    }
  }
})


<html ng-app="myApp">

<head>
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" />
  <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="myController">
  <input type="text" my-datepicker ng-model="date" date="date" on-select="onSelect(value,picker)" />
  <input type="button" ng-click="submitDate()" value="Submit" />
</body>

</html>

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

Comments

1

You have two options

Option 1:

Call your callback function in the directive like below:

var app = angular.module('myApp', []);
app.controller('myController', ['$scope', function($scope){
    $scope.date = "frommyController";
    $scope.submitDate = function(){
        console.log($scope.date);
    };
    $scope.onSelect = function(value, picker){
      alert('');
        scope.date = value;
        scope.$parent.$digest();
    }
}]);
app.directive('myDatepicker', function(){
    return {
        scope: {
            date: "=",
            onSubmit: "&onSelect"
        },
        restrict: 'EA',
        require: "ngModel",
        link: function(scope, element, attributes, modelController){
            scope.date = "fromdirevtive";
            element.datepicker({
                changeMonth: true,
                changeYear: true,
                dateFormat: "dd/mm/yy",
                onSelect: function(){scope.$apply(function() {
                    scope.onSubmit();
                }); }
            });
        }
    }
})

Option 2:

Use publisher/subscriber model to do some stuff in your parent controller..like below

var app = angular.module('myApp', []);
app.controller('myController', ['$scope', function($scope){
    $scope.date = "frommyController";
    $scope.submitDate = function(){
        console.log($scope.date);
    };

    $scope.$on('event',function()
    {
      alert('listener');
        scope.date = value;
        scope.$parent.$digest();
    });

}]);
app.directive('myDatepicker', function(){
    return {
        scope: {
            date: "="
        },
        restrict: 'EA',
        require: "ngModel",
        link: function(scope, element, attributes, modelController){
            scope.date = "fromdirevtive";
            element.datepicker({
                changeMonth: true,
                changeYear: true,
                dateFormat: "dd/mm/yy",
                onSelect: function(){scope.$apply(function() {
                  console.log(scope)
                    scope.$emit('event')
                });}
            });
        }
    }
})

Comments

0

Try below directory , instead of your directory:

app.directive('myDatepicker', function(){
    return {
        scope: {
            date: "=",
            onSubmit: "&onSelect"
        },
        restrict: 'EA',
        require: "ngModel",
        link: function(scope, element, attributes, modelController){
            scope.date = "fromdirevtive";
            element.datepicker({
                changeMonth: true,
                changeYear: true,
                dateFormat: "dd/mm/yy",
                onSelect:function(date) {

                scope.$apply(function() {
                    modelController.$setViewValue(date); 
                }); 
            }
            });
        }
    }
})

Hope this will helpful to you.

10 Comments

thats what I want to avoid to create multiple callbacks in multiple directives.
@nikhilmehta , check updated answer , now this is work for you. I also try this in your plunker and it is working , you can check replacing this code in your plunker
then there is no use of passing onSubmit to the directive scope
@nikhilmehta , if it is helpful to you then don't forgot to appreciate my work
you are right these are the ways through which I can achieve the thing. But I am learning angular and want to use only one callback for onSelect in multiple datepicker directives via reference.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.