François Romain
François Romain

Reputation: 14393

datepicker inside a modal not working

I am trying to use ui-bootstrap components to make a datepicker inside a modal. The datepicker has to send back a date formatted as a unix timestamp.

  1. this is working fine if the datepicker is not inside a modal (= the timestamp updates when the date is selected): http://plnkr.co/edit/xQFmVgJojiq6aG9U8f4H?p=preview

  2. then, i put the directive inside a modal: http://plnkr.co/edit/9zHQQPGAcomT5Vha33j3?p=preview

here are the controllers :

.controller('MyCtrl', [ '$scope', '$modal', function ($scope, $modal) {
    $scope.open = function () {
        var modalInstance = $modal.open({
            templateUrl: 'tplModal.html',
            controller: 'MyModalCtrl'
        });
    };
}])
.controller('MyModalCtrl', [ '$scope', '$modalInstance', function ($scope, $modalInstance) {
    $scope.required= {};
    $scope.disabled = function(date, mode) {
        return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
    };
    $scope.minDate = new Date();
    $scope.$watch('dt', function() { 
        if ($scope.dt) $scope.required.timestamp = Math.floor($scope.dt.getTime() / 1000); 
        console.log('timestamp: ', $scope.required.timestamp, '/ dt: ', $scope.dt);
    });
    $scope.cancel = function () {
        $modalInstance.dismiss('cancel');
    };
}]);

and the html template of the modal :

<div class="modal-body">
    <div ng-model="dt">
        <datepicker min="minDate" show-weeks="false"></datepciker>
    </div>
    <div>
        dt <span class="uneditable-input span2">{{dt | date:'dd.MM.yyyy' }}</span>
        dt <span class="uneditable-input span2">{{ dt }}</span>
        timestamp <span class="uneditable-input span2">{{ required.timestamp }}</span>
    </div>
</div>

In this 2nd version the timestamp doesn't update when the date is changed (it's like the $watch was not working).

Do you know how to make this work ?

Upvotes: 6

Views: 8066

Answers (2)

Sergiu Paraschiv
Sergiu Paraschiv

Reputation: 10153

You'll have to apply the same trick you did for timestamp and put it in an object on the scope as I did here.

$scope.picker = {
  dt: new Date(),
  timestamp: ''
};

Upvotes: 1

pkozlowski.opensource
pkozlowski.opensource

Reputation: 117370

You need to use the famous "dot" in the ng-model expression as $modal is creating a trasclusion scope for the window's content. In other words, there is a a scope created between your controller and modal's content.

Anyway, using the dot in the ng-model expression (which is the best practice) solves the problem for you:

<div ng-model="dt.value">
  <datepicker min="minDate" show-weeks="false"></datepciker>
</div>

and in JavaScript:

$scope.dt = {};
$scope.$watch('dt.value', function(newValue) { 
  if (newValue) $scope.required.timestamp = Math.floor(newValue.getTime() / 1000); 
  console.log('timestamp: ', $scope.required.timestamp, '/ dt: ', newValue);
});

Working plunk here: http://plnkr.co/edit/Adst8I8S0e0DLcVnhpLq?p=preview

Upvotes: 7

Related Questions