最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS uib-datepicker doesn't display calendar after the first openclose event while in uib-tab - Stack

programmeradmin5浏览0评论

Versions:

  • Bootstrap 3.5.5
  • AngularJS 1.4.7
  • AngularUIB 0.14.3

I'm using a uib-datepicker in a tabbed page (using uib-tabset)

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='isDatePickerOpen' ng-click='openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

Controller Code:

app.controller("ctrl", function($scope, heatMapSvc){
  $scope.isDatePickerOpen = false;

  $scope.openDatePicker = function(){
    $scope.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", $scope.isDatePickerOpen);
  };
});

When selecting the input, the datepicker calendar appears as expected. Once I select a date, however, the datepicker calendar won't reappear on selection. I've unfocused and refocused the control, nothing. In my openDatePicker method call, I write to console to ensure that the method is getting called. Every time I select the datepicker (regardless if the calendar appears), the controller is firing the correct method.

I've taken the datepicker out of the tabset that it was wrapped in, and the datepicker works correctly (shows the calendar every selection). I need this datepicker to work correctly within the uib-tabset that I've defined.

Versions:

  • Bootstrap 3.5.5
  • AngularJS 1.4.7
  • AngularUIB 0.14.3

I'm using a uib-datepicker in a tabbed page (using uib-tabset)

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='isDatePickerOpen' ng-click='openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

Controller Code:

app.controller("ctrl", function($scope, heatMapSvc){
  $scope.isDatePickerOpen = false;

  $scope.openDatePicker = function(){
    $scope.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", $scope.isDatePickerOpen);
  };
});

When selecting the input, the datepicker calendar appears as expected. Once I select a date, however, the datepicker calendar won't reappear on selection. I've unfocused and refocused the control, nothing. In my openDatePicker method call, I write to console to ensure that the method is getting called. Every time I select the datepicker (regardless if the calendar appears), the controller is firing the correct method.

I've taken the datepicker out of the tabset that it was wrapped in, and the datepicker works correctly (shows the calendar every selection). I need this datepicker to work correctly within the uib-tabset that I've defined.

Share Improve this question edited Dec 30, 2015 at 22:01 Jon asked Dec 30, 2015 at 21:08 JonJon 1,10513 silver badges24 bronze badges 2
  • Can you post your controller's code nevertheless? – Daniel Commented Dec 30, 2015 at 21:47
  • @Daniel, I added the relevant snippets of the controller. I work on a closed network, so copying large amounts of code gets tricky. – Jon Commented Dec 30, 2015 at 22:03
Add a ment  | 

2 Answers 2

Reset to default 7

Problem is in "scope inheritance". Angular scopes is based on js objects prototype inheritance.

So... $scope <- { uib-tables scope } <- { uib-tab scope } and at first time, { uib-tab scope } has not isDatePickerOpen property an it taken from $scope, but after poput is closed, { uib-tab scope } will take own isDatePickerOpen than equal false, and the latter is more a priority. Function openDatePicker changing $scope.isDatePickerOpen, but calendar directive will take value from { uib-tab scope }.

you can see it if will add {{isDatePickerOpen}} after input tag. After first time calendar opened it always wil be false.

Solution

1) use controllerAs syntax. remended

controller:

  var vm = this;

  vm.isDatePickerOpen = false;

  vm.openDatePicker = function(){
    vm.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", vm.isDatePickerOpen);
  };

template:

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='vm.isDatePickerOpen' ng-click='vm.openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

Note! For using this solution you must using controller as syntax for declare a controller.

<body ng-controller="SettingsController1 as vm">
...
</body>

or if you use ui-router

$stateProvider.state('contacts', {
  templateUrl: '...',
  controller: function(){
    ...
  },
  controllerAs: 'vm'
})

2) access to parent scope. not remended for information

controlller:

  $scope.isDatePickerOpen = false;

  $scope.openDatePicker = function(){
    $scope.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", $scope.isDatePickerOpen);
  };

template:

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='$parent.$parent.isDatePickerOpen' ng-click='openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

3) use object. can be use, but first sulution is better

controller:

  $scope.status = {isDatePickerOpen : false};

  $scope.openDatePicker = function(){
    $scope.status.isDatePickerOpen = true;
    console.log("isDatePickerOpen?", $scope.status.isDatePickerOpen);
  };

template:

<uib-tabset type='pills'>
  <uib-tab heading='HeatMap'>
    <input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-change='changeDateTime()' ng-model='selectedDate' is-open='status.isDatePickerOpen' ng-click='openDatePicker($event)'/>
  </uib-tab>
</uib-tabset>

May be this article explain topic more detail. http://www.undefinednull./2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/

Got this working with the following:

<input id='dateToImport' type='text' uib-datepicker-popup='yyyy-MM-dd' class='form-control' ng-model='selectedDate' is-open='dateToImportIsOpen' ng-click='dateToImportIsOpen = !dateToImportIsOpen'/>

Note that dateToImportIsOpen will be written to current $scope.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论