Angular daterangepicker - min date on "FROM" - angularjs

i need to set "from" and "to" date. I want on "from" set only from tomorow or any date in future, not in past. And after select start date, then enable "to" picker and set end date, but with min day range. And show day range in dom.
I try github solution from official page, but everything is from bootstrap daterange not for angular daterange. Thnx
here is html code
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<p class="input-group">
<input type="text"
class="form-control"
datetime-picker="yyyy-MM-dd"
ng-model="ctrl.picker4.date"
is-open="ctrl.picker4.open"
enable-time="false"
datepicker-options="ctrl.picker4.datepickerOptions"
myformat
/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="ctrl.openCalendar($event, 'picker4')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<div class="col-lg-5 col-md-5 col-sm-5 col-xs-12 form-group">
<label class="col-lg-2 col-xs-2 control-label" style="color: #fff">To</label>
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<p class="input-group">
<input type="text"
class="form-control"
datetime-picker="yyyy-MM-dd"
ng-model="ctrl.picker5.date"
is-open="ctrl.picker5.open"
enable-time="false"
datepicker-options="ctrl.picker5.datepickerOptions"
myformat
/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="ctrl.openCalendar($event, 'picker5')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
and here is controller
//date picker
var that = this;
// date picker
// min date picker
this.picker4 = {
date: new Date(),
datepickerOptions: {
showWeeks: true,
startingDay: 1,
maxDate: null
}
};
// max date picker
this.picker5 = {
date: new Date(),
datepickerOptions: {
showWeeks: true,
startingDay: 1,
minDate: null
}
};
/*
// set date for max picker, 10 days in future
this.picker5.date.setDate(this.picker5.date.getDate() + 10);
*/
// when closed picker
this.picker13 = {
date: new Date(),
closed: function (args) {
that.closedArgs = args;
}
};
this.openCalendar = function (e, picker) {
that[picker].open = true;
};
// watch min and max dates to calculate difference
var unwatchMinMaxValues = $scope.$watch(function () {
return [that.picker4, that.picker5, that.picker10, that.picker11];
}, function () {
// min max dates
that.picker4.datepickerOptions.maxDate = that.picker5.date;
that.picker5.datepickerOptions.minDate = that.picker4.date;
if (that.picker4.date && that.picker5.date) {
var diff = that.picker4.date - that.picker5.date;
that.dayRange = Math.round(Math.abs(diff / (1000 * 60 * 60 * 24)))
} else {
that.dayRange = 'n/a';
}
}, true);
// destroy watcher
$scope.$on('$destroy', function () {
unwatchMinMaxValues();
});

