Angular UI datepicker not updating - angularjs

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')

Related

Angular UI date picker error message in same line

In this plunk I have an Angular UI date picker with an error message that is displayed when the date is invalid. Problem is that the error message is shown below the date instead of the same line. How to fix this?
HTML
<form name="form1" ng-submit="validate(form1)" novalidate>
<p class="input-group" style="width:160px;margin-bottom:0px;">
<input type="text" class="form-control" ng-model="dtFrom"
is-open="config1.opened" uib-datepicker-popup="MM-dd-yyyy"
close-text="Close" name="dtFrom" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
<div style="background-color:red;color:white;width:150px"
ng-show="!form1.dtFrom.$valid">Invalid Date</div>
</form>
Javascript
var app = angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
app.controller('ctl', function ($scope) {
$scope.dtFrom = new Date ();
$scope.config1 = {};
$scope.config1.opened = false;
$scope.open1 = function(event){
event.preventDefault();
event.stopPropagation();
$scope.config1.opened = true;
};
});
You can add class list-inline in it.
Here is plnkr
http://plnkr.co/edit/23CxCMDRK6DBiW115K7T?p=preview
The reason you are seeing this misalignment is because you are using bootstrap classes but are not correctly applying them to all the corresponding elements. When you use an input-group as you've applied to the <p> element, you are using a specific bootstrap class that adds styling to the components, like display:table. To have a correct behavior for the whole form, you need to keep using these classes on sibling elements. Namely input-group and form-control. Using these you will notice that its better aligned to its neighbor in both position and height. Additionally its best to wrap all these components in a valid row and column classes for parent elements. I've added an updated version of your plnkr showing how these changes behave:
plnkr

Bootstrap UI Datepicker Popup not working after 2.1.4 update

I have the following code snippet that was working fine in my web application utilising the Bootstrap UI library v0.14.3:
HTML:
<div class="form-group">
<label for="dateSelection">Reporting Period:</label>
<div class="input-group input-group-sm right-align">
<input
id="dateSelection"
type="text"
class="form-control"
uib-datepicker-popup="{{ format }}"
popup-placement="bottom-right"
ng-model="date"
is-open="Calendar.opened"
datepicker-options="calendarOptions"
ng-required="true"
close-text="Close"
on-open-focus="false"
ng-change="chooseCustomDate( date )"
ng-disabled="true" />
<span class="input-group-btn">
<button
type="button"
class="btn btn-default"
ng-click="openCalendar()">
<i class="fa fa-calendar"></i>
</button>
</span>
</div>
</div>
Controller:
var yesterdayDate = moment().subtract( 1, 'days' );
$scope.selectedDate = $filter('date')( new Date( yesterdayDate ), 'yyyy-MM-dd' );
$scope.forecastVarianceErrors = [];
$scope.LBossVarianceErrors = [];
$scope.PortalDifferenceErrors = [];
$scope.date = $scope.selectedDate;
$scope.dtInstance = {};
$scope.showPortalDifferences = true;
$scope.showLBossVariances = true;
$scope.showForecastVariances = false;
$scope.format = 'EEEE, d MMMM, yyyy';
/*
* Reporting Period
*
*/
$scope.chooseCustomDate = function( date ) {
// Set the new date
$scope.selectedDate = $filter('date')( new Date( date ), 'yyyy-MM-dd' );
// Empty the variance arrays
$scope.forecastVarianceErrors = [];
$scope.LBossVarianceErrors = [];
$scope.PortalDifferenceErrors = [];
// Redraw the datatable
$scope.dtInstance.reloadData();
};
$scope.openCalendar = function() {
$scope.Calendar.opened = true;
};
$scope.Calendar = {
opened: false
};
$scope.calendarOptions = {
startingDay: 1
};
However, recently I required a feature to the Bootstrap UI's Popover element that was only available in v2.1.4 so I decided to make the transition to the latest version.
After updating, I noticed that all of my Datepicker Popups have now stopped working. I don't receive any errors, just simply the popup never seems to open. I am struggling to find information on what may have changed to see if I am now missing something, or need to alter my code in any way.
If I revert back to v0.14.3, my Datepicker Popups will start working again.
Any help appreciated.
Well it seems that I was the cause of my own demise.
Within my control, I added the ng-disabled tag to the <input> field to prevent any user from manually tampering with the date string. This seemed to be an allowed behaviour of v0.14.3, however, v2.1.4 was not so accommodating.
By changing the ng-disabled to a readonly tag, it allowed the calendar control to once again be drawn.
Also I found that v2.1.4 wants new Date(); specified for the ng-model or it fails to render the date string within the <input> field.

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

AngularJS binding datatimepicker selected value to ng-model

I have a newbie AngularJS question - I am using a datetimepicker library and I'm having a hard time getting the date selected to bind to my model... I saw some posts talking about not being able to access the datetimepicker model directly, but in my case I find that if I just manually TYPE IN a text value in my date input box, it binds! If I select a date with the chooser, I get the dreaded 'undefined' :(... help?
HTML markup:
<div class="col-md-2">
<div name="fromDateTime" class="input-group date" id="datetimepickerFrom">
<input class="form-control" type="text" name="fromDateTime" ng-model="formEntries.fromDateTime"/>
<span class="input-group-addon" data-ng-click="pickFromDateTime()"><span class="glyphicon glyphicon-calendar" id="calIconFrom"></span></span>
</div>
</div>
<div class="col-md-2">
<div name="toDateTime" class="input-group date" id="datetimepickerTo">
<input class="form-control" type="text" name="toDateTime" ng-model="formEntries.toDateTime"/>
<span class="input-group-addon" data-ng-click="pickToDateTime()"><span class="glyphicon glyphicon-calendar"></span></span>
</div>
</div>
Controller:
$scope.pickFromDateTime = function () {
$("#datetimepickerFrom").datetimepicker();
$("#datetimepickerFrom").datetimepicker().change(function() {
$(this).data("DateTimePicker").hide();
console.log($(this).data("DateTimePicker").getDate());
});
}
$scope.pickToDateTime = function () {
$("#datetimepickerTo").datetimepicker();
$("#datetimepickerTo").datetimepicker().change(function() {
$(this).data("DateTimePicker").hide();
console.log($(this).data("DateTimePicker").getDate());
});
}
$scope.getData = function() {
console.log($scope.formEntries.fromDateTime);
console.log($scope.formEntries.toDateTime);
}
Never ever ever write DOM or jQuery code in your controller. It will never work properly. You must create a directive to do this. The directive will listen to events from whatever library you're using and update your model. Here is an example of a directive that happens to work with the datepicker. This should get you on the right track.

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