AngularJS Example
HTML
<div ng-app id="calender_col">
<div ng-controller="calendarCtrl">
<div id="calender_top_arrow"
ng-mousedown="calendarUpArrowMouseStillDown = true; CalendarScrollUp();"
ng-mouseup="calendarUpArrowMouseStillDown = false;">Press to scroll up (or jusr scroll)</div>
<ul id="calendar">
<li ng-repeat="year in years" class="years">
<h1>{{year.name}}</h1>
<ul class="months">
<li ng-repeat="month in year.months" class="month" id="{{month.number}}.{{year.name}}">
<h3>{{month.name}}</h3>
<ul class="days">
<li ng-repeat="day in month.days | orderBy:orderProp" class="day" ng-class="isToday(day.date, month.number, year.name)">
<div class="day_div" ng-class="getDayClass(day.name, day.date, month.number, year.name)">
<div class="day_date {{day.date}}_{{month.number}}_{{year.name}}">
<h2>{{day.date}}</h2>
<h4>{{day.name}}</h4>
</div>
<ul class="activities">
<li ng-repeat="activity in day.activities" ng-click="$emit('calendarActivityClick', {name: activity.name})">
<span class="calender_activity_title">{{activity.name}}</span>
<span class="calender_activity_amount" ng-class="calendarActivityClass(activity)">{{activity.total_amount}}</span>
</li>
</ul>
</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<div id="calender_bottom_arrow"
...
CSS
</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ -->
<script src="http://docs.angularjs.org/angular-1.0.1.min.js"></script>
<style>
.ng-invalid { border: 1px solid red; }
#calender_col {
width:170px;
border-right:2px #f2f2f2 solid;
min-height:400px;
}
#calendar {
display:block;
width: 170px;
height: 400px;
overflow: hidden;
border:1px solid #e5e5e5;
margin-top:-10px;
}
.calendarActivityClassPositive {
color: green;
list-style: none;
}
.calendarActivityClassNegative {
color: #ff0000;
list-style: none;
}
#calender_top_arrow {
height:48px;
}
#calender_bottom_arrow {
}
.years {
display:block;
width:170px;
}
.years h1 {
display:block;
float:right;
width:170px;
height:35px;
line-height:35px;
background:#f1f1f1;
color:#999;
font-size:27px;
text-align:center;
font-weight:bold;
text-shadow:0px 1px 0px rgba(000,000,000,0.5);
}
.months {
display:block;
float:right;
width:170px;
list-style: none;
margin: 0;
}
.month {
float:right;
background-color:#d3d3d3;
display:block;
width:170px;
}
.month h3 {
display:block;
float:left;
width:170px;
height:26px;
line-height:26px;
text-align:center;
color:#FFF;
font-weight: bold;
background:orange;
border-top:1px solid #eaaa00;
font-size:16px;
text-shadow:0px 1px 0px rgba(000,000,000,0.5);
}
.days {
list-style: none;
margin: 0;
padding-left: 4px;
display:block;
float:right;
width:170px;
}
.day {
border-bottom: 1px solid #b3b3b3;
border-top:1px solid #f1f1f1;
display:block;
float:right;
width:170px;
}
.day_date {
float:right;
width:28px;
}
.day h2 {
display:block;
width:28px;
color:#9e9e9e;
text-align:center;
padding-top:3px;
font-size:18px;
text-shadow:0px 1px 0px rgba(255,255,255,0.7);
}
.day h4 {
border-top: 1px solid #BBB;
...
JavaScript
Date.prototype.getMonthName = function() {
var m = ['Jan','Feb','Mar','Apr','May','Jun','Jul',
'Aug','Sep','Oct','Nov','Dec'];
return m[this.getMonth()];
};
Date.prototype.getDayName = function() {
var m = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
return m[this.getDay()];
};
function calendarCtrl($scope) {
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf());
dat.setDate(dat.getDate() + days);
return dat;
};
$scope.toObject = function(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
if (arr[i] !== undefined){
if (String.fromCharCode(94 + i) == undefined)
alert(i);
rv[String.fromCharCode(94 + i)] = arr[i];
}
return rv;
};
$scope.getDates = function(startDate, stopDate) {
var years = {};
var currentDate = startDate;
var currentYear = {};
currentYear.name = currentDate.getFullYear();
years[currentYear.name] = currentYear;
var months = [];
var currentMonth = {};
currentMonth.number = Number(currentDate.getMonth()+1);
currentMonth.name = currentDate.getMonthName();
months.push(currentMonth);
years[currentYear.name]['months'] = $scope.toObject(months);
var days = [];
while (currentDate <= stopDate) {
if (currentDate.getFullYear() != currentYear.name)
{
months = [];
currentYear = {};
currentYear.name = currentDate.getFullYear();
years[currentYear.name] = currentYear;
}
if ((currentDate.getMonth()+1) != currentMonth.number)
{
currentMonth = {};
days = [];
currentMonth.number = Number(currentDate.getMonth()+1);
currentMonth.name = currentDate.getMonthName();
...