if you are using date ranges better to use daterangepicker (http://www.daterangepicker.com/). This will avoid hassles to write validation code for start date and end date. If you select Start date you will be able to select End Date after the Start Date only. no need to write validation code.

here is simply solution. We need to delete this from controller
that.picker4.datepickerOptions.maxDate = that.picker5.date;
and everything work. Now i dont need enable end date because this is working solution. But from code in my first question, i need to show daterange. I make code but i think, because i change date format, dayRange can not calculate.
if (that.picker4.date && that.picker5.date) {
var diff = that.picker4.date - that.picker5.date;
that.dayRange = Math.round(Math.abs(diff / (1000 * 60 * 60 * 24)))
} else {
that.dayRange = 'n/a';
}
Please take a look on code. Thnx

i have using the directive for date picker for start date minimum minDate:new Date().getDate+0, and maximum maxDate:new Date().getDate+30 ihave using bootstrap-datetimepicker
module.directive('examdatepicker1', function() {
return function(scope, element, attrs) {
var currentYear=new Date().getFullYear();
var finalYear=parseInt(new Date().getFullYear())+1;
$(element).datepicker({
dateFormat: 'yy/mm/dd',
changeYear: true,
changeMonth: true,
yearRange: currentYear+":"+finalYear,
minDate:new Date().getDate+0,
//maxDate:new Date().getDate+30,
onClose: function(date){
//var datearray = date.split("/");
//var newdate = datearray[1] + '/' + datearray[0] + '/' + datearray[2];
var selectedDate = new Date(date);
var msecsInADay = 86400000;
var minimum = new Date(selectedDate.getTime());
//var maximum = new Date(selectedDate.getTime() + (30*msecsInADay));
$("#end_exam_date").datepicker( "option", "minDate", minimum );
}
});
return false;
}
});
and for second datepicker
module.directive('examdatepicker2', function() {
return function(scope, element, attrs) {
var currentYear=new Date().getFullYear();
var finalYear=parseInt(new Date().getFullYear())+1;
$(element).datepicker({
dateFormat: 'yy/mm/dd',
changeYear: true,
changeMonth: true,
yearRange: currentYear+":"+finalYear
});
return false;
}
});
In Html
<input class="form-control bg-color-white" id="end_exam_date" name='end_exam_date' ng-model="end_exam_date" class="form-control" examdatepicker1 readonly required>

Related

Date issue uib-datepicker and $filter Angular JS

I'm dealing with an issue with dates format:
in my formular I'm using uib-datepicker-popup to get the calendar and in the controller I need to format this date so I'm using a $filter('date'),
so here is the input field:
<div class="input-group">
<input id="fechasolicitudc" type="text" class="form-control"
ng-class="(form.fechasolicitudc.$invalid) && (submitted) ? 'error': '' "
ng-style="(form.fechasolicitudc.$invalid) && (submitted) && {'background-color':'pink'}"
name="fechasolicitudc" uib-datepicker-popup="dd/MM/yyyy"
ng-model="vm.peticion.contacto.fechaSol"
is-open="vm.datePickerOpenStatus.fechasolicitudc"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default"
ng-click="vm.openCalendar('fechasolicitudc')">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
and in my controller:
if (vm.peticion.contacto.fechaSol != null) {
var d = $filter('date')(vm.peticion.contacto.fechaSol, 'yyyy-MM-dd');
vm.peticion.contacto.fechaSol = d;
}
what happenes is that the date is updated in the DB but the field becomes erased.
When I try give the input type="date" the field is not erased but the calendar popup does not work.
In your markup:
//...
uib-datepicker-popup="{{dateFormat}}" ng-model="vd"
datepicker-options="vdOptions"
// ...
In your controller:
$scope.dateFormat = 'dd MMM yyyy'; // or your custom date
// and if you want to have your date set as today
$scope.vd = new Date();
$scope.vdOptions = {
formatYear: 'yy',
formatMonth: 'MM',
maxDate: new Date(),
minDate: minDate,
startingDay: 1,
showWeeks: false,
yearRows: 2,
yearColumns: 2
};
vd = valueDate
I do not see the point of using $filter in this case.

Date picker validation in angularJS not working

I am trying to implement validations for my date time picker. I have a 'From' date picker and a 'To' datepicker in an Angular partial view. I want the 'From' date picker to display error message if a past date is selected and the 'To' date picker should display error message if the selected date is before the 'From' date. The error messages are supposed to appear on selection of the date.
My HTML is :
<div>
<form id="edit-profile" novalidate name="editReservationForm" autocomplete="off" class="form-horizontal">
<fieldset>
<div class="control-group">
<label class="control-label" for="reservation.reservedFrom">Reserved From<sup>*</sup></label>
<div class="controls input-group date" data-provide="datepicker">
<input type="text" class="span4" style="width:150px" name="reservedFrom" placeholder="Reserved From" ng-model="reservation.reservedFrom"
validator="required" required-error-message="Date is required" valid-method="watch" id="startDate" />
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
</div> <!-- /controls -->
</div> <!-- /control-group -->
<div class="control-group">
<label class="control-label" for="reservation.reservedTill">Reserved Till<sup>*</sup></label>
<div class="controls input-group date" data-provide="datepicker">
<input type="text" style="width:150px" class="span4" name="reservedTill" placeholder="Reserved Till" ng-model="reservation.reservedTill"
validator="required" required-error-message="Date is required" valid-method="checkErr" id="endDate" ng-change='checkErr()' />
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
<span>{{errMessage}}</span>
</div> <!-- /controls -->
</div> <!-- /control-group -->
</fieldset>
</form>
</div>
Controller :
myApp.controller('editReservationController', ['$scope', '$filter', 'reservationResolved', 'pocResolved', 'accountResolved', 'reservationServices', '$location', '$state',
function ($scope, $filter, reservationResolved, pocResolved, accountResolved, reservationServices, $location, $state) {
$scope.reservation = new Object();
$scope.accounts = accountResolved.data;
$scope.pocs = pocResolved.data;
$scope.reservation.employee = reservationResolved.data;
$scope.updateReservation = function () {
if ($scope.editReservationForm.$valid) {
//TODO: fix it properly
$scope.reservation.reservedTill = '';
$scope.reservation.reservedFrom = '';
$scope.reservation.reservedFrom = $('#startDate').val();
$scope.reservation.reservedTill = $('#endDate').val();
reservationServices.updateReservation($scope.reservation).then(function (result) {
$scope.data = result.data;
if (!result.data.error) {
$state.transitionTo('employeeTalentPool', {
id: $state.params.id
});
}
});
}
};
$scope.cancel = function () {
$location.path("/reservations");
};
$scope.checkErr = function () {
var startDate = new Date($scope.reservation.reservedFrom),
endDate = new date($scope.reservation.reservedTill);
$scope.errMessage = '';
if (startDate < new Date()) {
$scope.errMessage = 'Start Date should be greater than or equal today';
return false;
}
if (new Date(endDate) < new Date()) {
$scope.errMessage = 'End Date should be greater than or equal today';
return false;
}
if (endDate < startDate) {
$scope.errorMsg = "End must be after start";
return false;
}
return true;
};
}]);
I am totally new to Angular and I'm trying to understand it by doing projects. Can anyone have a check and provide a solution?
Thanks in advance...
A different approach without displaying any error message and satisfying selection criteria as mentioned in problem statement
Here is the plunker of working solution bit slightly different from your implementation,I've used bootstrap datepicker for this example which is almost similar to datetimepicker. Hope this will give you an understanding.
In the controller we can control when and what from and to dates should be disabled on their corresponding selection.Using minDate provided by datepicker we can change the min date of To date field to From date's.
By doing this we can eliminate the display of error message and which will also satisfy your selection criteria of From & To dates.
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('DatepickerPopupDemoCtrl', function($scope) {
$scope.datePicker = {};
$scope.start = new Date();
$scope.end = new Date();
$scope.datePicker.minStartDate = new Date();
// $scope.datePicker.maxStartDate = $scope.end;
$scope.datePicker.minEndDate = $scope.start;
// $scope.datePicker.maxEndDate = $scope.end; //fixed date same as $scope.maxStartDate init value
// watcher to watch the "From" date and set the min date for 'To' datepicker
$scope.$watch('start', function(v) {
$scope.datePicker.minEndDate = v;
$scope.dateOptions2.minDate = v;
});
$scope.dateOptions1 = {
//dateDisabled: disabled,
formatYear: 'yyyy',
// maxDate: $scope.datePicker.maxStartDate,
minDate: $scope.datePicker.minStartDate,
startingDay: 1
};
$scope.dateOptions2 = {
//dateDisabled: disabled,
formatYear: 'yyyy',
// maxDate: $scope.datePicker.maxEndDate,
minDate: $scope.datePicker.minEndDate,
startingDay: 1
};
// Disable weekend selection
function disabled(data) {
var date = data.date,
mode = data.mode;
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
}
$scope.open1 = function() {
$scope.popup1.opened = true;
};
$scope.open2 = function() {
$scope.popup2.opened = true;
};
$scope.formats = ['dd.MM.yyyy'];
$scope.format = $scope.formats[0];
$scope.altInputFormats = ['M!/d!/yyyy'];
$scope.popup1 = {
opened: false
};
$scope.popup2 = {
opened: false
};
});
In your HTML you can display like below
<div ng-controller="DatepickerPopupDemoCtrl">
<h5>From Date</h5>
<p class="input-group">
<input type="text"
class="form-control"
uib-datepicker-popup="{{format}}"
ng-model="start"
is-open="popup1.opened"
datepicker-options="dateOptions1"
close-text="Close"
readonly="true" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
<hr>
<h5>To Date</h5>
<p class="input-group">
<input type="text"
class="form-control"
uib-datepicker-popup="{{format}}"
ng-model="end"
is-open="popup2.opened"
datepicker-options="dateOptions2"
close-text="Close"
readonly="true"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open2()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
</div>

AngularUI: range datepicker don't block dates

Can anybody help?
I wanted in my start-datepicker blocked dates after end-date and blocked dates in end-datepicker before start-date.
I used angularui datepickers.
I tried to do this using this code:
$scope.start = new Date();
$scope.end = new Date($scope.start.getTime() + 7 * 24 * 60 * 60 * 1000);
$scope.minStartDate = 0; //fixed date
$scope.maxStartDate = $scope.end; //init value
$scope.minEndDate = $scope.start; //init value
$scope.maxEndDate = $scope.end; //fixed date same as $scope.maxStartDate init value
$scope.$watch('start', function(v){
$scope.minEndDate = v;
});
$scope.$watch('end', function(v){
$scope.maxStartDate = v;
});
And here's plunker:
http://plnkr.co/edit/tTBcSZE08VYCpitdhCRA?p=preview
I have updated your plunker with the necessary changes, basically you were setting minDate and maxDate incorrectly.You have declared date options but there is no such object in your controller, so I've added two date-options object for the calendars respectively. Here is the working code.
Changes in your JS are as below
$scope.datePicker ={};
$scope.start = new Date();
$scope.end = new Date($scope.start.getTime() + 7 * 24 * 60 * 60 * 1000);
$scope.datePicker.minStartDate = 0; //fixed date
$scope.datePicker.maxStartDate = $scope.end; //init value
$scope.datePicker.minEndDate = $scope.start; //init value
$scope.datePicker.maxEndDate = $scope.end; //fixed date same as $scope.maxStartDate init value
$scope.$watch('start', function(v) {
$scope.datePicker.minEndDate = v;
$scope.dateOptions2.minDate = v; //chabge the same in date options object to reflect in UI
});
$scope.$watch('end', function(v) {
$scope.datePicker.maxStartDate = v;
$scope.dateOptions1.maxDate = v;
});
//create two separate objects for date options where you can set ,in and max date..
$scope.dateOptions1 = {
//dateDisabled: disabled,
formatYear: 'yyyy',
maxDate: $scope.datePicker.maxStartDate,
minDate: $scope.datePicker.minStartDate,
startingDay: 1
};
$scope.dateOptions2 = {
//dateDisabled: disabled,
formatYear: 'yyyy',
maxDate: $scope.datePicker.maxEndDate,
minDate: $scope.datePicker.minEndDate,
startingDay: 1
};
Changes in your HTML as below
<div ng-controller="DatepickerPopupDemoCtrl">
<p class="input-group">
<input type="text"
class="form-control"
uib-datepicker-popup="{{format}}"
ng-model="start"
is-open="popup1.opened"
datepicker-options="dateOptions1"
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>
</p>
<hr>
<p class="input-group">
<input type="text"
class="form-control"
uib-datepicker-popup="{{format}}"
ng-model="end"
is-open="popup2.opened"
datepicker-options="dateOptions2"
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>
</p>
</div>

Angularjs factory data or object inaccessible directly inside the controller

I have just created an Angular JS factory (below is the code) which returns data for two datepickers (ui.bootstrap's elements) and bind to my html code, but when I am trying to modify the return $scope object by factory inside the controller its not working, I mean I cannot access the $scope.Date1 or $scope.Date2 objects which are available inside the controller (returned from factory).
var MyApp = angular.module("TestApp", ["ui.bootstrap"]);
angular.module('TestApp').factory('FirstFactory', function() {
return {
TwoDates: function(scope) {
scope.clear = function() {
scope.Date1 = null;
scope.Date2 = null;
};
scope.inlineOptions1 = {
customClass: getDayClass,
minDate: new Date(),
// showWeeks: true
};
scope.inlineOptions2 = {
customClass: getDayClass,
minDate: new Date(),
// showWeeks: true
};
scope.dateOptions1 = {
//dateDisabled: disabled,
formatYear: 'yyyy',
maxDate: new Date(2050, 7, 22),
minDate: new Date(),
startingDay: 1
};
scope.dateOptions2 = {
//dateDisabled: disabled,
formatYear: 'yyyy',
maxDate: new Date(2050, 5, 22),
minDate: new Date(),
//minDate: new Date($scope.changeMin()),
startingDay: 1
};
scope.toggleMin = function() {
scope.inlineOptions1.minDate = scope.inlineOptions1.minDate ? null : new Date();
scope.dateOptions1.minDate = scope.inlineOptions1.minDate;
var min2 = new Date();
scope.$watch('Date1', function() {
min2 = scope.Date1;
scope.dateOptions2.minDate = min2;
if (scope.Date1 > scope.Date2) {
// debugger;
scope.Date2 = scope.Date1;
console.log("Yes It's greater");
}
// console.log(min2);
});
scope.$watch('Date2', function() {
if (scope.Date2 < scope.Date1) {
//debugger;
scope.Date1 = scope.Date2;
console.log("Yes It's lesser");
}
// console.log(max1);
});
};
scope.toggleMin();
scope.open1 = function() {
scope.popup1.opened = true;
};
scope.open2 = function() {
scope.popup2.opened = true;
};
scope.popup1 = {
opened: false
};
scope.popup2 = {
opened: false
};
scope.setDate = function(year, month, day) {
scope.Date1 = new Date(year, month, day);
scope.Date2 = new Date(year, month, day);
};
scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd-MM-yyyy', 'shortDate'];
scope.format = scope.formats[2];
scope.altInputFormats = ['M!/d!/yyyy'];
function getDayClass(data) {
var date = data.date,
mode = data.mode;
if (mode === 'day') {
var dayToCheck = new Date(date).setHours(0, 0, 0, 0);
for (var i = 0; i < scope.events.length; i++) {
var currentDay = new Date(scope.events[i].date).setHours(0, 0, 0, 0);
if (dayToCheck === currentDay) {
return scope.events[i].status;
}
}
}
return '';
}
}
};
});
angular.module('TestApp').controller('StartDate', function($scope, $log, FirstFactory) {
//debugger;
FirstFactory.TwoDates($scope);
//or
console.log($scope.Date1);
});
<fieldset>
<form name="MeForm" novalidate>
<div ng-controller="StartDate">
<div class="row">
<div class="col-md-3">
<div>
<p class="input-group">
<input type="text" name="fdate" class="form-control" uib-datepicker-popup="{{format}}" ng-model="Date1" is-open="popup1.opened" datepicker-options="dateOptions1" 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>
<p class="error validationerror" ng-show="MeForm.fdate.$invalid && MeForm.fdate.$touched">First date is required</p>
</p>
</div>
<input type="text" [ng-value="Date1" ] />#*{{Date1 | date: 'dd-MM-yyyy'}}*#
<div>
<p class="input-group">
<input type="text" name="ldate" class="form-control" uib-datepicker-popup="{{format}}" ng-model="Date2" is-open="popup2.opened" datepicker-options="dateOptions2" 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>
<p class="error validationerror" ng-show="MeForm.ldate.$invalid && MeForm.ldate.$touched">Last date is required</p>
</p>
</div>
#*{{Date2 | date: 'dd-MM-yyyy'}}*#
</div>
</div>
</div>
<div>
<input type="text" name="firstname" ng-required="true" ng-model="user.firstname" placeholder="Enter your first name" class="form-control" />
<p class="error validationerror" ng-show="MeForm.firstname.$invalid && MeForm.firstname.$touched">You must fill out your first name</p>
<br />
<input type="text" name="lastname" ng-required="true" ng-model="user.lastname" placeholder="Enter your first name" class="form-control" />
<p class="error validationerror" ng-show="MeForm.lastname.$invalid && MeForm.lastname.$touched">You must fill out your last name</p>
<br />
<button type="submit" class="btn submitbtn">Submit</button>
</div>
</form>
</fieldset>
You constructed your factory return statement very oddly. Instead of this:
angular.module('TestApp').factory('FirstFactory', function() {
return {
TwoDates: function(scope) {
scope.example = function() {
//logic
}
//etc functions
}
}
}
Try it like this instead.
angular.module('TestApp').factory('FirstFactory', function() {
var Date1 = 0;
var Date2 = 0;
TwoDates.example = function(){
//logic on Date1 or Date2
}
//TwoDates.exampleFunction = function(){....
return TwoDates; //Important!
}
Notice that the factory's purpose is to return an object that contains all of your logic and variables.
This way you'll be able to use the Date1 and Date2 variables from within the factory and in any controllers that you use the factory in using factoryInstance.getDate1.
In the end your code (the very basics at least) will look like this
var MyApp = angular.module("TestApp", ["ui.bootstrap"]);
angular.module('TestApp').factory('FirstFactory', function() {
var Date1 = 0;
var Date2 = 0;
TwoDates.incrDate1 = function(){
Date1 += 1;
}
TwoDates.getDate1 = function(){
return Date1;
}
return TwoDates;
}
angular.module('TestApp').controller('StartDate', function($scope, FirstFactory) {
//get *function* that returns variables from Factory
//notice that I don't use FF.getDate1(), but instead pass the function without invoking it
$scope.getDate1 = FirstFactory.getDate1; //<-- no ()
console.log($scope.getDate1); // 0
FirstFactory.incrDate1(); // calls Factory method, uses Date1 variable
console.log($scope.getDate1); // 1
//you can also add other factory functions to your scope so you can use them in the html
$scope.incrDate1 = FirstFactory.incrDate1();
});
Here's another stackoverflow question that might help you out.

Angularjs min-date max-date validation messages

Angularjs - bootstraup UI- trying to place min-date max-date validation error messages.
but it is not working, not showing any min-date or max-date validation message.
I also tried form.offerEndDate.$error.min or form.offerEndDate.$error.max still didn't work
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="form.offerEndDate" is-open="opened" min-date="minDate" max-date="'2015-06-22'" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
<div ng-show="form.offerEndDate.$dirty && form.offerEndDate.$invalid">
<span class="alert-danger" ng-show="form.offerEndDate.$error.required">
Offer End Date is required.
</span>
<span class="alert-danger" ng-show="form.offerEndDate.$error.minDate">
Min Date Error.
</span>
<span class="alert-danger" ng-show="form.offerEndDate.$error.maxDate">
Max Date Error.
</span>
</div>
Here's finally my workaround for this problem:
<div class="input-group">
<input name="endDate" class="form-control" type="text" is-open="openedEnd"
datepicker-popup="shortDate" ng-focus="openedEnd=true"
date-disabled="disabledEnd(date,mode)"
datepicker-options="dateOptions"
ng-model="offre.endDate" required="" min="endMinDate" max="endMaxDate"
ts-valid-date="" />
<span class="input-group-btn">
<button type="button" class="btn btn-default btn-default-bordered" ng-click="openEnd($event)">
<i class="fa fa-calendar"></i>
</button>
</span>
</div>
<div class="alert alert-danger"
ng-messages="formOffre.endDate.$error"
ng-if="formOffre.endDate.$dirty || vm.showOffreValidation">
<div ng-message="required">#L("RemplissezLaDateDeFin")</div>
<div ng-message="date">#L("DateIncorrecte")! {{vm.endDateInvalidMessage}} </div>
<div ng-message="invalidDate">#L("DateIncorrecte")! {{vm.startDateInvalidMessage}}</div>
<div ng-messages-include="error-messages"></div>
ts-valid-date is a custom directive:
angular.module('app')
.directive('tsValidDate', ['$parse', function ($parse) {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
scope.$watch(function () {
return $parse(attrs.min)(scope) <= ctrl.$modelValue && $parse(attrs.max)(scope) >= ctrl.$modelValue;
}, function (currentValue) {
ctrl.$setValidity('invalidDate', currentValue);
});
}
};
}]);
This gives me the wanted solution, invalid the input and show ng-message with the minDate and maxDate allowed
Here's the javascript part of html:
$scope.dateOptions = {
showButtonBar: false,
startingDay: 1
};
$scope.startMinDate = new Date();
$scope.startMaxDate = new Date(new Date().getFullYear() + 5, new Date().getMonth(), new Date().getDate());
$scope.endMinDate = new Date();
$scope.endMaxDate = new Date(new Date().getFullYear() + 5, new Date().getMonth(), new Date().getDate());
vm.startDateInvalidMessage = abp.utils.formatString($scope.dateInvalidMessage,
$filter('date')($scope.startMinDate), $filter('date')($scope.startMaxDate));
vm.endDateInvalidMessage = abp.utils.formatString($scope.dateInvalidMessage,
$filter('date')($scope.endMinDate), $filter('date')($scope.endMaxDate));
$scope.disabledStart = function (date, mode) {
return date <= $scope.startMinDate || date > $scope.startMaxDate;
};
$scope.disabledEnd = function (date, mode) {
return date < $scope.endMinDate || date >= $scope.endMaxDate;
};
$scope.verifyDate = function () {
if ($scope.offre.startDate) {
$scope.endMinDate = $scope.offre.startDate;
vm.startDateInvalidMessage = abp.utils.formatString($scope.dateInvalidMessage,
$filter('date')($scope.startMinDate), $filter('date')($scope.startMaxDate));
vm.endDateInvalidMessage = abp.utils.formatString($scope.dateInvalidMessage,
$filter('date')($scope.endMinDate), $filter('date')($scope.endMaxDate));
}
if ($scope.offre.endDate) {
$scope.startMaxDate = $scope.offre.endDate;
vm.startDateInvalidMessage = abp.utils.formatString($scope.dateInvalidMessage,
$filter('date')($scope.startMinDate), $filter('date')($scope.startMaxDate));
vm.endDateInvalidMessage = abp.utils.formatString($scope.dateInvalidMessage,
$filter('date')($scope.endMinDate), $filter('date')($scope.endMaxDate));
}
};
$scope.$watch('offre.endDate', function () {
$scope.verifyDate();
});
$scope.$watch('offre.startDate', function () {
$scope.verifyDate();
});
$scope.openStart = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.openedStart = true;
};
$scope.openEnd = function ($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.openedEnd = true;
};
It can be connected to this issue.
Try to change min-date to min. and max-date to max.
Also keep in mind this issue. So you will be still able to type in manually date in the input field, though your calender will be disabled.

Resources