SrgHartman
SrgHartman

Reputation: 651

AngularJS custom directive: how to update parent variable specified in ng-model?

I'm trying to create a simple directive but its not going well. My directive is a div that has a datepicker. The directive is used by typing pickmoment as an attribute:

<p>Publish: <b>{{publishedTime}}</b></p>
<div ng-model="publishedTime" pickmoment>
</div>

As you can see I'm trying to update publishedTime from inside the directive. It does not work. The directive is defined as follows:

app.directive('pickmoment', function() {
    return {
        restrict: 'A',
        scope: true,

        template: '
                <input class="datepicker" id="_pickmoment" value="now" type="text">\
                <br><br>\
                <button type="button" class="okbutton">Ok</button>\
                <button type="button">Cancel</button>',

        link: function (scope, element, attr) {
                $(element).find('.datepicker').datepicker( { format: "MM d, yyyy", autoclose:true } );
                scope.$parent[attr.ngModel] = 'default value';

                $(element).find('.okbutton').click(function () {

                    var helpDate = $('#_pickmoment').val();
                    scope.$parent[attr.ngModel] = helpDate;

                });
        },

    };
  });

"Default value" for ng-model variable is set correctly but any update when click the Ok button does not do anything.

Can you help me? Thanks!

Upvotes: 1

Views: 1145

Answers (2)

manohar
manohar

Reputation: 155

You can also use the two way binding('=') to the parent variable instead of accessing $parent right?. (this might be a comment, but i don't have reputation)

Upvotes: 0

ms87
ms87

Reputation: 17492

A more elegant approach:

app.directive('pickmoment', function() {
    return {
        restrict: 'A',
        require:'ngModel',
        template: '
                <input class="datepicker" id="_pickmoment" value="now" type="text">\
                <br><br>\
                <button type="button" class="okbutton">Ok</button>\
                <button type="button">Cancel</button>',

        link: function (scope, element, attr,ngModelCtrl) {
                $(element).find('.datepicker').datepicker( { format: "MM d, yyyy", autoclose:true } );

                $(element).find('.okbutton').click(function () {
                    var helpDate = $('#_pickmoment').val();
                    scope.$apply(function () {
                            ngModelCtrl.$setValidity('someValidationError', scope.validateDate(helpDate));
                            ngModelCtrl.$setViewValue(helpDate);
                        });

                });
                scope.validateDate = function(date) {
                  //you can perform custom validation here, like a regex check or whatever
                };
        },

    };
  });

The angular way would be to require an ngModel for the directive, which makes validation and also manually setting the elements value (since you're using jQuery) a whole lot easier, the validation code is not necessary but you can see that you have a lot of options when you work with the ngModel of the directive. Of course the most angular way is to not use jQuery at all but that's a different discussion altogether.

Upvotes: 3

Related Questions