bootstrap_calendar.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. bootstrap_calendar by bic.cat (http://bic.cat) & xero (http://xero.nu)
  3. https://github.com/xero/bootstrap_calendar
  4. released open source under the Apache License
  5. */
  6. $.fn.calendar = function(options) {
  7. var args = $.extend({}, $.fn.calendar.defaults, options);
  8. this.each(function(){
  9. var calendar;
  10. var lblDaysMonth;
  11. var lblTextMonth = $('<div class="visualmonthyear"></div>');
  12. var calendar_id = "cal_" + Math.floor(Math.random()*99999).toString(36);
  13. var events = args.events;
  14. var days;
  15. if ( typeof args.days != "undefined" )
  16. days = args.days;
  17. else
  18. days = ["S", "M", "T", "W", "T", "F", "S"];
  19. var months;
  20. if ( typeof args.months != "undefined" )
  21. months = args.months;
  22. else
  23. months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  24. var show_days;
  25. if ( typeof args.show_days != "undefined" )
  26. show_days = args.show_days;
  27. else
  28. show_days = true;
  29. var popover_options;
  30. if ( args.popover_options != "undefined" )
  31. popover_options = args.popover_options;
  32. else
  33. popover_options = {placement: 'top'};
  34. var tooltip_options;
  35. if ( typeof args.tooltip_options != "undefined" )
  36. tooltip_options = args.tooltip_options;
  37. else
  38. tooltip_options = {placement: 'top'};
  39. var req_ajax;
  40. if ( typeof args.req_ajax != "undefined" )
  41. req_ajax = args.req_ajax;
  42. else
  43. req_ajax = false;
  44. var elem = $(this);
  45. showCalendar();
  46. /*** functions ***/
  47. //display
  48. function showCalendar(){
  49. //days of month label
  50. lblDaysMonth = $('<table class="daysmonth table table">');
  51. list_week();
  52. //date calculation object
  53. var dateObj = new Date();
  54. //check for date input
  55. var dateText = elem.val();
  56. if (dateText!= ""){
  57. if (validateDate(dateText)){
  58. var dateTextArray = dateText.split("/");
  59. //two digit years
  60. if(dateTextArray[2].length == 2){
  61. if (dateTextArray[2].charAt(0)=="0"){
  62. dateTextArray[2] = dateTextArray[2].substring(1);
  63. }
  64. dateTextArray[2] = parseInt(dateTextArray[2]);
  65. if (dateTextArray[2] < 50)
  66. dateTextArray[2] += 2000;
  67. }
  68. dateObj = new Date(dateTextArray[2], dateTextArray[1]-1, dateTextArray[0])
  69. }
  70. }
  71. //current month & year
  72. var month = dateObj.getMonth();
  73. var year = dateObj.getFullYear();
  74. showDaysOfMonth(month, year);
  75. //next/previous month controls
  76. var btnNextMonth = $('<td><i class="fa fa-arrow-right"></i></td>');
  77. btnNextMonth.click(function(e){
  78. e.stopPropagation();
  79. e.preventDefault();
  80. month = (month + 1) % 12;
  81. if (month==0)
  82. year++;
  83. change_month(month, year);
  84. });
  85. var btnPrevMonth = $('<td><i class="fa fa-arrow-left"></i></td>');
  86. btnPrevMonth.click(function(e){
  87. e.stopPropagation();
  88. e.preventDefault();
  89. month = (month - 1);
  90. if (month==-1){
  91. year--;
  92. month = 11;
  93. }
  94. change_month(month, year);
  95. });
  96. $('.icon-arrow-left').css('cursor', 'pointer');
  97. $('.icon-arrow-right').css('cursor', 'pointer');
  98. //current year & month label
  99. var lblDate = $('<table class="table header"><tr></tr></table>');
  100. var lblDateControl = $('<td colspan=5 class="year span6"></td>');
  101. lblDate.append(btnPrevMonth);
  102. lblDate.append(lblDateControl);
  103. lblDate.append(btnNextMonth);
  104. lblDateControl.append(lblTextMonth);
  105. calendar = $('<div class="calendar" id="' +calendar_id +'" ></div>');
  106. calendar.prepend(lblDate);
  107. //calendar.append(lblWeek);
  108. //lblDaysMonth.prepend(lblWeek);
  109. calendar.append(lblDaysMonth);
  110. //render calendar
  111. elem.append(calendar);
  112. check_events(month, year);
  113. }
  114. function change_month(month, year){
  115. lblDaysMonth.empty();
  116. list_week();
  117. showDaysOfMonth(month, year);
  118. check_events(month, year);
  119. }
  120. //week
  121. function list_week(){
  122. if ( show_days != false ){
  123. var lblWeek = $('<tr class="week_days" >');
  124. var insertCode = '';
  125. $(days).each(function(key, value){
  126. insertCode += '<td';
  127. if (key==0){
  128. insertCode += ' class="first"';
  129. }
  130. if (key==6){
  131. insertCode += ' class="last"';
  132. }
  133. insertCode += ">" + value + '</td>';
  134. });
  135. insertCode += '</tr>';
  136. lblWeek.append(insertCode);
  137. lblDaysMonth.append(lblWeek);
  138. }
  139. }
  140. function showDaysOfMonth(month, year){
  141. //console.log("show (month, year): ", month, " ", year)
  142. lblTextMonth.text(months[month] + " " + year);
  143. //days of month
  144. var day_counter = 1;
  145. var firstDay = calculateWeekday(1, month, year);
  146. var lastDaymonth = lastDay(month,year);
  147. var next_month = month + 1;
  148. var lblDaysMonth_string = "";
  149. //render first row of week
  150. for (var i=0; i<7; i++){
  151. if (i < firstDay){
  152. var dayCode = "";
  153. if (i == 0)
  154. dayCode += "<tr>";
  155. //if the day of the week is less than the number of the first day of the week do not put anything in the cell
  156. dayCode += '<td class="invalid';
  157. if (i == 0)
  158. dayCode += " first";
  159. dayCode += '"></td>';
  160. } else {
  161. var dayCode = "";
  162. if (i == 0)
  163. dayCode += '<tr>';
  164. dayCode += '<td id="' + calendar_id + '_' + day_counter + "_" + next_month + "_" + year + '" ';
  165. if (i == 0)
  166. dayCode += ' class="first"';
  167. if (i == 6)
  168. dayCode += ' class="last"';
  169. dayCode += '><a>' + day_counter + '</a></span>';
  170. if (i == 6)
  171. dayCode += '</tr>';
  172. day_counter++;
  173. }
  174. lblDaysMonth_string += dayCode
  175. }
  176. //rest of month
  177. var currentWeekDay = 1;
  178. while (day_counter <= lastDaymonth){
  179. var dayCode = "";
  180. if (currentWeekDay % 7 == 1)
  181. dayCode += "<tr>";
  182. dayCode += '<td id="' + calendar_id + '_' + day_counter + "_" + next_month + "_" + year + '" ';
  183. //start of week
  184. if (currentWeekDay % 7 == 1)
  185. dayCode += ' class="first"';
  186. //end of week
  187. if (currentWeekDay % 7 == 0)
  188. dayCode += ' class="last"';
  189. dayCode += '><a>' + day_counter + '</a></td>';
  190. if (currentWeekDay % 7 == 0)
  191. dayCode += "</tr>";
  192. day_counter++;
  193. currentWeekDay++;
  194. lblDaysMonth_string += dayCode
  195. }
  196. //fill empty days
  197. currentWeekDay--;
  198. if (currentWeekDay%7!=0){
  199. dayCode = "";
  200. for (var i=(currentWeekDay%7)+1; i<=7; i++){
  201. var dayCode = "";
  202. dayCode += '<td class="invalid';
  203. if (i==7)
  204. dayCode += ' last'
  205. dayCode += '"></td>';
  206. if (i==7)
  207. dayCode += '</tr>'
  208. lblDaysMonth_string += dayCode
  209. }
  210. }
  211. lblDaysMonth.append( lblDaysMonth_string );
  212. }
  213. //calcuation number of days in week
  214. function calculateWeekday(day,month,year){
  215. var dateObj = new Date(year, month, day);
  216. var numDay = dateObj.getDay();
  217. return numDay;
  218. }
  219. //date validation
  220. function checkdate (m, d, y) {
  221. // function by http://kevin.vanzonneveld.net
  222. // extracted from the manual phpjs.org libraries at http://www.desarrolloweb.com/manuales/manual-librerias-phpjs.html
  223. return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate();
  224. }
  225. //calculate last day of month for a given year
  226. function lastDay(month,year){
  227. var last_day=28;
  228. while (checkdate(month+1,last_day + 1,year)){
  229. last_day++;
  230. }
  231. return last_day;
  232. }
  233. function validateDate(date){
  234. var dateArray = date.split("/");
  235. if (dateArray.length!=3)
  236. return false;
  237. return checkdate(dateArray[1], dateArray[0], dateArray[2]);
  238. }
  239. function check_events(month, year){
  240. if (req_ajax != false){
  241. $.ajax({
  242. type: req_ajax.type,
  243. url: req_ajax.url,
  244. data: { month: month + 1, year: year },
  245. dataType: 'json'
  246. }).done(function( data ) {
  247. events = [];
  248. $.each(data, function(k,v){
  249. events.push(data[k]);
  250. });
  251. markEvents(month, year);
  252. });
  253. } else {
  254. markEvents(month, year);
  255. }
  256. }
  257. function markEvents(month, year){
  258. var t_month = month + 1;
  259. for(var i=0; i< events.length; i++) {
  260. if ( events[i][0].split('/')[1] == t_month && events[i][0].split('/')[2] == year ){
  261. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") ).addClass('event');
  262. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('data-original-title', events[i][1]);
  263. //bg
  264. if ( events[i][3] ){
  265. var e = $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") );
  266. e.append('<span></span>').find('span').css('background', events[i][3]);
  267. }
  268. //link
  269. if ( events[i][2] == '' || events[i][2] == '#' ){
  270. if ( events[i][4] != '' ){
  271. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('data-trigger', 'manual');
  272. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).addClass('manual_popover');
  273. } else {
  274. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('href', 'javascript:false;');
  275. }
  276. } else {
  277. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('href', events[i][2]);
  278. }
  279. //tooltip vs popover
  280. if ( events[i][4] ){
  281. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") ).addClass('event_popover');
  282. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('rel', 'popover');
  283. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('data-content', events[i][4]);
  284. } else {
  285. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") ).addClass('event_tooltip');
  286. $('#' + calendar_id + '_' + events[i][0].replace(/\//g, "_") + ' a' ).attr('rel', 'tooltip');
  287. }
  288. }
  289. }
  290. $('#' + calendar_id + ' ' + '.event_tooltip a').tooltip(tooltip_options);
  291. $('#' + calendar_id + ' ' + '.event_popover a').popover(popover_options);
  292. $('.manual_popover').click( function(){
  293. $(this).popover('toggle');
  294. } );
  295. }
  296. /*** --functions-- ***/
  297. });
  298. return this;
  299. };