diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..93c2249
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": [ [ "env", { modules: "umd" } ], "stage-1", "react" ],
+ "retainLines": true
+}
diff --git a/calendar-material.css b/calendar-material.css
index 2b8c64d..9e1fd66 100644
--- a/calendar-material.css
+++ b/calendar-material.css
@@ -4,7 +4,7 @@
width: 301px;
background: #fff;
position: absolute;
- z-index: 100;
+ z-index: 10000;
padding: 0;
font-family: Roboto, sans-serif;
box-shadow: 0 19px 60px rgba(0, 0, 0, .3), 0 15px 20px rgba(0, 0, 0, .22)
diff --git a/calendar.js b/calendar.js
index 5cd687d..4bd618f 100644
--- a/calendar.js
+++ b/calendar.js
@@ -4,7 +4,7 @@
*
* Original: http://www.openjs.com/scripts/ui/calendar/
* Modified: http://yourcmc.ru/git/vitalif-js/calendar
- * Version: 2018-03-14
+ * Version: 2018-03-17
* License: MIT-like, http://www.openjs.com/license.php
*
* Example:
@@ -13,294 +13,365 @@
* Calendar.set("date");
*
*/
-function Calendar()
+export class Calendar
{
-}
-
-// Configuration
-Calendar.defaultOptions = {
- month_names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],
- close_label: 'Закрыть',
- weekdays: ["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],
- sunday: 6,
- selectboxes: false, // true: use selectboxes for year and month, false: show months and years in table
- years: {min: -70, max: 10}, // range of displayed years if selectboxes==true
- format: 'd.m.Y', // either d.m.Y or Y-m-d, other formats are not supported
- month_days: [31,28,31,30,31,30,31,31,30,31,30,31],
- // Today's date
- today: new Date(),
-};
-
-// State variables
-Calendar.instance = null;
-Calendar.box = null;
-Calendar.addedListener = false;
-
-Calendar.prototype.setHTML = function(html)
-{
- html += ""+this.close_label+" ";
- Calendar.box.innerHTML = html;
-};
-
-/// Called when the user clicks on a date in the calendar.
-Calendar.prototype.selectDate = function(year, month, day)
-{
- var i = this.input;
- var t = i.value.split(/\s+/, 2)[1]||'';
- if (t)
- t = ' '+t;
- i.value = (this.format == 'Y-m-d' ? year + '-' + month + '-' + day : day + '.' + month + '.' + year) + t;
- Calendar.hideCalendar();
-};
-
-Calendar.prototype.showMonths = function(year, month)
-{
- var cur_y = this.today.getFullYear();
- var cur_m = this.today.getMonth();
- var sel_m = this.selected.getFullYear() == year ? this.selected.getMonth() : -1;
- var html = '';
- html += "
";
- html += " ";
- html += " "+year+" ";
- html += " ";
- html += "";
- for (var i in this.month_names) {
- if (i && !(i % 3))
- html += " ";
- var class_name = (year < cur_y || year == cur_y && i < cur_m ? 'past' :
- (year > cur_y || year == cur_y && i > cur_m ? 'future' : 'today'))
- + (i == sel_m ? ' selected' : '');
- html += ""+this.month_names[i]+" ";
- }
- html += " ";
- html += "
";
- this.setHTML(html);
-};
-
-Calendar.prototype.showYears = function(year)
-{
- var beg = year & ~15;
- var cur_y = this.today.getFullYear();
- var sel_y = this.selected.getFullYear();
- var html = '';
- html += "";
- html += "";
- html += " ";
- html += " "+beg+" - "+(beg+15)+" ";
- html += " ";
- html += " ";
- html += "";
- for (var i = 0; i < 16; i++) {
- if (i && !(i % 4))
- html += " ";
- var class_name = (beg+i < cur_y ? 'past' : (beg+i > cur_y ? 'future' : 'today'))
- + (beg+i == sel_y ? ' selected' : '');
- html += ""+(beg+i)+" ";
- }
- html += " ";
- html += "
";
- this.setHTML(html);
-};
-
-/// Creates a calendar with the date given in the argument as the selected date.
-Calendar.prototype.makeCalendar = function(year, month)
-{
- // Display the table
- var next_month = month+1;
- var next_month_year = year;
- if (next_month >= 12) {
- next_month = 0;
- next_month_year++;
+ // Configuration
+ static defaultOptions = {
+ month_names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],
+ close_label: 'Закрыть',
+ weekdays: ["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],
+ sunday: 6,
+ selectboxes: false, // true: use selectboxes for year and month, false: show months and years in table
+ years: {min: -70, max: 10}, // range of displayed years if selectboxes==true
+ format: 'd.m.Y', // either d.m.Y or Y-m-d, other formats are not supported
+ month_days: [31,28,31,30,31,30,31,31,30,31,30,31],
+ // Today's date
+ today: new Date(),
+ callback: null,
+ start: 'days',
}
- var previous_month = month-1;
- var previous_month_year = year;
- if (previous_month < 0) {
- previous_month = 11;
- previous_month_year--;
+ // State variables
+ static instance = null;
+ static box = null;
+ static addedListener = false;
+
+ setHTML(html)
+ {
+ html += ""+this.close_label+" ";
+ Calendar.box.innerHTML = html;
}
- var current_year = this.today.getFullYear();
+ isVisible()
+ {
+ return Calendar.instance == this && Calendar.box.style.display == 'block';
+ }
- var html = '';
- html += "";
- html += " ";
- if (!this.selectboxes) {
- html += " "+this.month_names[month]+" ";
- html += " "+year+" ";
- } else {
- html += " ";
- for (var i in this.month_names) {
- html += ""+this.month_names[i]+" ";
+ /// Called when the user clicks on a date in the calendar.
+ selectDate(year, month, day)
+ {
+ var i = this.input;
+ var t = i.value.split(/\s+/, 2)[1]||'';
+ if (t)
+ t = ' '+t;
+ if (this.callback)
+ {
+ var c = this.callback;
+ t = year + '-' + month + '-' + day + t;
+ c(new Date(t));
}
- html += " ";
- html += "";
- for (var i = current_year+this.years.min; i < current_year+this.years.max; i++) {
- html += ""+i+" ";
- }
- html += " ";
- }
- html += " ";
- html += "";
-
- // Get the first day of this month
- var first_day = new Date(year,month,1);
- var start_day = (first_day.getDay()+this.sunday)%7;
-
- var d = 1;
- var flag = 0;
-
- // Leap year support
- if (!(year % 4) && ((year % 100) || !(year % 400)))
- this.month_days[1] = 29;
- else
- this.month_days[1] = 28;
-
- var days_in_this_month = this.month_days[month];
-
- // Create the calendar
- var yea = this.today.getFullYear();
- var all_diff = (year - yea) || (month - this.today.getMonth());
- var sel_day = year == this.selected.getFullYear() && month == this.selected.getMonth() ? this.selected.getDate() : -1;
- for (var i = 0; i <= 5; i++) {
- if (w >= days_in_this_month)
- break;
- html += "";
- for (var j = 0; j < 7; j++) {
- if (d > days_in_this_month)
- flag = 0; // If the days has overshooted the number of days in this month, stop writing
- else if (j >= start_day && !flag)
- flag = 1; // If the first day of this month has come, start the date writing
-
- if (flag) {
- var w = d, mon = month+1;
- if (w < 10)
- w = "0" + w;
- if (mon < 10)
- mon = "0" + mon;
-
- // Is it today?
- var class_name = '';
-
- var diff = all_diff || (d - this.today.getDate());
- if (diff < 0)
- class_name = ' past';
- else if (!diff)
- class_name = ' today';
- else
- class_name = ' future';
-
- if (d == sel_day)
- class_name += ' selected';
-
- class_name += " " + this.weekdays[j].toLowerCase();
-
- html += ""+d+" ";
- d++;
+ else
+ {
+ t = (this.format == 'Y-m-d' ? year + '-' + month + '-' + day : day + '.' + month + '.' + year) + t;
+ i.value = t;
+ if ("Event" in window)
+ {
+ var evt = document.createEvent('Event');
+ evt.initEvent('change', true, true);
+ i.dispatchEvent(evt);
}
else
- html += " ";
+ i.fireEvent("onchange");
+ }
+ Calendar.instance.hideCalendar();
+ }
+
+ showMonths(year)
+ {
+ var cur_y = this.today.getFullYear();
+ var cur_m = this.today.getMonth();
+ var sel_m = this.selected.getFullYear() == year ? this.selected.getMonth() : -1;
+ var html = '';
+ html += "";
+ html += " ";
+ html += " "+year+" ";
+ html += " ";
+ html += "";
+ for (var i in this.month_names) {
+ if (i && !(i % 3))
+ html += " ";
+ var class_name = (year < cur_y || year == cur_y && i < cur_m ? 'past' :
+ (year > cur_y || year == cur_y && i > cur_m ? 'future' : 'today'))
+ + (i == sel_m ? ' selected' : '');
+ html += ""+this.month_names[i]+" ";
}
html += " ";
+ html += "
";
+ this.setHTML(html);
}
- html += "
";
- this.setHTML(html);
-};
-/// Display the calendar - if a date exists in the input box, that will be selected in the calendar.
-Calendar.prototype.showCalendar = function()
-{
- Calendar.instance = this;
- var input = this.input;
+ showYears(year)
+ {
+ var beg = year & ~15;
+ var cur_y = this.today.getFullYear();
+ var sel_y = this.selected.getFullYear();
+ var html = '';
+ html += "";
+ html += "";
+ html += " ";
+ html += " "+beg+" - "+(beg+15)+" ";
+ html += " ";
+ html += " ";
+ html += "";
+ for (var i = 0; i < 16; i++) {
+ if (i && !(i % 4))
+ html += " ";
+ var class_name = (beg+i < cur_y ? 'past' : (beg+i > cur_y ? 'future' : 'today'))
+ + (beg+i == sel_y ? ' selected' : '');
+ html += ""+(beg+i)+" ";
+ }
+ html += " ";
+ html += "
";
+ this.setHTML(html);
+ }
- //Position the div in the correct location...
- var div = Calendar.box;
- var xy = getOffset(input);
- var width = input.clientWidth||input.offsetWidth;
- var height = input.clientHeight||input.offsetHeight;
- div.style.left = (xy.left-1)+"px";
- div.style.top = (xy.top+height-1)+"px";
+ /// Creates a calendar with the date given in the argument as the selected date.
+ makeCalendar(year, month)
+ {
+ // Display the table
+ var next_month = month+1;
+ var next_month_year = year;
+ if (next_month >= 12) {
+ next_month = 0;
+ next_month_year++;
+ }
- // Show the calendar with the date in the input as the selected date
- this.selected = new Date();
- var date_in_input = input.value.replace(/\s+.*$/, ''); //Remove time
- if (date_in_input) {
- // date format is HARDCODE
- var selected_date = false;
- var date_parts = date_in_input.split("-");
- if (date_parts.length == 3) {
- // Y-m-d
- date_parts[1]--; //Month starts with 0
- selected_date = new Date(date_parts[0], date_parts[1], date_parts[2]);
- } else if (date_parts.length == 1) {
- date_parts = date_in_input.split('.');
+ var previous_month = month-1;
+ var previous_month_year = year;
+ if (previous_month < 0) {
+ previous_month = 11;
+ previous_month_year--;
+ }
+
+ var current_year = this.today.getFullYear();
+
+ var html = '';
+ html += "";
+ html += " ";
+ if (!this.selectboxes) {
+ html += " "+this.month_names[month]+" ";
+ html += " "+year+" ";
+ } else {
+ html += " ";
+ for (var i in this.month_names) {
+ html += ""+this.month_names[i]+" ";
+ }
+ html += " ";
+ html += "";
+ for (var i = current_year+this.years.min; i < current_year+this.years.max; i++) {
+ html += ""+i+" ";
+ }
+ html += " ";
+ }
+ html += " ";
+ html += "";
+
+ // Get the first day of this month
+ var first_day = new Date(year,month,1);
+ var start_day = (first_day.getDay()+this.sunday)%7;
+
+ var d = 1;
+ var flag = 0;
+
+ // Leap year support
+ if (!(year % 4) && ((year % 100) || !(year % 400)))
+ this.month_days[1] = 29;
+ else
+ this.month_days[1] = 28;
+
+ var days_in_this_month = this.month_days[month];
+
+ // Create the calendar
+ var yea = this.today.getFullYear();
+ var all_diff = (year - yea) || (month - this.today.getMonth());
+ var sel_day = year == this.selected.getFullYear() && month == this.selected.getMonth() ? this.selected.getDate() : -1;
+ for (var i = 0; i <= 5; i++) {
+ if (w >= days_in_this_month)
+ break;
+ html += "";
+ for (var j = 0; j < 7; j++) {
+ if (d > days_in_this_month)
+ flag = 0; // If the days has overshooted the number of days in this month, stop writing
+ else if (j >= start_day && !flag)
+ flag = 1; // If the first day of this month has come, start the date writing
+
+ if (flag) {
+ var w = d, mon = month+1;
+ if (w < 10)
+ w = "0" + w;
+ if (mon < 10)
+ mon = "0" + mon;
+
+ // Is it today?
+ var class_name = '';
+
+ var diff = all_diff || (d - this.today.getDate());
+ if (diff < 0)
+ class_name = ' past';
+ else if (!diff)
+ class_name = ' today';
+ else
+ class_name = ' future';
+
+ if (d == sel_day)
+ class_name += ' selected';
+
+ class_name += " " + this.weekdays[j].toLowerCase();
+
+ html += ""+d+" ";
+ d++;
+ }
+ else
+ html += " ";
+ }
+ html += " ";
+ }
+ html += "
";
+ this.setHTML(html);
+ }
+
+ /// Display the calendar - if a date exists in the input box, that will be selected in the calendar.
+ showCalendar()
+ {
+ Calendar.instance = this;
+ var input = this.input;
+
+ // Show the calendar with the date in the input as the selected date
+ this.selected = new Date();
+ var date_in_input = input.value.replace(/\s+.*$/, ''); //Remove time
+ if (date_in_input) {
+ // date format is HARDCODE
+ var selected_date = false;
+ var date_parts = date_in_input.split("-");
if (date_parts.length == 3) {
- // d.m.Y
+ // Y-m-d
date_parts[1]--; //Month starts with 0
- selected_date = new Date(date_parts[2], date_parts[1], date_parts[0]);
+ selected_date = new Date(date_parts[0], date_parts[1], date_parts[2]);
+ } else if (date_parts.length == 1) {
+ date_parts = date_in_input.split('.');
+ if (date_parts.length == 3) {
+ // d.m.Y
+ date_parts[1]--; //Month starts with 0
+ selected_date = new Date(date_parts[2], date_parts[1], date_parts[0]);
+ }
+ }
+ if (selected_date && !isNaN(selected_date.getFullYear())) { //Valid date.
+ this.selected = selected_date;
}
}
- if (selected_date && !isNaN(selected_date.getFullYear())) { //Valid date.
- this.selected = selected_date;
- }
+
+ if (this.start == 'years')
+ this.showYears(this.selected.getFullYear());
+ else if (this.start == 'months')
+ this.showMonths(this.selected.getFullYear());
+ else
+ this.makeCalendar(this.selected.getFullYear(), this.selected.getMonth());
+
+ // Position the div in the correct location...
+ var div = Calendar.box;
+ var xy = getOffset(input);
+ var height = input.clientHeight||input.offsetHeight;
+ div.style.display = "block";
+ div.style.left = (xy.left-1)+"px";
+ if (div.offsetHeight + xy.top+height-1 >= (document.documentElement.clientHeight||document.body.clientHeight) &&
+ xy.top-div.offsetHeight >= 0)
+ div.style.top = (xy.top-div.offsetHeight)+'px';
+ else
+ div.style.top = (xy.top+height-1)+"px";
+ };
+
+ /// Hides the currently show calendar.
+ hideCalendar()
+ {
+ Calendar.box.style.display = "none";
}
- this.makeCalendar(this.selected.getFullYear(), this.selected.getMonth());
- Calendar.box.style.display = "block";
-};
-
-/// Hides the currently show calendar.
-Calendar.hideCalendar = function()
-{
- Calendar.box.style.display = "none";
-};
-
-/// Setup a text input box to be a calendar box.
-Calendar.set = function(input_or_id, options)
-{
- if (typeof input_or_id == 'string')
- input_or_id = document.getElementById(input_or_id);
- if (!input_or_id)
- return; // If the input field is not there, exit.
- options = options||{};
- var instance = new Calendar();
- for (var i in Calendar.defaultOptions)
- instance[i] = options[i] || Calendar.defaultOptions[i];
- instance.input = input_or_id;
- Calendar.init();
- addListener(input_or_id, 'focus', function(ev) {
- instance.showCalendar();
- });
- return instance;
-};
-
-/// Will be called once when the first input is set.
-Calendar.init = function()
-{
- if (!Calendar.box || !Calendar.box.parentNode) {
- var div = document.createElement('div');
- if (!Calendar.box)
- Calendar.box = div;
- div.className = "calendar-box";
- addListener(div, "mousedown", function(ev) {
- ev = ev || window.event;
- if (ev.stopPropagation)
- ev.stopPropagation();
- else
- ev.cancelBubble = true;
- return true;
+ /// Setup a text input box to be a calendar box.
+ static set(input_or_id, options)
+ {
+ if (typeof input_or_id == 'string')
+ input_or_id = document.getElementById(input_or_id);
+ if (!input_or_id)
+ return; // If the input field is not there, exit.
+ options = options||{};
+ var instance = new Calendar();
+ for (var i in Calendar.defaultOptions)
+ instance[i] = options[i] || Calendar.defaultOptions[i];
+ instance.input = input_or_id;
+ Calendar.init();
+ input_or_id.addEventListener('focus', function(ev) {
+ instance.showCalendar();
});
- document.getElementsByTagName("body")[0].insertBefore(div,document.getElementsByTagName("body")[0].firstChild);
- if (!Calendar.addedListener) {
- addListener(document, "mousedown", function() { Calendar.hideCalendar(); });
- Calendar.addedListener = true;
+ return instance;
+ }
+
+ /// Will be called once when the first input is set.
+ static init()
+ {
+ if (!Calendar.box || !Calendar.box.parentNode) {
+ var div = document.createElement('div');
+ if (!Calendar.box)
+ Calendar.box = div;
+ div.className = "calendar-box";
+ div.addEventListener("mousedown", function(ev) {
+ ev = ev || window.event;
+ if (ev.stopPropagation)
+ ev.stopPropagation();
+ else
+ ev.cancelBubble = true;
+ return true;
+ });
+ document.getElementsByTagName("body")[0].insertBefore(div,document.getElementsByTagName("body")[0].firstChild);
+ if (!Calendar.addedListener) {
+ document.addEventListener("mousedown", function() { Calendar.instance && Calendar.instance.hideCalendar(); });
+ Calendar.addedListener = true;
+ }
}
}
-};
+}
+
+window.Calendar = Calendar;
+
+function getOffsetRect(elem)
+{
+ var box = elem.getBoundingClientRect();
+
+ var body = document.body;
+ var docElem = document.documentElement;
+
+ var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
+ var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
+ var clientTop = docElem.clientTop || body.clientTop || 0;
+ var clientLeft = docElem.clientLeft || body.clientLeft || 0;
+ var top = box.top + scrollTop - clientTop;
+ var left = box.left + scrollLeft - clientLeft;
+
+ return { top: Math.round(top), left: Math.round(left) };
+}
+
+function getOffsetSum(elem)
+{
+ var top = 0, left = 0;
+ while(elem)
+ {
+ top = top + parseInt(elem.offsetTop);
+ left = left + parseInt(elem.offsetLeft);
+ elem = elem.offsetParent;
+ }
+ return { top: top, left: left };
+}
+
+function getOffset(elem)
+{
+ if (elem.getBoundingClientRect)
+ return getOffsetRect(elem);
+ else
+ return getOffsetSum(elem);
+}
diff --git a/calendar.min.js b/calendar.min.js
index 5ef4b20..878e6e3 100644
--- a/calendar.min.js
+++ b/calendar.min.js
@@ -1 +1 @@
-if(!window.Calendar){window.Calendar={month_names:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],close_label:"Закрыть",weekdays:["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],sunday:6,selectboxes:false,years:{min:-70,max:10},format:"d.m.Y",month_days:[31,28,31,30,31,30,31,31,30,31,30,31],today:new Date(),selected:new Date(),opt:{},data:[],addedListener:false,wrt:function(a){this.data.push(a)},fin:function(){this.wrt(" ");document.getElementById(this.opt.calendar).innerHTML=this.data.join("");this.data=[]},selectDate:function(d,e,a){var c=this.opt.input;var b=c.value.split(/\s+/,2)[1]||"";if(b){b=" "+b}c.value=(this.format=="Y-m-d"?d+"-"+e+"-"+a:a+"."+e+"."+d)+b;this.hideCalendar()},showMonths:function(c,e){var f=this.today.getFullYear();var g=this.today.getMonth();var a=this.selected.getFullYear()==c?this.selected.getMonth():-1;this.wrt("");this.wrt("< ");this.wrt(" "+c+" ");this.wrt(" > ");this.wrt("");for(var b in this.month_names){if(b&&!(b%3)){this.wrt(" ")}var d=(cf||c==f&&b>g?"future":"today"))+(b==a?" selected":"");this.wrt(""+this.month_names[b]+" ")}this.wrt(" ");this.wrt("
");this.fin()},showYears:function(d){var b=d&~15;var f=this.today.getFullYear();var a=this.selected.getFullYear();this.wrt("");this.wrt("");this.wrt(" < ");this.wrt(" "+b+" - "+(b+15)+" ");this.wrt(" > ");this.wrt(" ");this.wrt("");for(var c=0;c<16;c++){if(c&&!(c%4)){this.wrt(" ")}var e=(b+cf?"future":"today"))+(b+c==a?" selected":"");this.wrt(""+(b+c)+" ")}this.wrt(" ");this.wrt("
");this.fin()},makeCalendar:function(k,x){var a=x+1;var g=k;if(a>=12){a=0;g++}var c=x-1;var f=k;if(c<0){c=11;f--}var m=this.today.getFullYear();this.wrt("");this.wrt("< ");if(!this.selectboxes){this.wrt(" "+this.month_names[x]+" ");this.wrt(" "+k+" ")}else{this.wrt(" ");for(var s in this.month_names){this.wrt(""+this.month_names[s]+" ")}this.wrt(" ");this.wrt("");for(var s=m+this.years.min;s"+s+"")}this.wrt(" ")}this.wrt(" > ");this.wrt("");var o=new Date(k,x,1);var y=(o.getDay()+Calendar.sunday)%7;var v=1;var r=0;if(!(k%4)&&((k%100)||!(k%400))){this.month_days[1]=29}else{this.month_days[1]=28}var t=this.month_days[x];var e=this.today.getFullYear();var u=(k-e)||(x-this.today.getMonth());var z=k==this.selected.getFullYear()&&x==this.selected.getMonth()?this.selected.getDate():-1;for(var s=0;s<=5;s++){if(h>=t){break}this.wrt("");for(var q=0;q<7;q++){if(v>t){r=0}else{if(q>=y&&!r){r=1}}if(r){var h=v,p=x+1;if(h<10){h="0"+h}if(p<10){p="0"+p}var n="";var l=u||(v-this.today.getDate());if(l<0){n=" past"}else{if(!l){n=" today"}else{n=" future"}}if(v==z){n+=" selected"}n+=" "+this.weekdays[q].toLowerCase();this.wrt(""+h+" ");v++}else{this.wrt(" ")}}this.wrt(" ")}this.wrt("
");this.fin()},showCalendar:function(){var b=this.opt.input;var h=document.getElementById(this.opt.calendar);var g=getOffset(b);var e=b.clientWidth||b.offsetWidth;var a=b.clientHeight||b.offsetHeight;h.style.left=(g.left-1)+"px";h.style.top=(g.top+a-1)+"px";this.selected=new Date();var d=b.value.replace(/\s+.*$/,"");if(d){var c=false;var f=d.split("-");if(f.length==3){f[1]--;c=new Date(f[0],f[1],f[2])}else{if(f.length==1){f=d.split(".");if(f.length==3){f[1]--;c=new Date(f[2],f[1],f[0])}}}if(c&&!isNaN(c.getFullYear())){this.selected=c}}this.makeCalendar(this.selected.getFullYear(),this.selected.getMonth());document.getElementById(this.opt.calendar).style.display="block"},hideCalendar:function(){document.getElementById(this.opt.calendar).style.display="none"},set:function(a){if(typeof a=="string"){a=document.getElementById(a)}if(!a){return}if(!Calendar.opt.calendar||!document.getElementById(Calendar.opt.calendar)){Calendar.init()}addListener(a,"focus",function(b){Calendar.opt.input=this;Calendar.showCalendar()})},init:function(){if(!this.opt.calendar||!document.getElementById(this.opt.calendar)){var a=document.createElement("div");if(!this.opt.calendar){this.opt.calendar="calender_div_"+Math.round(Math.random()*100)}a.setAttribute("id",this.opt.calendar);a.className="calendar-box";addListener(a,"mousedown",function(b){b=b||window.event;if(b.stopPropagation){b.stopPropagation()}else{b.cancelBubble=true}return true});document.getElementsByTagName("body")[0].insertBefore(a,document.getElementsByTagName("body")[0].firstChild);if(!Calendar.addedListener){addListener(document,"mousedown",function(){Calendar.hideCalendar()});Calendar.addedListener=true}}}}};
\ No newline at end of file
+(function(global,factory){if(typeof define==="function"&&define.amd){define(["exports"],factory)}else if(typeof exports!=="undefined"){factory(exports)}else{var mod={exports:{}};factory(mod.exports);global.calendar=mod.exports}})(this,function(exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var _createClass=function(){function defineProperties(target,props){for(var i=0;i"+this.close_label+"";Calendar.box.innerHTML=html}},{key:"isVisible",value:function isVisible(){return Calendar.instance==this&&Calendar.box.style.display=="block"}},{key:"selectDate",value:function selectDate(year,month,day){var i=this.input;var t=i.value.split(/\s+/,2)[1]||"";if(t)t=" "+t;if(this.callback){var c=this.callback;t=year+"-"+month+"-"+day+t;c(new Date(t))}else{t=(this.format=="Y-m-d"?year+"-"+month+"-"+day:day+"."+month+"."+year)+t;i.value=t;if("Event"in window){var evt=document.createEvent("Event");evt.initEvent("change",true,true);i.dispatchEvent(evt)}else i.fireEvent("onchange")}Calendar.instance.hideCalendar()}},{key:"showMonths",value:function showMonths(year){var cur_y=this.today.getFullYear();var cur_m=this.today.getMonth();var sel_m=this.selected.getFullYear()==year?this.selected.getMonth():-1;var html="";html+="";html+=" ";html+=" "+year+" ";html+=" ";html+="";for(var i in this.month_names){if(i&&!(i%3))html+=" ";var class_name=(yearcur_y||year==cur_y&&i>cur_m?"future":"today")+(i==sel_m?" selected":"");html+=""+this.month_names[i]+" "}html+=" ";html+="
";this.setHTML(html)}},{key:"showYears",value:function showYears(year){var beg=year&~15;var cur_y=this.today.getFullYear();var sel_y=this.selected.getFullYear();var html="";html+="";html+="";html+=" ";html+=" "+beg+" - "+(beg+15)+" ";html+=" ";html+=" ";html+="";for(var i=0;i<16;i++){if(i&&!(i%4))html+=" ";var class_name=(beg+icur_y?"future":"today")+(beg+i==sel_y?" selected":"");html+=""+(beg+i)+" "}html+=" ";html+="
";this.setHTML(html)}},{key:"makeCalendar",value:function makeCalendar(year,month){var next_month=month+1;var next_month_year=year;if(next_month>=12){next_month=0;next_month_year++}var previous_month=month-1;var previous_month_year=year;if(previous_month<0){previous_month=11;previous_month_year--}var current_year=this.today.getFullYear();var html="";html+="";html+=" ";if(!this.selectboxes){html+=" "+this.month_names[month]+" ";html+=" "+year+" "}else{html+=" ";for(var i in this.month_names){html+=""+this.month_names[i]+" "}html+=" ";html+="";for(var i=current_year+this.years.min;i"+i+""}html+=" "}html+=" ";html+="";var first_day=new Date(year,month,1);var start_day=(first_day.getDay()+this.sunday)%7;var d=1;var flag=0;if(!(year%4)&&(year%100||!(year%400)))this.month_days[1]=29;else this.month_days[1]=28;var days_in_this_month=this.month_days[month];var yea=this.today.getFullYear();var all_diff=year-yea||month-this.today.getMonth();var sel_day=year==this.selected.getFullYear()&&month==this.selected.getMonth()?this.selected.getDate():-1;for(var i=0;i<=5;i++){if(w>=days_in_this_month)break;html+="";for(var j=0;j<7;j++){if(d>days_in_this_month)flag=0;else if(j>=start_day&&!flag)flag=1;if(flag){var w=d,mon=month+1;if(w<10)w="0"+w;if(mon<10)mon="0"+mon;var class_name="";var diff=all_diff||d-this.today.getDate();if(diff<0)class_name=" past";else if(!diff)class_name=" today";else class_name=" future";if(d==sel_day)class_name+=" selected";class_name+=" "+this.weekdays[j].toLowerCase();html+=""+d+" ";d++}else html+=" "}html+=" "}html+="
";this.setHTML(html)}},{key:"showCalendar",value:function showCalendar(){Calendar.instance=this;var input=this.input;this.selected=new Date;var date_in_input=input.value.replace(/\s+.*$/,"");if(date_in_input){var selected_date=false;var date_parts=date_in_input.split("-");if(date_parts.length==3){date_parts[1]--;selected_date=new Date(date_parts[0],date_parts[1],date_parts[2])}else if(date_parts.length==1){date_parts=date_in_input.split(".");if(date_parts.length==3){date_parts[1]--;selected_date=new Date(date_parts[2],date_parts[1],date_parts[0])}}if(selected_date&&!isNaN(selected_date.getFullYear())){this.selected=selected_date}}if(this.start=="years")this.showYears(this.selected.getFullYear());else if(this.start=="months")this.showMonths(this.selected.getFullYear());else this.makeCalendar(this.selected.getFullYear(),this.selected.getMonth());var div=Calendar.box;var xy=getOffset(input);var height=input.clientHeight||input.offsetHeight;div.style.display="block";div.style.left=xy.left-1+"px";if(div.offsetHeight+xy.top+height-1>=(document.documentElement.clientHeight||document.body.clientHeight)&&xy.top-div.offsetHeight>=0)div.style.top=xy.top-div.offsetHeight+"px";else div.style.top=xy.top+height-1+"px"}},{key:"hideCalendar",value:function hideCalendar(){Calendar.box.style.display="none"}}],[{key:"set",value:function set(input_or_id,options){if(typeof input_or_id=="string")input_or_id=document.getElementById(input_or_id);if(!input_or_id)return;options=options||{};var instance=new Calendar;for(var i in Calendar.defaultOptions){instance[i]=options[i]||Calendar.defaultOptions[i]}instance.input=input_or_id;Calendar.init();input_or_id.addEventListener("focus",function(ev){instance.showCalendar()});return instance}},{key:"init",value:function init(){if(!Calendar.box||!Calendar.box.parentNode){var div=document.createElement("div");if(!Calendar.box)Calendar.box=div;div.className="calendar-box";div.addEventListener("mousedown",function(ev){ev=ev||window.event;if(ev.stopPropagation)ev.stopPropagation();else ev.cancelBubble=true;return true});document.getElementsByTagName("body")[0].insertBefore(div,document.getElementsByTagName("body")[0].firstChild);if(!Calendar.addedListener){document.addEventListener("mousedown",function(){Calendar.instance&&Calendar.instance.hideCalendar()});Calendar.addedListener=true}}}}]);return Calendar}();Calendar.defaultOptions={month_names:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],close_label:"Закрыть",weekdays:["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],sunday:6,selectboxes:false,years:{min:-70,max:10},format:"d.m.Y",month_days:[31,28,31,30,31,30,31,31,30,31,30,31],today:new Date,callback:null,start:"days"};Calendar.instance=null;Calendar.box=null;Calendar.addedListener=false;window.Calendar=Calendar;function getOffsetRect(elem){var box=elem.getBoundingClientRect();var body=document.body;var docElem=document.documentElement;var scrollTop=window.pageYOffset||docElem.scrollTop||body.scrollTop;var scrollLeft=window.pageXOffset||docElem.scrollLeft||body.scrollLeft;var clientTop=docElem.clientTop||body.clientTop||0;var clientLeft=docElem.clientLeft||body.clientLeft||0;var top=box.top+scrollTop-clientTop;var left=box.left+scrollLeft-clientLeft;return{top:Math.round(top),left:Math.round(left)}}function getOffsetSum(elem){var top=0,left=0;while(elem){top=top+parseInt(elem.offsetTop);left=left+parseInt(elem.offsetLeft);elem=elem.offsetParent}return{top:top,left:left}}function getOffset(elem){if(elem.getBoundingClientRect)return getOffsetRect(elem);else return getOffsetSum(elem)}});
diff --git a/calendar.util.js b/calendar.util.js
deleted file mode 100644
index 389c820..0000000
--- a/calendar.util.js
+++ /dev/null
@@ -1,47 +0,0 @@
-(function() {
-
-// UTILITY FUNCTIONS
-window.addListener = (function() {
- return window.addEventListener
- ? function(el, type, fn) { el.addEventListener(type, fn, false); }
- : function(el, type, fn) { el.attachEvent('on'+type, fn); };
-})();
-
-var getOffsetRect = function(elem)
-{
- var box = elem.getBoundingClientRect();
-
- var body = document.body;
- var docElem = document.documentElement;
-
- var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
- var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
- var clientTop = docElem.clientTop || body.clientTop || 0;
- var clientLeft = docElem.clientLeft || body.clientLeft || 0;
- var top = box.top + scrollTop - clientTop;
- var left = box.left + scrollLeft - clientLeft;
-
- return { top: Math.round(top), left: Math.round(left) };
-};
-
-var getOffsetSum = function(elem)
-{
- var top = 0, left = 0;
- while(elem)
- {
- top = top + parseInt(elem.offsetTop);
- left = left + parseInt(elem.offsetLeft);
- elem = elem.offsetParent;
- }
- return { top: top, left: left };
-};
-
-window.getOffset = function(elem)
-{
- if (elem.getBoundingClientRect)
- return getOffsetRect(elem);
- else
- return getOffsetSum(elem);
-};
-
-})();
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b553076
--- /dev/null
+++ b/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "calendarjs",
+ "author": {
+ "name": "Vitaliy Filippov",
+ "email": "vitalif@yourcmc.ru",
+ "url": "http://yourcmc.ru/wiki/"
+ },
+ "description": "Yet another date picker",
+ "dependencies": {},
+ "devDependencies": {
+ "babel-cli": "^6.26.0",
+ "babel-core": "^6.26.0",
+ "babel-preset-env": "^1.6.1",
+ "babel-preset-react": "^6.24.1",
+ "babel-preset-stage-1": "^6.24.1",
+ "uglify-js": "^3.3.15"
+ },
+ "scripts": {
+ "compile": "node_modules/.bin/babel calendar.js | node_modules/.bin/uglifyjs > calendar.min.js"
+ }
+}
diff --git a/test.htm b/test.htm
index 3649be6..64fffb7 100644
--- a/test.htm
+++ b/test.htm
@@ -1,8 +1,7 @@
-
-
+