Introduced simple datepicker
diff --git a/dev/js/src/datepicker.js b/dev/js/src/datepicker.js
new file mode 100644
index 0000000..1a1d9fe
--- /dev/null
+++ b/dev/js/src/datepicker.js
@@ -0,0 +1,222 @@
+/**
+ * Date picker for the
+ * Virtual Collection builder.
+ */
+define(['util'], function () {
+ "use strict";
+
+ var loc = KorAP.Locale;
+
+ loc.WDAY = loc.WDAY || [
+ 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'
+ ];
+
+ loc.MONTH = loc.MONTH || [
+ 'January', 'February', 'March', 'April',
+ 'May', 'June', 'July', 'August',
+ 'September', 'October', 'November',
+ 'December'
+ ];
+
+ var d = document;
+
+ return {
+ create : function () {
+ return Object.create(this)._init();
+ },
+
+ _init : function () {
+ return this;
+ },
+
+ select : function (year, month, day) {
+ if (arguments.length >= 1) {
+ this._selected = {'year' : year};
+ if (arguments.length >= 2) {
+ this._selected['month'] = month;
+ if (arguments.length >= 3)
+ this._selected['day'] = day;
+ };
+ return this;
+ };
+ return this._selected;
+ },
+
+ show : function (year, month) {
+ var picker = d.createElement('div');
+ picker.classList.add('datepicker');
+ this._showYear = year;
+ this._showMonth = month;
+ picker.appendChild(this._yearHelper());
+ picker.appendChild(this._monthHelper());
+ picker.appendChild(this._dayHelper());
+ return picker;
+ },
+
+ incrYear : function () {
+ this._showYear++;
+ this._updateYear();
+ this._updateMonth();
+ this._updateDay();
+ return;
+ },
+
+ decrYear : function () {
+ this._showYear--;
+ this._updateYear();
+ this._updateMonth();
+ this._updateDay();
+ return;
+ },
+
+ incrMonth : function () {
+ this._showMonth++;
+ if (this._showMonth > 12) {
+ this._showMonth = 1;
+ this.incrYear();
+ }
+ else {
+ this._updateMonth();
+ this._updateDay();
+ };
+ },
+
+ decrMonth : function () {
+ this._showMonth--;
+ if (this._showMonth < 1) {
+ this._showMonth = 12;
+ this.decrYear();
+ }
+ else {
+ this._updateMonth();
+ this._updateDay();
+ };
+ },
+
+ _yearHelper : function () {
+ var year = d.createElement('div');
+ year.classList.add('year');
+
+ // Decrement year
+ year.appendChild(d.createElement('span'))
+ .onclick = this.decrYear.bind(this);
+
+ this._yElement = year.appendChild(d.createElement('span'));
+ this._yElement.appendChild(document.createTextNode(this._showYear));
+
+ // Increment year
+ year.appendChild(d.createElement('span'))
+ .onclick = this.incrYear.bind(this);
+
+ return year;
+ },
+
+ _updateYear : function () {
+ this._yElement.firstChild.data = this._showYear;
+ },
+
+ _monthHelper : function () {
+ var month = d.createElement('div');
+ month.classList.add('month');
+
+ // Decrement month
+ month.appendChild(d.createElement('span'))
+ .onclick = this.decrMonth.bind(this);
+
+ this._mElement = month.appendChild(d.createElement('span'));
+ this._mElement.appendChild(
+ document.createTextNode(loc.MONTH[this._showMonth-1])
+ );
+
+ // Increment month
+ month.appendChild(d.createElement('span'))
+ .onclick = this.incrMonth.bind(this);
+
+ return month;
+ },
+
+ _updateMonth : function () {
+ this._mElement.firstChild.data = loc.MONTH[this._showMonth-1];
+ },
+
+ _dayHelper : function () {
+ var table = d.createElement('table');
+
+ var tr = table.appendChild(d.createElement('thead'))
+ .appendChild(d.createElement('tr'));
+ for (var i = 0; i < 7; i++) {
+ tr.appendChild(d.createElement('th'))
+ .appendChild(d.createTextNode(loc.WDAY[i]));
+ };
+
+ this._dBElement = this._dayBody();
+
+ table.appendChild(this._dBElement);
+ return table;
+ },
+
+ _dayBody : function () {
+ var showDate = new Date(this._showYear, this._showMonth - 1, 1, 0, 0, 0, 0);
+ var date = new Date(this._showYear, this._showMonth - 1, 1, 0, 0, 0, 0);
+ var today = new Date();
+
+ // Skip back to the previous monday (may be in the last month)
+ date.setDate(date.getDate() - ((date.getDay() + 6) % 7));
+
+ var tb = d.createElement('tbody');
+
+ var s = this.select();
+
+ // Iterate over all days of the table
+ while (1) {
+
+ // Loop through the week
+ var tr = tb.appendChild(d.createElement('tr'));
+ for (var i = 0; i < 7; i++) {
+ var td = tr.appendChild(d.createElement('td'));
+
+ // Not part of the current month
+ if (date.getMonth() !== showDate.getMonth())
+ td.classList.add('out');
+
+ // This is the current day
+ if (date.getDate() === today.getDate() &&
+ date.getMonth() === today.getMonth() &&
+ date.getFullYear() === today.getFullYear()) {
+ td.classList.add('today');
+ };
+
+ // This is the day selected
+ if (s['day']) {
+ if (date.getDate() === s['day'] &&
+ date.getMonth() === s['month']-1 &&
+ date.getFullYear() === s['year']) {
+ td.classList.add('selected');
+ };
+ };
+
+ // Add the current day to the table
+ td.appendChild(
+ d.createTextNode(date.getDate())
+ );
+
+ // Next day
+ date.setDate(date.getDate() + 1);
+ };
+
+ if (date.getMonth() !== showDate.getMonth())
+ break;
+ };
+ return tb;
+ },
+
+ _updateDay : function () {
+ var newBody = this._dayBody();
+ this._dBElement.parentNode.replaceChild(
+ newBody,
+ this._dBElement
+ );
+ this._dBElement = newBody;
+ }
+ };
+});