Reputation: 195
I want to disable specific dates in the date picker of AngularJS.
I am using AngularJS-bootstrap css for components(angular directives).(ui.bootstrap.datepicker)
i was using the following code:
datePicker.html:
<title>Typehead</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
<script src="./ui-bootstrap-tpls-1.2.1.min.js"></script>
<script src="./datePicker.js"></script>
</head>
<body ng-app="ui.bootstrap.demo" >
<style>
.full button span {
background-color: limegreen;
border-radius: 32px;
color: black;
}
.partially button span {
background-color: orange;
border-radius: 32px;
color: black;
}
</style>
<div ng-controller="DatepickerDemoCtrl">
<pre>Selected date is: <em>{{dt | date:'fullDate' }}</em></pre>
<h4>Inline</h4>
<div style="display:inline-block; min-height:290px;">
<uib-datepicker ng-model="dt" class="well well-sm" datepicker-options="inlineOptions" ></uib-datepicker>
</div>
<h4>Popup</h4>
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt" is-open="popup1.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="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt" is-open="popup3.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="open3()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup ng-model="dt" is-open="popup2.opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" />
<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>
</div>
<div class="row">
<div class="col-md-6">
<label>Format: <span class="muted-text">(manual alternate <em>{{altInputFormats[0]}}</em>)</span></label> <select class="form-control" ng-model="format" ng-options="f for f in formats"><option></option></select>
</div>
</div>
<hr />
<button type="button" class="btn btn-sm btn-info" ng-click="today()">Today</button>
<button type="button" class="btn btn-sm btn-default" ng-click="setDate(2009, 7, 24)">2009-08-24</button>
<button type="button" class="btn btn-sm btn-danger" ng-click="clear()">Clear</button>
<button type="button" class="btn btn-sm btn-default" ng-click="toggleMin()" uib-tooltip="After today restriction">Min date</button>
</div>
</body>
datePicker.js:
var myApp= angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap', 'ui.bootstrap.dateparser', 'ui.bootstrap.datepicker']);
myApp.controller('DatepickerDemoCtrl', function($scope, $http) {
$scope.today = function() {
$scope.dt = new Date();
};
$scope.today();
$scope.clear = function() {
$scope.dt = null;
};
$scope.inlineOptions = {
customClass: getDayClass,
minDate: new Date(),
showWeeks: false
};
$scope.dateOptions = {
dateDisabled: disabled,
formatYear: 'yy',
maxDate: new Date(2020, 5, 22),
minDate: new Date(),
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.toggleMin = function() {
$scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date();
$scope.dateOptions.minDate = $scope.inlineOptions.minDate;
};
$scope.toggleMin();
$scope.open1 = function() {
$scope.popup1.opened = true;
};
$scope.open2 = function() {
$scope.popup2.opened = true;
};
$scope.open3 = function() {
$scope.popup3.opened = true;
};
$scope.setDate = function(year, month, day) {
$scope.dt = new Date(year, month, day);
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
$scope.format = $scope.formats[0];
$scope.altInputFormats = ['M!/d!/yyyy'];
$scope.popup1 = {
opened: false
};
$scope.popup2 = {
opened: false
};
$scope.popup3 = {
opened: false
};
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
var afterTomorrow = new Date();
afterTomorrow.setDate(tomorrow.getDate() + 1);
$scope.events = [
{
date: tomorrow,
status: 'full'
},
{
date: afterTomorrow,
status: 'partially'
}
];
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 '';
}
});
the documentation gives me : dateDisabled (date, mode) - An optional expression to disable visible options based on passing a date and current mode.
i tried long and hard to use it but wasted 5 hours on it. im sure the solution is simple.Can anyone help with the following:
1.How do i use it to disable a single date 2.Disable multiple dates passed from an array!
any help with working example would be appreciated!
Upvotes: 3
Views: 9231
Reputation: 521
Link the date-disabled attribute to a function that takes two arguments in your scope like this:
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" date-disabled="disabled(date, mode)" /> <!-- Other attributes deleted for clarity -->
That function will be called for all the visible dates on the calendar. So, you will need to check the date passed against the dates you want to be disabled. For example, the function bellow will disable the dates: March 14, 2016, March 15, 2016 and March 16, 2016
$scope.disabled = function(date, mode){
var holidays = [
new Date(2016,2,14),
new Date(2016,2,15),
new Date(2016,2,16),
]
var isHoliday = false;
for(var i = 0; i < holidays.length ; i++) {
if(areDatesEqual(holidays[i], date)){
isHoliday = true;
}
}
return ( mode === 'day' && isHoliday );
};
function areDatesEqual(date1, date2) {
return date1.setHours(0,0,0,0) === date2.setHours(0,0,0,0)
}
UPDATE:
To change the class of a specific date you use the custom-class attribute:
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" date-disabled="disabled(date, mode)" custom-class="dayClass(date, mode)"/>
The dayClass function will be called for all the visible dates and return the css class you want to add to that element. For example, the function below will add the class appointment to the dates on the appointments array
$scope.dayClass = function(date, mode) {
var appointments = [
new Date(2016,2,3),
new Date(2016,2,8),
new Date(2016,2,22),
]
if (mode === 'day') {
var dateToCheck = new Date(date);
for(var i = 0; i < appointments.length ; i++) {
if(areDatesEqual(appointments[i], dateToCheck)){
return 'appointment';
}
}
}
return '';
}
Then you need to add some style, something like this:
.appointment>button {
color: white;
background-color: red;
}
UPDATE 2
To perform an action for specific dates you could use ng-change and follow the same approach as before, it could be something like this:
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt" ng-change="dateSelected()" /> <!-- Other attributes deleted for clarity -->
On your controller:
$scope.dateSelected = function(){
var appointments = [
new Date(2016,2,3),
new Date(2016,2,8),
new Date(2016,2,22),
];
var dateSelected = new Date($scope.dt);
for(var i = 0; i < appointments.length ; i++) {
if(areDatesEqual(appointments[i], dateSelected)){
performAction();
}
}
};
function performAction(){
alert("Appointment date selected");
}
Here a full example:
var myApp= angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap', 'ui.bootstrap.dateparser', 'ui.bootstrap.datepicker']);
myApp.controller('DatepickerDemoCtrl', function($scope, $http) {
$scope.today = function() {
$scope.dt = new Date();
};
$scope.today();
$scope.clear = function() {
$scope.dt = null;
};
$scope.inlineOptions = {
minDate: new Date(),
showWeeks: false
};
$scope.dateOptions = {
formatYear: 'yy',
maxDate: new Date(2020, 5, 22),
minDate: new Date(),
startingDay: 1
};
// Disable weekend selection
function disabledasda(data) {
var date = data.date,
mode = data.mode;
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
}
$scope.toggleMin = function() {
$scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date();
$scope.dateOptions.minDate = $scope.inlineOptions.minDate;
};
$scope.toggleMin();
$scope.open1 = function() {
$scope.popup1.opened = true;
};
$scope.setDate = function(year, month, day) {
$scope.dt = new Date(year, month, day);
};
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
$scope.format = $scope.formats[0];
$scope.altInputFormats = ['M!/d!/yyyy'];
$scope.popup1 = {
opened: false
};
var today = new Date();
$scope.holidays = [
new Date(today.getFullYear(),today.getMonth(),14),
new Date(today.getFullYear(),today.getMonth(),15),
new Date(today.getFullYear(),today.getMonth(),16),
]
$scope.appointments = [
new Date(today.getFullYear(),today.getMonth(),3),
new Date(today.getFullYear(),today.getMonth(),7),
new Date(today.getFullYear(),today.getMonth(),20),
]
$scope.disabled = function(date, mode){
var isHoliday = false;
for(var i = 0; i < $scope.holidays.length ; i++) {
if(areDatesEqual($scope.holidays[i], date)){
isHoliday = true;
}
}
return ( mode === 'day' && isHoliday );
};
function areDatesEqual(date1, date2) {
return date1.setHours(0,0,0,0) === date2.setHours(0,0,0,0)
}
$scope.dayClass = function(date, mode) {
if (mode === 'day') {
var dateToCheck = new Date(date);
for(var i = 0; i < $scope.appointments.length ; i++) {
if(areDatesEqual($scope.appointments[i], dateToCheck)){
return 'appointment';
}
}
}
return '';
};
$scope.dateSelected = function(){
var dateSelected = new Date($scope.dt);
for(var i = 0; i < $scope.appointments.length ; i++) {
if(areDatesEqual($scope.appointments[i], dateSelected)){
performAction();
}
}
};
function performAction(){
alert("Appointment date selected");
}
});
<html>
<head>
<title>Typehead</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.2/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.2/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap-tpls.min.js"></script>
</head>
<body ng-app="ui.bootstrap.demo" >
<style>
.full button span {
background-color: limegreen;
border-radius: 32px;
color: black;
}
.partially button span {
background-color: orange;
border-radius: 32px;
color: black;
}
.appointment>button {
color: white;
background-color: red;
}
</style>
<div ng-controller="DatepickerDemoCtrl">
<pre>Selected date is: <em>{{dt | date:'fullDate' }}</em></pre>
<h4>Popup</h4>
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt" ng-change="dateSelected()"is-open="popup1.opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" alt-input-formats="altInputFormats" date-disabled="disabled(date, mode)" custom-class="dayClass(date, mode)" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
</div>
</body>
</html>
Upvotes: 6