<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link data-require="bootstrap-css@*" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css"
/>
<script data-require="angular.js@1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script data-require="moment.js@2.10.2" data-semver="2.10.2" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<script data-require="angular-animate@*" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular-animate.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MyCalendarSlider as vm">
<div class="jumbotron">
<div class="container">
<h1>Animated Day of Week Selector</h1>
<p>Example using ng-animate.</p>
<p>Associated <a href="http://stackoverflow.com/questions/34614719/sliding-animation-when-updating-an-array-in-angular" target="_blank">stackoverflow</a> question.</p>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="vm.stagger"> Stagger animations
</label>
</div>
<div>
<label>Selected day</label>: {{ vm.selectedDate }}
</div>
</div>
</div>
<div class="container">
<div class="calendar-slider-actions" ng-class="{ stagger: vm.stagger }">
<a class="slider-prev" ng-click="vm.prevWeek()">
<i class="glyphicon glyphicon-menu-left"></i>
</a>
<div class="slider-clip-container">
<div class="slider-clip slide-direction-{{ vm.slideDirection }}">
<ul class="slides">
<li class="slide" data-ng-repeat="date in vm.dates">
<div class="radio">
<input type="radio" name="group-days" id="field-{{date.weekDay | lowercase}}" ng-value="vm.selectedDate" ng-checked="vm.selectedDate === date.date"
/>
<label class="btn btn-primary btn-primary-alpha radio-label" for="field-{{date.weekDay | lowercase}}" ng-click="vm.selectDate(date)">
<strong>{{date.weekDay}}</strong> {{date.shortDate}}
</label>
</div>
</li>
</ul>
</div>
</div>
<a class="slider-next" ng-click="vm.nextWeek()">
<i class="glyphicon glyphicon-menu-right"></i>
</a>
</div>
</div>
</body>
</html>
/* global moment */
// Code goes here
var myApp = angular.module('myApp', ['ngAnimate']);
myApp.controller('MyCalendarSlider', DayPickerCtrl);
function DayPickerCtrl($scope) {
var vm = this;
vm.stagger = true;
vm.dates = [];
vm.selectedDate = moment().startOf('day').format();
_changeDisplayedWeek(0);
vm.selectDate = function (date) {
vm.selectedDate = date.date;
};
vm.nextWeek = function () {
vm.slideDirection = 'left';
_changeDisplayedWeek(7);
};
vm.prevWeek = function () {
vm.slideDirection = 'right';
_changeDisplayedWeek(-7);
};
function _changeDisplayedWeek(daysToAdd) {
var selectedDate = moment(vm.selectedDate).add(daysToAdd, 'days');
vm.selectedDate = selectedDate.format();
vm.weekOfYear = selectedDate.format('WW');
vm.dates = _expandWeek(selectedDate);
}
function _expandWeek(startDate) {
var dates = [];
var dayOfWeek = moment(startDate).startOf('isoweek');
for (var i = 0; i < 7; i++) {
dates.push({
weekDay: dayOfWeek.format('dd'),
shortDate: dayOfWeek.format('DD.MM'),
date: dayOfWeek.format()
});
dayOfWeek.add(1, 'd');
}
return dates;
}
}
/* Styles go here */
.calendar-slider-actions {
width: 815px;
height: 95px;
/*background-color: purple;*/
position: relative;
margin-bottom: 10px;
overflow: hidden;
}
.slider-prev, .slider-next {
position: absolute;
top: 0;
/*background-color: yellow;*/
display: inline-block;
width: 75px;
height: 95px;
text-align: center;
font-size: 40px;
line-height: 105px;
color: #ddd;
cursor: pointer;
}
.slider-next {
right: 0;
left: auto;
}
.slider-clip-container {
position: absolute;
left: 75px;
top: 0;
width: 665px;
overflow: hidden;
display: inline-block;
}
.slider-clip {
width: 1995px;
height: 95px;
}
.slides, .slide > .radio, .slide > .radio > input {
padding: 0;
margin: 0;
}
li.slide {
float: left;
list-style: none;
margin: 10px;
}
li.slide > .radio > input {
display: none;
}
li.slide > .radio > .btn {
height: 75px;
width: 75px;
overflow: hidden;
padding: 0;
font-size: 20px;
}
li.slide > .radio > .btn > strong {
display: block;
font-size: 35px;
margin-bottom: -10px;
}
li.slide > .radio > input:not([checked]) + .btn {
background: linear-gradient(#fff, #eee);
color: rgb(33, 68, 122);
border: solid #eee 2px;
}
.slide {
transition:0.5s transform, 0.5s opacity;
}
.stagger .slide.ng-enter-stagger, .slide.ng-leave-stagger {
transition-duration: 0s;
}
.stagger .slide.ng-enter-stagger {
transition-delay: 0.10s;
}
.stagger .slide.ng-leave-stagger {
transition-delay: 0.00s;
}
.slide-direction-left .slide.ng-enter {
transform:translateX(665px);
opacity: 0;
}
.slide-direction-left .slide.ng-enter-active {
transform:translateX(0px);
opacity: 1;
}
.slide-direction-left .slide.ng-leave {
transform:translateX(-665px);
opacity: 1;
}
.slide-direction-left .slide.ng-leave-active {
transform:translateX(-1330px);
opacity: 0;
}
.slide-direction-right .slide.ng-enter {
transform:translateX(-665px);
opacity: 0;
}
.slide-direction-right .slide.ng-enter-active {
transform:translateX(0px);
opacity: 1;
}
.slide-direction-right .slide.ng-leave {
transform:translateX(-665px);
opacity: 1;
}
.slide-direction-right .slide.ng-leave-active {
transform:translateX(0px);
opacity: 0;
}