datepicker.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /* =========================================================
  2. * bootstrap-datepicker.js
  3. * original by Stefan Petre
  4. * tweaked by gus
  5. * ========================================================= */
  6. !function( $ ) {
  7. // Picker object
  8. var Datepicker = function(element, options){
  9. this.element = $(element);
  10. this.days = options.days||["sun","mon","tue","wed","thu","fri","sat"];
  11. this.months = options.months||["january","february","march","april","may","june","july","august","september","october","november","december"];
  12. this.format = options.format||$(element).data("datepicker-format")||'mm/dd/yyyy hh:ii:ss';
  13. this.noDefault = options.noDefault||$(element).data("datepicker-nodefault")||false;
  14. this.picker = $(DPGlobal.template).appendTo("body").on({
  15. mousedown: $.proxy(this.click, this)
  16. });
  17. this.weekStart = options.weekStart||0;
  18. this.weekEnd = this.weekStart == 0 ? 6 : this.weekStart - 1;
  19. this.head();
  20. if (!this.element.prop("value")&&!this.noDefault) {
  21. this.element.prop("value",DPGlobal.formatDate(new Date(), this.format));
  22. }
  23. this.update();
  24. this.element.on({
  25. focus: $.proxy(this.show, this),
  26. click: $.proxy(this.show, this),
  27. keyup: $.proxy(this.keyup, this)
  28. });
  29. };
  30. Datepicker.prototype = {
  31. constructor: Datepicker,
  32. show: function(e) {
  33. this.update();
  34. this.picker.show();
  35. this.height = this.element.outerHeight();
  36. this.place();
  37. $(window).on("resize", $.proxy(this.place, this));
  38. if (e) {
  39. e.stopPropagation();
  40. e.preventDefault();
  41. }
  42. this.element.trigger({
  43. type: "show",
  44. date: this.date
  45. });
  46. $("body").on("click.bs-sc-datepicker", $.proxy(this.hide, this));
  47. },
  48. hide: function(e){
  49. if (e && $(e.target).parents(".bs-sc-datepicker").length) return false;
  50. this.picker.hide();
  51. $(window).off("resize", this.place);
  52. $("body").off("click.bs-sc-datepicker");
  53. },
  54. setValue: function(val) {
  55. if (typeof(val)!=='undefined') {
  56. this.date = val;
  57. }
  58. var formated = DPGlobal.formatDate(this.date, this.format);
  59. this.element.prop("value", formated);
  60. },
  61. place: function(){
  62. var offset = this.element.offset();
  63. this.picker.css({
  64. top: offset.top + this.height,
  65. left: offset.left
  66. });
  67. },
  68. update: function(){
  69. this.date = DPGlobal.parseDate(this.element.prop("value"), this.format);
  70. this.viewDate = new Date(this.date);
  71. this.fill();
  72. },
  73. keyup: function() {
  74. this.date = DPGlobal.parseDate(this.element.prop("value"), this.format);
  75. this.element.trigger({
  76. type: 'changeDate',
  77. date: this.date
  78. });
  79. },
  80. head: function(){
  81. var dowCnt = this.weekStart;
  82. var html = '<tr>';
  83. while (dowCnt < this.weekStart + 7) {
  84. html += '<th class="dow">'+this.days[(dowCnt++)%7]+'</th>';
  85. }
  86. html += '</tr>';
  87. this.picker.find(".datepicker-days thead").append(html);
  88. },
  89. fill: function() {
  90. var d = new Date(this.viewDate),
  91. year = d.getFullYear(),
  92. month = d.getMonth(),
  93. day = d.getDay();
  94. currentDate = new Date(this.date.getFullYear(), this.date.getMonth(), this.date.getDate(), 0, 0, 0, 0);
  95. currentDate = currentDate.valueOf();
  96. if (month > 0) {
  97. var prevMonth = new Date(year, month-1, 1,0,0,0,0);
  98. var prevMonthNr = prevMonth.getMonth();
  99. } else {
  100. var prevMonth = new Date(year-1, 11, 1, 0, 0, 0, 0);
  101. var prevMonthNr = prevMonth.getMonth();
  102. }
  103. if (month < 11) {
  104. var nextMonthNr = month + 1;
  105. } else {
  106. var nextMonthNr = 0;
  107. }
  108. var beginMonth = new Date(year, month, 1,0,0,0,0);
  109. startAtWeekday = beginMonth.getDay() - this.weekStart;
  110. if (startAtWeekday < 0) {
  111. prevMonthDays = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
  112. startPrevMonthAtDate = prevMonthDays - (6 + startAtWeekday);
  113. } else if (startAtWeekday > 0) {
  114. prevMonthDays = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
  115. startPrevMonthAtDate = prevMonthDays - startAtWeekday + 1;
  116. } else {
  117. startPrevMonthAtDate = 1;
  118. prevMonth.setMonth(month);
  119. }
  120. prevMonth.setDate(startPrevMonthAtDate);
  121. d = prevMonth;
  122. html = []; allDone = false; x=0;
  123. while(!allDone) {
  124. if (d.getDay() == this.weekStart) {
  125. html.push('<tr>');
  126. }
  127. clsName = '';
  128. if (d.getMonth() == prevMonthNr) {
  129. clsName += ' old';
  130. } else if (d.getMonth() == nextMonthNr) {
  131. clsName += ' new';
  132. }
  133. if (d.valueOf() == currentDate) {
  134. clsName += ' active';
  135. }
  136. clsName += ' ' + d.valueOf();
  137. html.push('<td class="day'+clsName+'">' + d.getDate() + '</td>');
  138. if (d.getDay() == this.weekEnd) {
  139. html.push('</tr>');
  140. }
  141. d.setDate(d.getDate()+1);
  142. allDone = ((d.getDay() == this.weekStart) && (d.getMonth() == nextMonthNr));
  143. x++;
  144. if (x > 99) {
  145. console.log("safety");
  146. return;
  147. }
  148. }
  149. this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
  150. headerStr = this.months[this.viewDate.getMonth()] + ' ' + this.viewDate.getFullYear();
  151. this.picker.find('.datepicker-days thead .monthname').html(headerStr);
  152. },
  153. click: function(e) {
  154. e.stopPropagation();
  155. e.preventDefault();
  156. var target = $(e.target).closest('span, td, th');
  157. if (target.length == 1) {
  158. switch(target[0].nodeName.toLowerCase()) {
  159. case 'th':
  160. switch(target[0].className) {
  161. case 'prev':
  162. if (this.viewDate.getMonth() > 0) {
  163. this.viewDate.setMonth(this.viewDate.getMonth() - 1);
  164. } else {
  165. this.viewDate.setFullYear(this.viewDate.getFullYear() - 1);
  166. this.viewDate.setMonth(11);
  167. }
  168. break;
  169. case 'next':
  170. if (this.viewDate.getMonth() < 11) {
  171. this.viewDate.setMonth(this.viewDate.getMonth() + 1);
  172. } else {
  173. this.viewDate.setFullYear(this.viewDate.getFullYear() + 1);
  174. this.viewDate.setMonth(0);
  175. }
  176. break;
  177. }
  178. this.fill();
  179. break;
  180. case 'td':
  181. if (target.is('.day')){
  182. if (target.is('.old')) {
  183. return;
  184. } else if (target.is('.new')) {
  185. return;
  186. }
  187. var day = parseInt(target.text(), 10)||1;
  188. var month = this.viewDate.getMonth();
  189. var year = this.viewDate.getFullYear();
  190. this.date = new Date(year, month, day,this.date.getHours(),this.date.getMinutes(),this.date.getSeconds(),0);
  191. this.viewDate = new Date(year, month, day,0,0,0,0);
  192. this.fill();
  193. this.setValue();
  194. this.element.trigger({
  195. type: 'changeDate',
  196. date: this.date
  197. });
  198. this.hide();
  199. }
  200. break;
  201. }
  202. }
  203. return false;
  204. },
  205. };
  206. $.fn.datepicker = function ( option ) {
  207. return this.each(function () {
  208. var $this = $(this),
  209. data = $this.data('datepicker'),
  210. options = typeof option == 'object' && option;
  211. if (!data) {
  212. $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
  213. }
  214. if (typeof option == 'string') data[option]();
  215. });
  216. };
  217. $.fn.datepicker.defaults = {
  218. };
  219. $.fn.datepicker.Constructor = Datepicker;
  220. var DPGlobal = {
  221. isLeapYear: function (year) {
  222. return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
  223. },
  224. getDaysInMonth: function (year, month) {
  225. return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
  226. },
  227. parseDate: function(dateStr, format) { //convert str into date
  228. dateStr = dateStr.replace(/:/g, '/');
  229. dateStr = dateStr.replace(/ /g, '/');
  230. strParts = dateStr.split('/');
  231. format = format.replace(/:/g, '/');
  232. format = format.replace(/ /g, '/');
  233. formatParts = format.split('/');
  234. date = new Date(),
  235. date.setHours(0); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0);
  236. for (var key in formatParts) {
  237. if (typeof strParts[key] != 'undefined') {
  238. val = strParts[key];
  239. switch(formatParts[key]) {
  240. case 'dd':
  241. case 'd':
  242. date.setDate(val);
  243. break;
  244. case 'mm':
  245. case 'm':
  246. date.setMonth(val - 1);
  247. break;
  248. case 'yy':
  249. date.setFullYear(2000 + val);
  250. break;
  251. case 'yyyy':
  252. date.setFullYear(val);
  253. break;
  254. case 'hh':
  255. case 'h':
  256. date.setHours(val);
  257. break;
  258. case 'ii':
  259. case 'i':
  260. date.setMinutes(val);
  261. break;
  262. case 'ss':
  263. case 's':
  264. date.setSeconds(val);
  265. break;
  266. }
  267. }
  268. }
  269. return date;
  270. },
  271. formatDate: function(date, format){ // build a formatted string
  272. var templateParts = {
  273. dd: (date.getDate() < 10 ? '0' : '') + date.getDate(),
  274. d: date.getDate(),
  275. mm: ((date.getMonth() + 1) < 10 ? '0' : '') + (date.getMonth() + 1),
  276. m: date.getMonth() + 1,
  277. yyyy: date.getFullYear(),
  278. yy: date.getFullYear().toString().substring(2),
  279. hh: (date.getHours() < 10 ? '0' : '') + date.getHours(),
  280. h: date.getHours(),
  281. ii: (date.getMinutes() < 10 ? '0' : '') + date.getMinutes(),
  282. i: date.getMinutes(),
  283. ss: (date.getSeconds() < 10 ? '0' : '') + date.getSeconds(),
  284. s: date.getSeconds()
  285. };
  286. var dateStr = format;
  287. for (var key in templateParts) {
  288. val = templateParts[key];
  289. dateStr = dateStr.replace(key, val);
  290. }
  291. return dateStr;
  292. },
  293. headTemplate: '<thead>'+
  294. '<tr>'+
  295. '<th class="prev"><i>&larr;</i></th>'+
  296. '<th colspan="5" class="monthname"></th>'+
  297. '<th class="next"><i>&rarr;</i></th>'+
  298. '</tr>'+
  299. '</thead>',
  300. contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
  301. };
  302. DPGlobal.template = '<div class="bs-sc-datepicker dropdown-menu">'+
  303. '<div class="datepicker-days">'+
  304. '<table class=" table-condensed">'+
  305. DPGlobal.headTemplate+
  306. '<tbody></tbody>'+
  307. '</table>'+
  308. '</div>'+
  309. '</div>';
  310. }( window.jQuery );
  311. $(function() {
  312. $("input[data-datepicker-format]").datepicker({
  313. weekStart: 1,
  314. days: ["zo","ma","di","wo","do","vr","za"],
  315. months: ["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"]
  316. });
  317. });