Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am developing my first app using Angular and I got stuck with this problem for a couple of hours now and I can't see what's wrong. I have used ui-bootstrap date with no issues in other places but than I tried using it inside a modal and what happens is that whenever you pick a date inside the modal for the first time it works properly but than if you pick the wrong date and want to pick the correct one clicking the button to open the calendar a second time it doesn't work if it's inside the modal.

I have created a plunker sample where the error is reproduced.

code fragments follows:

index.html

<!DOCTYPE html>
<html ng-app="myApp">

<head>
<link data-require="[email protected]" data-semver="3.1.1" rel="stylesheet"      href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link data-require="[email protected]" data-semver="3.2.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" />
<script data-require="[email protected]" data-semver="1.2.21" src="https://code.angularjs.org/1.2.21/angular.js"></script>
<script data-require="[email protected]" data-semver="0.11.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script>
<script src="app.js"></script>
</head>

<body>
<h1>Angular ui date!</h1>
<div ng-controller="DateController">
  <div class="row">
      <div class="col-md-6">
          <h4>Date(This works)</h4>
          <p class="input-group">
              <input type="text" class="form-control" datepicker-popup="{{format}}" disabled
                     ng-model="activityDate" is-open="opened" datepicker-options="dateOptions"
                     ng-required="true" close-text="Close"/>

            <span class="input-group-btn">
              <button type="button" class="btn btn-default" ng-click="open($event)"><i
                      class="glyphicon glyphicon-calendar"></i></button>
            </span>
          </p>
      </div>
  </div>
  <div class="row">
      <div class="col-md-6">
          <button type="button" class="btn btn-primary" ng-click="openModal()">Open Date Modal</button>
      </div>
  </div>
</div>

dateModal.html

<div>
<div class="modal-header">
  <h3 class="modal-title">Date Modal Sample</h3>
</div>
<div class="modal-body">
<div class="row">
  <div class="col-md-6">
      <h4>Modal Date(works only the first time! whyyyyyy?????)</h4>

      <p class="input-group">
          <input type="text" class="form-control" datepicker-popup="{{format}}" disabled
                 ng-model="dateModal" is-open="opened"
                 ng-required="true" close-text="Close"/>
            <span class="input-group-btn">
              <button type="button" class="btn btn-default" ng-click="open($event)">
                <i class="glyphicon glyphicon-calendar"></i>
              </button>
            </span>
      </p>
  </div>
</div>
</div>
<div class="modal-footer">
  <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</div>

app.js

'use strict';

(function () {
var myApp = angular.module('myApp', ['ui.bootstrap']);

myApp.controller('DateController', ['$scope', '$modal', '$log', function($scope, $modal, $log){
  //Initializes date
    $scope.today = function () {
        $scope.activityDate = new Date();
    };

    //open calendar to select initial date
    $scope.open = function ($event) {
        $event.preventDefault();
        $event.stopPropagation();
        $scope.opened = true;
        $log.info('open function was called');
    };

    $scope.today();
    $scope.format = 'MM/dd/yyyy';


    //open modal window
    $scope.openModal = function () {
        var modalInstance = $modal.open({
            templateUrl: 'dateModal.html',
            controller: 'DateModalController'
        });
    }

}]);

myApp.controller('DateModalController', ['$scope', '$modalInstance', function($scope, $modalInstance){

  $scope.cancel = function () {
      $modalInstance.dismiss('Cancel');
  };

  //Initializes date
  $scope.today = function () {
      $scope.dateModal = new Date();
  };

  //open calendar to select initial date
  $scope.open = function ($event) {
      $event.preventDefault();
      $event.stopPropagation();
      $scope.opened = true;
      $log.info('open button from modal calendar field has been pressed!!!!');
  };
  $scope.today();
  $scope.format = 'MM/dd/yyyy';
}]);

})();
share|improve this question
    
See this question which had a similar (if not the same) problem: stackoverflow.com/questions/25375075/… –  link64 Aug 20 at 2:12

2 Answers 2

up vote 1 down vote accepted

Scopes inherit from their parent scopes.

The modal is created as a child of the scope that you passed in when initalising it (or on the $rootScope by default). When attempting to set a property directly on the scope, angular will automatically create it for you. However, if you try doing model.myProperty, if model doesn't exist on the child scope, it will travel up to the parent and correctly set it there (if it exists).

A good description on how scopes work can be found here: https://github.com/angular/angular.js/wiki/Understanding-Scopes

Here is a working sample without having to resort to using $parent.

http://plnkr.co/edit/WeJqirLDOoFuTqJEHEdg

 <input type="text" class="form-control" datepicker-popup="{{format}}" disabled
                     ng-model="dateModal.date" is-open="dateModal.opened" 
                     ng-required="true" close-text="Close"/>
share|improve this answer
    
Thanks for the answer. Had to accept this one as it ships a better explanation. I am also assuming that this is better implementation than using $parent right? Or it doesn't really matters? –  Marcos Maia Aug 20 at 13:42
1  
Using $parent will just take you to the direct parent. It doesn't cater for situations where you might be multiple levels deep. For simple applications it may not be a problem, but once you have multiple directives and controllers in an application I would avoid using it –  link64 Aug 20 at 13:46

Pretty sure it's related to the modal's scope overriding your scope and $scope.opened in the directive. I'm not sure the exact cause but you can work around it by using is-open="$parent.opened" in your dateModal template.

share|improve this answer
    
Thanks, that worked. I would still like to understand whyyy???. I am new to Angular and advanced javascript so it would be great to get a detailed explanation on this issue. Anyway, that's great. It works. Thank you very much. –  Marcos Maia Aug 20 at 13:22
    
Please take a look at the nice explanation from @link64 above. –  Marcos Maia Aug 20 at 13:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.