Jonathan Szekely
Jonathan Szekely

Reputation: 207

How to pass data from directive to controller?

I am currently working on integrating a plugin in my angular application and I'm trying to convert it into a directive. I have fiddled around with the events and methods of the plugin but failed to get the desired results. here's my code:

HTML

<div class="input-daterange datepicker full" rangepicker ng-model="packer.selected.date">
    <i class="fa fa-calendar"></i>
    <div class="inputs datepicker">
        <input 
            ng-model="packer.selected.date.start"
           name="start" 
           value="<% packer.initData.dateStart %>">
        <span class="add-on">-</span>
        <input 
            ng-model="packer.selected.date.end"
           name="end" 
           value="<% packer.initData.dateStart %>">
    </div>
</div>

Javascript:

Application.directive('rangepicker', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs, ngModel) {

            $(element).datepicker({
                format: 'yyyy-mm-dd'
            });

            $(element).on('changeDate', function(){
                /*
                $(element).find('input').each(function(){
                    $(this).trigger('input');

                }) */                
            })

        }
    };
});

Application.controller('PackingStatisticsController', ['$scope', '$http', 'initData', function($scope, $http, initData) {

    var packer = this;
    packer.initData = initData;

    packer.selected = {
        date : {
            start : "",
            end : ""
        },
        user : ""
    }

    packer.log = function()
    {
        console.log(packer.selected);
    }


}]);

I've read anything I thought was relevant to my issue but I haven't managed to shed the veil of confusion. The commented code is supposed to trigger the input value change event which I hoped would update the model. I fail to understand where the model I designate in the html meets my directive's data.

https://bootstrap-datepicker.readthedocs.org/en/latest/index.html this is the plugin I'm working with.

Upvotes: 0

Views: 1249

Answers (2)

Jonathan Szekely
Jonathan Szekely

Reputation: 207

Alas, i have done it!

Application.directive('rangepicker', function() {
    return {
        restrict: 'A',
        require: 'ngModel',    // added the ngmodel requirement
        scope : {              
            ngModel: "="
        },  // also added this, which if i understood well
            // makes the 2 way data binding possible
        link: function(scope, element, attrs) {

            $(element).datepicker({
                format: 'yyyy-mm-dd'
            });

            $(element).on('changeDate', function(){
                var values = $(element).find('input');
                var interval = {
                    start : values[0].value,
                    end : values[1].value
                }                

                scope.$apply(function(){
                    // and here i update the given model scope (packer.selected.data)
                    scope.ngModel = interval;
                });

            })

        }
    };
});

Upvotes: 1

Dima Gimburg
Dima Gimburg

Reputation: 1466

you can pass as an attribute the model you want to modify from the controller's scope like this (look at the scope property):

Application.directive('rangepicker', function() {
return {
    restrict: 'A',
    scope : {
       model : '='
    }
    link: function(scope, element, attrs, ngModel) {

        $(element).datepicker({
            format: 'yyyy-mm-dd'
        });

        $(element).on('changeDate', function(){
            /*
            $(element).find('input').each(function(){
                $(this).trigger('input');

            }) */                
        })

    }
};
});

and in the html:

<div class="input-daterange datepicker full" model="myModelVar" rangepicker ng-model="packer.selected.date">

now the myModeVar is two way data bindable. once you change it in the directive it changes in the controller's scope.

in the controller:

Application.controller('PackingStatisticsController', ['$scope', '$http', 'initData', function($scope, $http, initData) {
    $scope.myModelVar = ...;
}]);

Upvotes: 1

Related Questions