This is probably an easy question, but I'm having a problem with this datepicker. The problem is I set the format to dd/mm/yyyy with data-date-format attribute. However, when checking my ng-model the value is the following: Wed Jul 17 2013 00:00:00 GMT+0000 (Greenwich Standard Time)
What I want is it to bind to dd/mm/yyyy format.
How can I fix this?
Here is my code:
<label for="inputDateFrom">Frá</label>
<div class="control-group input-append">
<input type="text" ng-model="booking.Booking.DateFrom" data-date-format="dd/mm/yyyy" bs-datepicker>
<button type="button" class="btn" data-toggle="datepicker"><i class="icon-calendar"></i></button>
</div>
Update 18.07.13:
According to rGil's answer I tried to use $scope.$watch. It works fine but first it gets the CORRECT date (from getBooking() service function), then it changes to the CURRENT date - which is not the date.
JavaScript code is following:
$scope.$watch('booking.Booking.DateFrom', function(v){ // using the example model from the datepicker docs
$scope.booking.Booking.DateFrom = moment(v).format();
alert(moment(v).format());
});
$scope.$watch('booking.Booking.DateTo', function(v){ // using the example model from the datepicker docs
$scope.booking.Booking.DateTo = moment(v).format();
alert(moment(v).format());
});
// Sækjum staka bókun
if(bookingID != null) {
BookingService.getBooking(bookingID).then(function(data) {
$scope.booking = data.data;
$scope.booking.Booking.DateFrom = moment($scope.booking.Booking.DateFrom);
$scope.booking.Booking.DateTo = moment($scope.booking.Booking.DateTo);
});
}
Then my HTML is the following:
<label for="inputDateFrom">Frá</label>
<div class="control-group input-append">
<input type="text" ng-model="booking.Booking.DateFrom" data-date-format="dd-mm-yyyy" bs-datepicker>
<button type="button" class="btn" data-toggle="datepicker"><i class="icon-calendar"></i></button>
</div>
<label for="inputDateTo">Til</label>
<div class="control-group input-append">
<input type="text" ng-model="booking.Booking.DateTo" data-date-format="dd-mm-yyyy" bs-datepicker>
<button type="button" class="btn" data-toggle="datepicker"><i class="icon-calendar"></i></button>
</div>
Looking over the AngularStrap source code, I found that if you set the (seemingly undocumented) attribute date-type to any value outside of "Date" (for example: String) this prevents bs-datpicker from returning the selected date as a date object and solves the issue. So in this case it would be:
<input type="text" ng-model="booking.Booking.DateFrom" data-date-format="dd/mm/yyyy" date-type="string" bs-datepicker>
Tested on AngularStrap v0.7.4 and v0.7.5
This can easily be done without a plugin. Using this post you can create a $scope variable with the correct formatting.
Example:
$scope.$watch('datepicker.date', function(v){ // using the example model from the datepicker docs
var d = new Date(v);
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1; //Months are zero based
var curr_year = d.getFullYear();
$scope.modDate = curr_date + "/" + curr_month + "/" + curr_year;
console.log($scope.modDate)
})
FORKED DEMO - open console
There are ways to do it in a more elegant way, with AngularJS. Just use the date filter Angular. Like this:
$filter('date')(date, "yy/MM/yyyy", date.getTimezoneOffset())
$filter('date') gets the angularjs filter that take in args, the date, the template and the timezone, and returns a well formatted string.
08/03/2016
Related
In an angular project, I have an bootstrap-ui datepicker which is used to provide info on the date when an invoice has been paid.
Initially, upon creating the invoice, as it has not been paid and so I should have an ng-model variable indicating null or something like that :
$scope.invoice.Payment_Date = null
The thing is, it appears that the datepicker needs to have a valid date object to work. When using everything this way, when I select a date in the datepicker to say my invoice has been paid, the datepicker indicates a correct date like Tuesday, February 15 2016, but the ng-model variable remains null.
If I initialize the variable as such :
$scope.invoice.Payment_Date = new Date();
then when changing the datepicker date, the ng-model is updated as it should.
The problem is, I may have to create/update the invoice without saying it has been paid, and doing so, I get a Payment_Date which has the value of the date said invoice has been created/updated.
Is there a way to leave this variable set to null or empty when the datepicker is left untouched and yet having it get the correct datepicker value when it's used ?
Hope someone can help !
Edit : here's the HTML code of the datepicker :
<form name="formFacture" novalidate rc-submit="modifierFacture()">
<div class="form-group">
<label>Date de paiement : </label>
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="dd MMMM yyyy" ng-model="facture.Date_Paiement" is-open="popupDatePaiement.opened" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" close-text="Fermer" clear-text="Effacer" current-text="Aujourd'hui" readonly="readonly" ng-click="openDatePaiement()" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openDatePaiement()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="container text-center">
<button type="submit" class="btn btn-primary">Enregistrer</button>
<div class="btn btn-primary" ng-click="ChangeLocation('prev', '/#factures')">Retour</div>
</div>
</form>
Here's the JS code :
$scope.facture = {};
$scope.dateOptions = {
startingDay: 1
};
$scope.popupDatePaiement = {
opened: false
};
var openDatePaiement = $scope.openDatePaiement = function() {
$scope.popupDatePaiement.opened = true;
};
$scope.modifierFacture = function(){
console.log($scope.facture);
return
}
After reviewing the code I found that :
I can get a valid date with the datepicker ( there was a slight error with the ng-model ) but if I change the date twice, the facture.Date_Paiement variable stays with the 1st choice, the 2nd choice does not get forwarded to it.
If I use the "clear" button inside the datepicker, the facture.Date_Paiement variable doesn't revert to null
I've tried adding this line :
$scope.Date_Paiement = null
inside the openDatePaiement function, but in this case, the facture.Date_Paiement staus null at all times.
Ok, after hours spent researching the whys of this question, I found an answer.
DO NOT rely on console.log(object) to tell you what is inside the object as it seems the function parsing the object to render it inside the console is bugged !
Instead, use console.log(JSON.stringify(object)) and you'll have the correct values.
My head still aches, what are we to do when such things are bugged ???
I have below code snippet in which datepicker control is there.
<input type="text" name="startDate" class="form-control input-sm" datepicker-popup="dd-MMMM-yyyy" ng-model="startDate" required />
Here, i have to disable the past dates in the datepicker control and below is what i have configured but its not working. Am I missing something here?
App.config(['datepickerConfig', 'datepickerPopupConfig', function (datepickerConfig, datepickerPopupConfig) {
datepickerConfig.startingDay = 1;
datepickerConfig.showWeeks = true;
datepickerPopupConfig.datepickerPopup = "dd-MMMM-yyyy";
datepickerPopupConfig.currentText = "Now";
datepickerPopupConfig.clearText = "Erase";
datepickerPopupConfig.closeText = "Close";
}]);
If you want to narrow the range of possible dates add min-date or max-date just as in the example.
Here's the relevant part of documentation:
max-date (Default: null) - Defines the maximum available date.
min-date (Default: null) - Defines the minimum available date.
Since angular ui-bootstrap version 1.1.0 you need to use an attribute called datepicker-options to configure a datepicker:
<input type="text" class="form-control" datepicker-options="dateOptions" datepicker-popup="dd-MMMM-yyyy" is-open="popup.opened"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
Now you only need to set the minDate property to the current date or any other date you like to be the minimum Date of the datepicker. Instead of writing the datepicker configuration in the .config block of your application, you should write it in a controller or a service:
$scope.dateOptions = {
minDate: new Date()
};
$scope.popup = {
opened: false
};
$scope.open = function() {
$scope.popup.opened = true;
};
For more information, please read the official documentation.
I have a form where I have a conditionally required datepicker element. I can not initiate this element with any value as the user has to enter it. Datepicker format is dd/mm/yyyy. Issue is that it was working fine until I added ng-required. After ng-required condition added to the element, when user clicks on calendar, calendar default date is Dec 31 1969. It's very inconvenient to the user bringing that date to current date. I tried setting default date to today in datepicker options but no luck.
<div class="form-group col-md-3 required" ng-show="decision==true">
<label class="control-label">Test Date</label>
<div class="input-group">
<input name="testDate" type="text" class="form-control" datepicker-popup="dd/MM/yyyy" ng-model="testDate" is-open="dpOpened.testDateTo"
close-text="Close" onfocus="this.blur();" datepicker-options="dateOptions" ng-required="decision==true" required/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="datepickerPopup($event, 'testDateTo')">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
</div>
--controller.js--
$scope.datepickerPopup = function($event, opened) {
$event.preventDefault();
$event.stopPropagation();
$scope.dpOpened[opened] = true;
}
$scope.dateOptions = {
showWeeks : false,
defaultDate : new Date()
};
$scope.dpOpened = {
testDateTo : false,
};
$scope.today = function() {
return new Date();
}
You have the ng-model set to testDate but I don't see where you have set that in your controller. Try setting testDate = new Date(). See this relevant pull request
I had the same issue.
You should NOT initialize the bsDatePicker field with new Date(). You must initialize with 'null' from formbuilder, even if it is a required field.
I'm new to Angular and to JS, therefore I'm sorry if my problem is quite trivial.
I'm using ui.bootstrap.datepicker to modify a date property of my foo model. My foo.date is a string like '2000-01-31'. What I want is to visualize foo.date in the form as January 31, 2000, while preserving 'foo.date' format to '2000-01-31'.
Here there is my datepiker:
<div class="input-group">
<input type="text"
class="form-control"
datepicker-popup="MMMM dd, yyyy"
ng-model="foo.date"
is-open="opened"
ng-required="true"
show-weeks = 'false'
close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="pdfc.open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
If I set datepicker-popup to "MMMM dd, yyyy", the original date format of the model is broken. I see something like this:
"2000-01-31T00:00:00.000Z"
...instead of this:
2000-01-31
I read some related solutions like this one, but the directive.directive('datepickerPopup', function (){...} is "overridden" by datepicker-popup in the form.
In this plnkr you can see my problem in action. Is there a nice way to decouple those two date formats?
Use date filter. Here is what it can do.
First inject filter service to your controller:
.controller('myCtrl',['$filter','$scope',function($filter,$scope){//..}]);
If you have other services to inject, read about dependency injection.
Second, assign new variable with date filter.
var dateView = $filter('date')($scope.foo.date,'MMMM d, yyyy');
Then you can show it:
(Controller)
$scope.foo.fDate = dateView;
(View)
{{foo.fDate}}
To observe it after change, set watch on it:
$scope.$watch(function() { return $scope.foo.date; },
function(n,o){
var dateView = $filter('date')($scope.foo.date,'MMMM d, yyyy');
$scope.foo.fDate = dateView;
});
It will listen for changes and change it.
It is better to show it in another variable. Of course you can set in watch instead of fDate, foo.date, but you may help problem with manual editing label, because variable will be changed after one letter is written.
I have tried to extend the UI datepicker with previous and next day buttons.
As you can see from the plunker I can change the model either by using the datepicker or the prev/next buttons. But when the model is changed with the prev/next buttons, the datepicker ist not updated.
http://plnkr.co/edit/k1flklFny5BoX6zdwyWJ?p=preview
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control"
datepicker-popup="{{ctrl.format}}" ng-model="ctrl.dt"
is-open="ctrl.opened" datepicker-options="ctrl.dateOptions"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="ctrl.open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
</div>
I tried several approaches already (including $scope and the demonstrated controller as syntax) but it simply does not work. Any ideas?
PS: I tried very hard to have prev button, datepicker, next button in one line, centered, the datepicker occupying just enough space it needs. If anyone has an idea how to accomplish that, any help is greatly appreciated.
I don't know why, but seems that ngModel doesn't react when Date object changed itself. But it changed if you assign to scope property new instance of Date.
Try this:
this.prevDay = function() {
this.dt = getPrevNextDate(this.dt, -1);
};
this.nextDay = function() {
this.dt = getPrevNextDate(this.dt, 1);
};
function getPrevNextDate(date, increment)
{
var newDate = new Date();
newDate.setDate(date.getDate() + increment);
return newDate;
}
And better to cache this into some variable like var self = this at top of controller function and use self variable instead of this
This way you will avoid error in this line:
$log.log('GET api/v1/person/' + this.person.id + '/entry returned: ' + data.length + ' entries')