9

I was using ng-include on a few of my pages, however I had to stop using ng-include because it was breaking the angular-ui datepicker. I opened this Github bug.

I am wondering if anyone else was having issues with directives not functioning the same way when being used as part of a ng-include.

Is there a way to make the datepicker work as expected as part of a ng-include?

Here is a plunker showing how it is broken. http://plnkr.co/edit/AboEJGxAK3Uz76CfpaZ0?p=preview

Here is the html that works when on the view, but does not work when part of a ng include.

<div class="row">
  <div class="col-md-2">
    <p class="input-group">
      <input type="text" class="form-control" datepicker-popup="yyyy/MM/dd" ng-model="something.dt2" is-open="secondCal"
         min-date="minDate" name="secondCal" max-date="'2015-06-22'" datepicker-options="dateOptions"
         date-disabled="disabled(date, mode)" ng-required="true" close-text="Close"/>
        <span class="input-group-btn">
          <button type="button" class="btn btn-default" style="line-height: 1.2em" ng-click="open($event, 'secondCal')">
            <i class="ss-icon ss-calendar"></i>
          </button>
        </span>
    </p>
  </div>
</div>

Here is the JS from the controller.

$scope.open = function ($event, elementOpened) {
      $event.preventDefault();
      $event.stopPropagation();

      $scope[elementOpened] = !$scope[elementOpened];
  };

And two ways I was doing ng-include

<div ng-include src="'dist/partials/myPartial.html'"></div>
<div ng-include="'dist/partials/myPartial.html'"></div>

Update I found that this is because the ng-include directive creates a new scope for each include. This SO post creates a new directive that does the include without creating a new scope. However there seems there "should" be a way to fix it without using a different include.

2 Answers 2

20

The datepicker will be unable to open as soon as the is-open is changed by the datepicker directive itself (e.g. click outside to close the datepicker).

This is a common issue regarding the "Prototypal Inheritance" characteristic of scope.

For a complete detail, you could read this: Understanding-Scopes

You could easily solve this by not storing any primitive values directly into $scope, but some object and using dot-notation like this:

<input type="text" class="form-control"
    datepicker-popup="yyyy/MM/dd" ng-model="something.dt2"
    is-open="model.secondCal"

and in your controller:

app.controller('MainCtrl', function($scope) {
  $scope.model = {};

  $scope.open = function($event, elementOpened) {
    $event.preventDefault();
    $event.stopPropagation();

    $scope.model[elementOpened] = !$scope.model[elementOpened];
  };
});

Example Plunker: http://plnkr.co/edit/dJNIwSz2Uot3McmIMhd4?p=preview

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

1 Comment

thank you for this! I did change $scope.model[elementOpened] = !$scope.model[elementOpened]; to $scope.model[elementOpened] = true; but everything works as expected. Kudos.
0

I've created Plunker to debug it but it works fine with your code

http://plnkr.co/edit/nxYCiwRqdWMOkfZoRhGY?p=preview

<body ng-controller="MainCtrl">
  <div ng-include="'partial.html'"></div>
</body>

after clarification and further tests i see that calendar with ng-include lose the scope when triggering the change not by scope method, the easy workaround would be as per this plunker

http://plnkr.co/edit/nxYCiwRqdWMOkfZoRhGY?p=preview

Don't remember which one of the angular team said it but if you don't have a dot in your model you are doing it wrong.

a little explanation why it works:

if you do

$scope.valueName = value

it will assign value to the current scope immediately

but if you do

$scope.something.valueName = value

what will happen is that angular will first locate $scope.something, if it doesn't exists on current scope it will look in parent (as long as you don't work in isolated scope) then when it finds it it will assign value or return something like 'cant find valueName of undefined'

from the angularjs documentation: https://docs.angularjs.org/api/ng/directive/ngInclude

This directive creates new scope. This directive executes at priority level 400.

5 Comments

the datepicker opens once, after you close it, it will not open again.
Updated to make it a little easier to click plnkr.co/edit/nxYCiwRqdWMOkfZoRhGY?p=preview
I click it over and over again and it close and open as expected
@maurycy After open the datepicker, click anywhere beside the Click button.
According to this post, the one that said is Miško.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.