Can't set datepicker date from controller in AngularJS - angularjs

I am trying to create an AngularJS datepicker on the push of a button. I am using this bootstrap-ui control. The control works (pops up on the click of a button, and I can select a date), but I can't seem to set the initial date back from the scope (so that when it is first opened, the designated date is already selected).
The error I get in the Chrome console is:
Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.
jade:
button(type="button" ng-model="date.from" btn-radio="'From'" ng-click="date.openFromPopup($event);" show-weeks="false" show-button-bar="false" datepicker-popup = "date.format" is-open = "date.fromOpened" min = "date.minDate" max = "date.today") From
Since I have a watch on $scope.date.from, I can confirm that the selected date is correct, but I can never set it from the controller. Any ideas?
AngularJS controller:
$scope.date = {};
$scope.date.format = "yyyy/MM/dd";
$scope.date.opened = false;
$scope.date.from = new Date();
$scope.date.today = new Date();
$scope.date.minDate = null;
$scope.date.fromOpened = false;
$scope.$watch('date.from', function(v) {
if(v){
alert(v);
}
});

In the example on the angular-ui page, it says to use it like this...
$scope.from = function() {
$scope.dt = new Date();
};
$scope.from();
Does that work?

Related

AngularJS and input datetimelocal default format

I have an AngularJS (1.5) application and have a HTML input with the type datetime-local. I'm trying to set the default value with Date.now() and would like it to be displayed in the format 'yyyy-MM-ddTHH:mm'. I don't want the seconds displayed. I tried setting the default value in the component and set input value:
var todayDate = Date.now();
this.sampleDate = { value: new Date(todayDate) };
In HTML, I set the ng-model set to: ng-model="$ctrl.sampleDate.value"
Resulting in date and time and seconds. I have tried adding .toLocalString() to Date.now() but that did not help. I have also tried adding a filter in the value in the HTML.
The seconds (and milliseconds) won't be shown if they are set to0.
You can achieve this by manually setting the seconds and milliseconds to 0
var todayDate = new Date();
todayDate.setSeconds(0);
todayDate.setMilliseconds(0);
Or by creating a new date without specifying the seconds and milliseconds.
var todayDate = new Date(2018, 11, 28, 14, 57)
var app = angular.module('testApp', []).controller('testController', function($scope) {
var todayDate = new Date();
todayDate.setSeconds(0)
todayDate.setMilliseconds(0)
$scope.sampleDate = {value: todayDate};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="testApp" ng-controller="testController">
<input ng-model="sampleDate.value" type="datetime-local">
</div>

Angular Bootstrap UI Datepicker update minDate

This should be simple and I believed all my code is correct, but I suppose it is not.
I have two Datepickers. Datepicker 2 should be setting it's minDate to the value of datepicker 1. This works, as I can see the min-date attr updating when I select a date on Datepicker 1, but Datepicker 2 does not re-render the disabled dates. I feel like I should be refreshing the Datepicker somehow, but unsure how.
// Datepicker Controller
app.controller('datepickerController', ['$scope', function($scope) {
// open depart date
$scope.openDepartDatepicker = function($event) {
$event.preventDefault();
$event.stopPropagation();
// open depart datepicker
$scope.departDatepickerOpen = true;
}
// open return date
$scope.openReturnDatepicker = function($event) {
$event.preventDefault();
$event.stopPropagation();
// open return datepicker
$scope.returnDatepickerOpen = true;
}
$scope.$watch('search.searchparams.journeys[0].departuredate',function(value){
$scope.returnMinDate = value;
});
// minDate set intiitally
$scope.departMinDate = new Date();
$scope.returnMinDate = new Date();
// date options
$scope.departDateOptions = {};
$scope.returnDateOptions = {};
// date format
$scope.dateFormat = 'EEE dd/MM/yyyy';
}]);
And here is the actual input
<input id="returnDate" placeholder="Returning" type="text" class="form-control" data-ng-model="search.searchparams.journeys[1].departuredate" datepicker-popup="{{dateFormat}}" data-ng-focus="openReturnDatepicker($event)" show-button-bar="false" min-date="{{returnMinDate}}" is-open="returnDatepickerOpen" datepicker-options="returnDateOptions" readonly=""/>
Nothing I have tried has made a difference. The new minDate is updating, but just not being applied to the Datepicker. I can actually see the updated min-date attribute in my inspector, so all values are updating as expected.
Any help appreciated
The issue is so simple and so silly.
min-date="{{returnMinDate}}"
needs to be
min-date="returnMinDate"
It smacked me right in the face this morning.

How I restrict the user to only enter Date Field in angular bootstrap datepicker

I am new in angular and I stuck at point where I am unable to restrict the user to enter valid date manually. It sets the date as undefined for empty, characters as well as invalid date entered by the user. The date format I have mentioned is MM-dd-yyyy. Even if I enter 85/34/2102 it assumes this as a date and takes some junk value instead of validating and throwing an error.
my code of angular date-picker in html
<input type="text" class="form-control" datepicker-popup="{{clCtrl.format}}"
ng-model="clCtrl.QualityExpirationDate" is-open="clCtrl.openedQualityDate"
min-date="clCtrl.minDate" datepicker-options="clCtrl.dateOptions"
ng-required="true" close-on-date-selection="true" show-button-bar="false" />
and code in angular controller side
self.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
self.formats = ['MM-dd-yyyy', 'MM/dd/yyyy', 'MM.dd.yyyy', 'shortDate'];
self.format = self.formats[0];
self.openQualityDate = function ($event) {
$event.preventDefault();
$event.stopPropagation();
self.openedQualityDate = true;
};
self.toggleMin = function () {
self.minDate = self.minDate ? null : new Date();
};
self.toggleMin();
self.clear = function () {
self.QualityExpirationDate = null;
};
Add a 'readonly' attribute to the input field:
<input type="text" readonly class="form-control" datepicker-popup="{{clCtrl.format}}" ng-model="clCtrl.QualityExpirationDate" is-open="clCtrl.openedQualityDate" min-date="clCtrl.minDate" datepicker-options="clCtrl.dateOptions" ng-required="true" close-on-date-selection="true" show-button-bar="false" />
If you want to allow user input but restrict to valid dates you could add this to your controller:
$scope.$watch('dt', function(val) {
$scope.isValidDate = isNaN(new Date(val).getTime());
});
then use the 'isValidDate' scope property to show/hide a message and/or disable submission, or whatever you want to do.
Of course it would be better to abstract this validation into a directive so it could easily be reused on all your date fields.

AngularJS data binding not working with ui-date component

I'm using the ui-date component as a dropdown datepicker in an AngularJS project. The problem I'm having is that the data binding between the model and the datepicker is only one-way, not two-way as I expect it to be.
My HTML has a Prev and Next button to allow the user to adjust the date backwards and fowards one day at a time. Or they can click in the date box itself to show the dropdown datepicker and specify any date they want.
Plunker here.
HTML:
ThisDate: {{ ThisDate }}
<p>
<button ng-click="PrevDay()">< Prev</button>
<button ng-click="NextDay()">Next ></button>
<p>
Set Date: <input ui-date ng-model="ThisDate" id="ThisDate">
Javascript:
var app = angular.module('app', ['ui.date']);
app.controller('MyController', function($scope) {
$scope.ThisDate = new Date();
$scope.PrevDay = function() {
$scope.ThisDate = DateOffset($scope.ThisDate, -1);
};
$scope.NextDay = function() {
$scope.ThisDate = DateOffset($scope.ThisDate, 1);
};
function DateOffset(ThisDate, NumDays) {
var d = ThisDate;
d.setDate(d.getDate() + NumDays);
return d
}
});
Problem:
If you change the date using the dropdown datepicker, the date box will change and {{ ThisDate }} will update properly. But if you click the Prev or Next buttons, only the bound {{ ThisDate }} will change... not the date box which is bound to "ThisDate" in the model.
Steps to Reproduce:
Run the Plunker. Notice that if you click in the date box, you can change the date from the dropdown and the date box will change accordingly AND the text area at the top which is bound to ThisDate will also change. Now click the Next or Prev button. Notice that ONLY the bound ThisDate text will change, NOT the date box. The date box should also change since it is bound to ThisDate.
Any ideas on why the ui-date datepicker isn't registering the changes in the model to ThisDate?
Plunker here.
It's not seeing the date object change. If you assign a new date object it works:
function DateOffset(ThisDate, NumDays) {
var d = new Date();
d.setTime(ThisDate.getTime() + (NumDays * 1000 * 60 * 60 * 24));
return d
}

Angular strap binding datePicker not working with start and end date?

I use angular strap datePicker
<input type="text" name="dateFrom" ng-model="dateFrom" bs-datepicker
data-end-date="{{endDate}}" data-start-date="{{startDate}}" />
How ever when change endDate or startDate from code it does update in the DOM but the date picker remains unaware of this change, is there some kind of update I need to trigger?
The change is done via a ng-click with function on the same scope, that then sets a new value for endDate and startDate.
Like so (CoffeeScript):
$scope.setDateRange = (dateRange) ->
if dateRange is "past"
$scope.endDate = "-1d"
$scope.startDate = ""
if dateRange is "now"
$scope.endDate = ""
$scope.startDate = ""
if dateRange is "future"
$scope.endDate = ""
$scope.startDate = "+1d"
Edit:
Here is the solution:
On the controller constructor I store the date from and to controls:
dateFromCtrl = $element.find 'input[name="dateFrom"]'
dateToCtrl = $element.find 'input[name="dateTo"]'
Then when setDateRangeis called I made few helper methods to call the datepicker setEndDate and setStartDate methods:
setEndDate = (date) ->
dateFromCtrl.datepicker 'setEndDate', date
dateToCtrl.datepicker 'setEndDate', date
setStartDate = (date) ->
dateFromCtrl.datepicker 'setStartDate', date
dateToCtrl.datepicker 'setStartDate', date
setDateRange = (dateRange) ->
if dateRange is "past"
setEndDate "-1d"
setStartDate ""
if dateRange is "now"
setEndDate ""
setStartDate ""
if dateRange is "future"
setEndDate ""
setStartDate "+1d"
Try using the setStartDate() and setEndDate() calls:
http://bootstrap-datepicker.readthedocs.org/en/latest/methods.html#setstartdate
Or you might look at the datepicker that is now provided by the Angular folks, so it has especially nice integration within Angular: http://angular-ui.github.io/bootstrap/

Resources