Angular + Bootstrap + Datepicker = not working - angularjs

I'm using AngularJs 1.6 with angular-ui-bootstrap 2.5.0 (bootstrap-ui-tpl.min.js)
On loading the page, the model value (dateOfBirth) is not getting pre-populated in the date picker textbox. It seems, many have reported similar issues for different versions of angular/bootstrap but nothing seems to work.
HTML:
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dateOfBirth" datepicker-options="dateOptions"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openDobDatePicker()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
Javascript:
$scope.format = 'dd/MM/yyyy'
$scope.dateOfBirth = '05/12/2004'
$scope.dateOptions = {
maxDate: new Date(),
startingDay: 1,
showWeeks: false
}
Edit:
It seems angular provides uibDateParser to parse String to Date object. However, the following fails silently:
$scope.dateOfBirth = $uibDateParser.parse('05/12/2004', 'dd/MM/yyyy')

It's not getting populated because it's a string and not a valid Date. So, if you change it like,
$scope.dateOfBirth = new Date("05/12/2004");
..it would work! Also, note that new Date(..) will come with local timezone so in case you want to change timezone or anything regarding manipulation of dates, momentjs is a great library to handle those.
EDIT: If your format is dd/MM/yyyy, you can maybe do something like this to convert in valid date:
var parts ='05/12/2004'.split('/');
$scope.dateOfBirth = new Date(parts[2],parts[1]-1,parts[0]));

Related

Angular Js DatePicker not showing anything in the input but when you click the calendar popup is correct

Using Angular 1.5.2, UI-Bootstrap 1.2.5, Bootstrap css 3.3.6
So my json data comes in with the date as a string (I can't help or change that).
"start": "2014-06-12"
I use moment to convert to a date.
//part of a larger object returned from an ajax call
$scope.item=data[0];
$scope.item.startM=moment($scope.item.start);
$scope.item.endM=moment($scope.item.end);
In the {{item}} I see visually on screen
"start":"2014-06-12"
"startM":"2014-06-12T04:00:00.000Z"
In the console I can display the
startM:o
_d:Thu Jun 12 2014 00:00:00 GMT-0400 (Eastern Daylight Time)
_f:"YYYY-MM-DD"
_i:"2014-06-12"
_isAMomentObject:true
_isUTC:false
_isValid:true
_locale:A
The input field is blank????
When I click on the calendar to see the date it's selected the correct date and will display properly in the input field if I select it.
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="item.end" is-open="popup2.opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" alt-input-formats="altInputFormats" /><span class="input-group-btn"><button type="button" class="btn btn-default" ng-click="open2()"><i class="glyphicon glyphicon-calendar"></i></button> </span>
$scope.dateOptions = {
formatYear: 'yy',
maxDate: new Date(2020, 5, 22),
minDate: new Date(),
startingDay: 1
};
$scope.formats = ['yyyy-MM-dd','dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
$scope.format = $scope.formats[0];
I know I'm not providing much detail but I'm struggling to understand why the calendar knows the correct date but the input box doesn't...
You have minDate: new Date(). That is today, but then you are attempting to set the date to June 12, 2014 which is less than the minimum date you have specified. That's probably why it's blank.
The problem is that the uib-datepicker-popup appears to require a date generated by uibDateParser. You need to do something like this instead of using moment.js:
$scope.item.start = uibDateParser.parse($scope.item.start, "yyyy-MM-dd")
I can't tell you why it shows correctly in the popup but not in the text box, but it is what it is at this point I'm sure.

Bootstrap-ui datepicker : how of have an empty ng-model?

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 ???

ui.bootstrap.datepicker: decoupling "displayed date format" from "ng-model date format"

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.

angularjs bootstrap datepicker is not updating the model

I'm trying to use the bootstrap datepicker using angular ui inside a my own angular controller.
http://angular-ui.github.io/bootstrap/
With all the libraries updated to the latest version I have a strange bevavior: the intial value is read from the controller, the datepicker is shown, I select the date and the textbox is updated but after this the value in the controller changes to undefined.
I'm missing something? What can cause this behavior?
thanks,
Luca morelli
this is the content of the view, two dates to define a range
<input type="text" class="form-control" datepicker-popup="{{dtFormat}}" ng-model="dtFine" is-open="dtFineOpened"
ng-required="true" close-text="Chiudi" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="openDtFine($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
this is the typescript code that handles the involved members
$scope.dtInizio = moment().format("DD/MM/YYYY");
$scope.dtFine = moment().format("DD/MM/YYYY");
$scope.dtInizioOpened = false;
$scope.dtFormat = "dd/MM/yyyy";
$scope.openDtInizio = ($event) => {
$event.preventDefault();
$event.stopPropagation();
$scope.dtInizioOpened = true;
}
$scope.openDtFine = ($event) => {
$event.preventDefault();
$event.stopPropagation();
$scope.dtFineOpened = true;
}
Using batarang I see that choosing the first date, when the popup is closed the model isn't update, when I go to open the second popup the modul is updated showing DtInizio as undefined
Debugging more I found this: I set a breakpoint to evalutate the status and I see that the value is
Tue Sep 16 2014 00:00:00 GMT+0200 (W. Eu...
and this is correct, but below I find
proto: Invalid Date
What does it means?

Datepicker not binding formatted value

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

Resources