I am trying to use uib-datepicker-popup but am running into an issue that once the calendar opens and I choose a date, I cannot reopen the calendar without refreshing the screen. I step through the function call on the ng-click and it sets the is-open flag to true but the popup doesn't show after the first time.
This is the HTML:
<span class="input-group" >
<input type="text" class="input-sm " uib-datepicker-popup="{{format}}"
ng-model="requestDate" is-open="opened1"
datepicker-options="dateOptions" close-text="Close" />
<span class=" input-sm" >
<button type="button" class="btn btn-default" ng-click="open1()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</span>
And the controller:
$scope.format = 'yyyy-MM-dd';
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.open1 = function() {
$scope.opened1 = true;
};
I don't understand why it won't open...any thoughts?
thank you all for your help. I did a lot more searching after I posted the question and came across something that fixed the issue...not sure why it made it work but it does.
I changed the open1 function to the following...I got it to work first for one and then extended to so I can use it for all...
$rootScope.openCalendar = function($event,whch) {
$event.preventDefault(); <- I had tried this before
$event.stopPropagation(); <- I had tried this before
$rootScope.datepicker = {[whch]: true};
};
In my HTML I changed both lines: (look for the <--)
<input type="text" class="input-sm " uib-datepicker-popup="{{format}}"
ng-model="requestDate" is-open="datepicker.opened1" <--
datepicker-options="dateOptions" close-text="Close" />
<span class=" input-sm" >
<button type="button" class="btn btn-default" ng-click="openCalendar($even, 'opened1')"> <--
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
This works really well from what I can see so far. I guess I could shorten it a bit by using Lex's suggestion too....
Thanks again!
My code is too large to post here, so I just post the relevant parts.
I have a fairly large app and now I want to add a datapicker. I copied the code from the Angular UI bootstrap site.
In my controller I initialize
$scope.popup1 ={'opened': false}
$scope.dt = new Date();
and declare
$scope.open1 = function()
{
$scope.popup1.opened=true;
}
and, in my view I have
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt"
is-open="popup1.opened" min-date="minDate" max-date="maxDate"
datepicker-options="dateOptions" date-disabled="disabled(date, mode)"
ng-required="true" close-text="Close"
alt-input-formats="altInputFormats" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1()">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
when I click the button, the function is called and $scope.popup1.opened is set to true.
However, the datepicker does not pop up.
Am I missing something obvious? Do I need to enable the datepicker or something?
I had a similar problem once that a calendar popup didn't show up. It turned out to just be a CSS problem, it was hidden behind another object. See if you can find the popup anywhere in the DOM and then check what it's z-index CSS property is set to.
How can I prevent the datepicker popup from opening at the same time when I click on only 1 input?
Plunkr
<form>
<div class="form-group">
<label for="fromDate">From:</label>
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" show-weeks="false" ng-click="open($event)" name="fromDate" id="fromDate" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
<div class="form-group">
<label for="toDate">To:</label>
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="toDate" is-open="opened2" datepicker-options="dateOptions" ng-required="true" close-text="Close" show-weeks="false" ng-click="open($event)" name="toDate" id="toDate" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
</form>
I looked at your plunkr. In your script.js file you have the following
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
$scope.opened2 = true;
};
$scope.opened = true; and $scope.opened2=true; are both being set. This is forcing both of them to open. You are calling this function when either of the calendar buttons is clicked
ng-click="open($event)"
is-open will force the calendar to show when the variable is set somewhere else in code as well. Remember it is 2-way binding
As for your solution. A simple way I can think to fix it is to pass another variable into your open method telling it which button was clicked so
$scope.open = function($event, calId) {
$event.preventDefault();
$event.stopPropagation();
if(calId===1) $scope.opened = true;
if(calId===2) $scope.opened2 = true;
};
Then in your html for the buttons change to the following passing in a 1,2,3 etc.. for whichever datepicker on the page you want to display.
ng-click="open($event,1)"
I believe that I have followed the advice of others such as the good answer to "How to have at least two datepickers of ui-bootstrap on a single page?" and successfully incorporated two of them on my page. While I can endlessly edit the text version of each date, I can only have the pop-up calendar for each date occur only once. Extra clicks on the calendar icons seem to do nothing.
What have I done wrong? I don't see that this is expected behavior or what option I've left off or accidentally included.
relevant html is:
<div>
<input type="text" datepicker-popup="{{format}}" ng-model="startDate" is-open="openedStart" datepicker-options="dateOptions" close-text="Close" />
<button type="button" ng-click="open($event,'openedStart')"></button>
<input type="text" datepicker-popup="{{format}}" ng-model="endDate" is-open="openedEnd" datepicker-options="dateOptions" close-text="Close" />
<button type="button" ng-click="open($event,'openedEnd')"></button>
relevant js code is:
$scope.openedStart = false;
$scope.openedEnd = false;
$scope.format = "dd.MM.yyyy";
$scope.open = function($event,opened) {
$event.preventDefault();
$event.stopPropagation();
$scope[opened] = true;
};
Try creating an object. Something like this:
html:
<input type="text" datepicker-popup="{{format}}" ng-model="startDate" is-open="opened.openedStart" datepicker-options="dateOptions" close-text="Close" />
<button type="button" ng-click="open($event,'openedStart')"></button>
<input type="text" datepicker-popup="{{format}}" ng-model="endDate" is-open="opened.openedEnd" datepicker-options="dateOptions" close-text="Close" />
<button type="button" ng-click="open($event,'openedEnd')"></button>
Your controller:
$scope.opened = {};
$scope.opened.openedStart = false;
$scope.opened.openedEnd = false;
$scope.open = function($event,datepicker) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened[datepicker] = true;
};
I want to have several datepickers on a page. But with the default solution from UI-Bootstrap it is not possible, no one of datepickers may be opened. The conflict with each other. Here is my code:
<div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
I just did a copy/paste of the datepicker code from the site http://angular-ui.github.io/bootstrap/#/datepicker. They conflict with each other. When I click <input> field to open a datepicker no one can be opened properly, both are opened for a second and immediately disappear.
How may I have several datepickers on a single page?
Rather than using a different function you can use a different is-open attribute and then pass the attribute in through the ng-click function. You still need different models:
<div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt1" is-open="opened1" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open($event,'opened1')"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt2" is-open="opened2" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open($event,'opened2')"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
And inside controller:
$scope.open = function($event,opened) {
$event.preventDefault();
$event.stopPropagation();
$scope[opened] = true;
};
I'm still learning Angular and UI-Bootstrap, so take that into account when reading my answer. I did something similar to BlueMonk, but in a flexible way that keeps my controller code from having to know about the instances of the datepicker on the page.
I put all of the datepicker code in my controller into a single namespace:
$scope.datePicker = (function () {
var method = {};
method.instances = [];
method.open = function ($event, instance) {
$event.preventDefault();
$event.stopPropagation();
method.instances[instance] = true;
};
method.options = {
'show-weeks': false,
startingDay: 0
};
var formats = ['MM/dd/yyyy', 'dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
method.format = formats[0];
return method;
}());
And then used the following markup:
<p class="input-group">
<input type="text" class="form-control" ng-model="editableEmployee.dateHired" datepicker-popup="{{datePicker.format}}" datepicker-options="datePicker.options" is-open="datePicker.instances['dateHired']" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="datePicker.open($event, 'dateHired')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
<p class="input-group">
<input type="text" class="form-control" ng-model="editableEmployee.dateFired" datepicker-popup="{{datePicker.format}}" datepicker-options="datePicker.options" is-open="datePicker.instances['dateFired']" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="datePicker.open($event, 'dateFired')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
This worked like a charm for me.
This should work (different models, open flag, and functions):
<div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt1" is-open="opened1" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open1()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt2" is-open="opened2" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open2()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
And inside controller:
$scope.open1 = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened1 = true;
};
$scope.open2 = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened2 = true;
};
Here is what worked for me:
$id is scope id, provided by angular.
ctrl.opened = {};
ctrl.openDatatimePicker = function ($event, id) {
$event.preventDefault();
$event.stopPropagation();
ctrl.opened[id] = true;
}
<input type="text"
class="form-control"
uib-datepicker-popup="{{vm.datepickerFormat}}"
ng-model="x.FraDato"
is-open="vm.opened[$id]"
datepicker-options="vm.datepickerOptions"
ng-required="true"
ng-click="vm.openDatatimePicker($event,$id)"/>
No Additional changes are necessary. As long as you wrap each date input in it's own controller div the scope will reside with that input
Example:
<div ng-controller="DatepickerDemoCtrl">
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open($event)"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
</div>
<div ng-controller="DatepickerDemoCtrl">
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open($event)"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
</div>
though its an old question but answring for someone who fall in to same problem as i did.
i assigned the datepicker onfocus to that element and it workd great.
Sample code.
$(document).on('focus','.datepicker',function(){
$(this).datepicker();
});
Can open multi datepickers of ui-bootstrap on a single page
JS
$scope.open = {};
$scope.openCalendar = function (e, date) {
e.preventDefault();
e.stopPropagation();
if ($scope.open[date] === true) {
$scope.open = {};
} else {
$scope.open = {};
$scope.open[date] = true;
}
};
HTML
<input type="text" id="created1" name="created1" datetime-picker="" datepicker-options="dateOptions" timepicker-options="timeOptions" ng-click="openCalendar($event, 'created1')" placeholder="0000/00/00 00:00" is-open="open.created1" autocomplete="off" class="form-control" ng-model="vm.condition.created1">
<input type="text" id="created2" name="created2" datetime-picker="" datepicker-options="dateOptions" timepicker-options="timeOptions" ng-click="openCalendar($event, 'created2')" placeholder="0000/00/00 00:00" is-open="open.created2" autocomplete="off" class="form-control" ng-model="vm.condition.created2">