upstream jqueryhcal
authorDobrica Pavlinusic <dpavlin@rot13.org>
Sat, 14 Nov 2009 14:23:31 +0000 (15:23 +0100)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Sat, 14 Nov 2009 14:23:31 +0000 (15:23 +0100)
http://thebitterpill.com/07-2007/a-jquery-hcal-parser/

www/js/jqueryhcal/jqueryhcal.css [new file with mode: 0644]
www/js/jqueryhcal/jqueryhcal.js [new file with mode: 0644]

diff --git a/www/js/jqueryhcal/jqueryhcal.css b/www/js/jqueryhcal/jqueryhcal.css
new file mode 100644 (file)
index 0000000..d7d6d22
--- /dev/null
@@ -0,0 +1,42 @@
+.calTable{\r
+       border:1px solid #ccc; border-collapse:collapse; float:left; width:172px; \r
+       margin:0 10px 10px 0;\r
+       background:#fff url(/media/img/datepicker/gradient-e5e5e5-ffffff.gif) repeat-x 0 -20px;\r
+       text-align:center;}\r
+.calTable thead th {font-size:9px; color:#333; padding:0; \r
+       line-height:1.4em}}\r
+.calTable .calHeader {\r
+        text-transform:uppercase;\r
+        letter-spacing:1px;\r
+        }\r
+.calTable .abbrevDays {text-transform:lowercase}\r
+\r
+.calTable td {border:1px solid #ccc; vertical-align:top; padding:2px 3px 3px}\r
+\r
+.outOfRange, .notInMonth {background:#eee; opacity:.5}\r
+.out-of-range {color:#ccc}     \r
+.longDays, .calTable td .event {display:none}\r
+  .calTable td:hover .event {display:block; \r
+               position:absolute;\r
+               z-index:1000; \r
+               background:#ffc; \r
+               border:1px solid #333; \r
+               width:170px;\r
+               font-size:10px; \r
+               padding:2px 4px;\r
+               text-align:left;\r
+       }\r
+.calDayToday {\r
+  background-color:#e4e3de;\r
+}\r
+.weekend {color:#900}\r
+.calEventDay {background:#ff9}\r
+.calDayLabel {font-size:9px; }\r
+       \r
+#jhCalendar:after { /* clear floats */\r
+    content: "."; \r
+    display: block; \r
+    height: 0; \r
+    clear: both; \r
+    visibility: hidden;\r
+}
\ No newline at end of file
diff --git a/www/js/jqueryhcal/jqueryhcal.js b/www/js/jqueryhcal/jqueryhcal.js
new file mode 100644 (file)
index 0000000..589112b
--- /dev/null
@@ -0,0 +1,231 @@
+/* CONFIG/ GLOBALS */
+
+var dayNames = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
+var dayAbbrevs = new Array("S", "M", "T", "W", "T", "F", "S");
+var monthNames = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
+var monthLength = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
+
+var firstDayOfWeek = 0;
+var DEBUG = 1;
+var globalDateHash = new Object();
+
+/************************************** helper functions ************************/
+function debug(message) {
+  if (DEBUG)
+    alert(message);
+}
+
+/* Trims the starting zero off of a number to ensure JS gets a regular int, not an octal */
+function trimStartingZero(number) {
+       number = (number + '');
+       if (number.substring(0,1) == "0") {
+               number = number.substring(1,number.length)
+       }
+       return parseInt(number);
+}
+/* parses datetime */
+function parseDT(dt) {
+       var dtText;
+       var result;
+       if ($(dt).attr('title')) {
+               dtText = $(dt).attr('title');
+       } else {
+               dtText = $(dt).children([0]).html();
+       }
+       if (dtText != null) {
+               result = dtText.match( /^(\d{4})(\d{2})(\d{2})/ );
+       }
+       if (result == null) {
+       //      debug("didn't recognize DT: " + dtText);
+               return
+       }
+       return [result[1], result[2], result[3]];
+}
+
+// TODO deal with leap year
+getMonthLength = function(year, month) {
+  return monthLength[month - 1];
+}
+/*********************************************************************
+**     First: check for abilities and readiness 
+**     Second: find events (.vevent), process and add to globalDateHash
+**     Third: make month tables and append to page 
+**********************************************************************/
+function findHCalendarEvents () {
+  if (!(document.getElementById && document.createElement)) {
+    debug("No DOM!");
+    return;
+  }
+  if ($('#jhCalendar') == null) {  
+    debug("jhCalendar not found!")
+    return;
+  }
+  $('.vevent').each(function() {
+       var eventHash = {};
+       var startDateInfo;
+       var endDateInfo;
+       eventHash.summary = $(this).find(".summary, :first").html();
+       eventHash.description = $(this).find(".description").html();
+       eventHash.time = $(this).find(".time, :first").html();
+       startDateInfo = parseDT($(this).children(".dtstart")); 
+       
+       endDateInfo = parseDT($(this).children(".dtend"));
+       if (endDateInfo == null) {
+               endDateInfo = [[startDateInfo[0]],[startDateInfo[1]],[startDateInfo[2]]];
+       }
+       var startDate = startDateInfo[2];
+       var endDate = endDateInfo[2];
+
+       // handle events that span months:
+       // If event goes into next month, grab end of this month and add event until then.
+       // If event starts in previous month, grab start of month and add event till end date.
+       if ((startDateInfo[0] < endDateInfo[0]) || (endDateInfo[0] > endDateInfo[0])
+                       || (startDateInfo[1] < endDateInfo[1]) || (endDateInfo[1] > startDateInfo[1])) {
+               endDate = getMonthLength(startDateInfo[0], startDateInfo[1]);
+               addEventHashToGlobalDateHash(eventHash, startDateInfo, startDate, endDate);
+               
+               startDate = 1;
+               endDate = parseInt(endDateInfo[2]);
+               addEventHashToGlobalDateHash(eventHash, endDateInfo, startDate, endDate);
+       } 
+       //For events that are within a single month, just populate the event days normally.
+       else {
+               addEventHashToGlobalDateHash(eventHash, startDateInfo, startDate, endDate);
+       }
+       return;  
+  });
+  for (year in globalDateHash) {
+    for (month in globalDateHash[year]) {
+      var mt = makeMonthTable(globalDateHash[year][month], year, month);
+      $('#jhCalendar').append(mt);
+    }
+  }
+}
+
+
+/**
+ * Adds EventHash Object representing Event Data on a specific Day to the GlobalDateHash Object. 
+ * If the startDateDay and endDateDay are not equal, the event will be added to all Days in between.
+ */
+function addEventHashToGlobalDateHash(eventHash, dateInfo, startDate, endDate) {
+       // ParseDT returns an Array with three parts:
+       // First [0] is the Year, Second [1] is the Month, Third [2] is the Day. 
+       //  If the startDate is not equal to endDate, it's a multi-day event and we must loop through 
+       // and add the event for each day in the span globalDateHash.
+       for (var i = trimStartingZero(startDate); i <= trimStartingZero(endDate); i++) {
+               // If the Year doesn't exist in the globalDateHash, add Object for it.
+               if (globalDateHash[ dateInfo[0] ] == null) {
+                       globalDateHash[ dateInfo[0] ] = new Object();
+               }
+               // If the Month doesn't exist in the globalDateHash, add Object to represent it.
+               if (globalDateHash[ dateInfo[0] ][ dateInfo[1] ] == null) {
+                       globalDateHash[ dateInfo[0] ][ dateInfo[1] ] = new Object();
+               }
+               // If the Day doesn't exist in the globaDateHash, add Array to store Events on this day.
+               if (globalDateHash[ dateInfo[0] ][ dateInfo[1] ][ i ] == null) {
+                       globalDateHash[ dateInfo[0] ][ dateInfo[1] ][ i ] = new Array();
+               }
+               // Add this Event to the Array List of Events for this Day.
+               globalDateHash[ dateInfo[0] ][ dateInfo[1] ][ i ].push(eventHash);
+       }
+}
+
+//Create Table of the specified Month for the specified Year, with events. 
+function makeMonthTable (monthHash, year, month) {
+  currentMonthLength = getMonthLength(year, month);
+  previousMonthLength = getMonthLength(year, month-1);
+  var today = new Date;
+  var todayYear = today.getFullYear();
+  var todayMonth = today.getMonth() + 1;
+  var todayDay = today.getDate();    
+  var days = new Array(currentMonthLength+1); // We are going to index this array starting at 1.  Because I said so.
+  
+  // Create an HTML Table to Represent the Month and set necessary Attributes.
+  var monthTable =  document.createElement('table');
+  $(monthTable).addClass('calTable');
+  
+ // Create thead with rows for month/year, full day names and abbreviated day names
+  var thead = document.createElement("thead");
+  $(monthTable).append(thead);
+
+  var titleRow = document.createElement('tr');
+  $(thead).append(titleRow)
+
+  var titleTH = document.createElement('th')
+  $(titleRow).append($(titleTH).addClass('calHeader').attr("colspan", 7));
+  $(titleTH).html(monthNames[trimStartingZero(month)-1] + " " + year);
+
+  
+  var headerRow = document.createElement('tr');
+       for (var i = 0; i < dayNames.length; i++) {
+               $(headerRow).html($(headerRow).html() + '<th scope="col" >' + dayNames[i] + '</th>');
+       }
+  $(thead).append($(headerRow).addClass('longDays'));
+
+  var abbrevHeaderRow = document.createElement('tr');
+       for (var i = 0; i < dayAbbrevs.length; i++) {
+               $(abbrevHeaderRow).html($(abbrevHeaderRow).html() + '<th scope="col" >' + dayAbbrevs[i] + '</th>');
+       }
+  $(thead).append($(abbrevHeaderRow).addClass('abbrevDays'));
+       
+  // create tbody and fill with days
+  var tbody = document.createElement("tbody");
+  $(monthTable).append(tbody);
+
+  for (var i = 1; i <= currentMonthLength; i++) {
+    days[i] = document.createElement('td');
+    if (todayYear == year && todayMonth == month && todayDay == i) {
+      days[i].className += ' calDayToday';
+    }
+    $(days[i]).append('<div class="calDayLabel">' + i + '</div>');
+  }
+  
+  // populate days here
+  
+  for (var day in monthHash) {
+    var eventString = '';
+    for (var i = 0; i < monthHash[day].length; i++) {
+      dayTD = days[day-0];
+       $(dayTD).addClass('calEventDay');
+       eventString += '<p><strong>' + monthHash[day][i].summary + '</strong> ';
+       if (monthHash[day][i].description) {
+               eventString += monthHash[day][i].description;
+       }
+       eventString += '</p>';
+       $(dayTD).append('<div class="event">' + eventString + '</div>');
+    }
+
+  }    
+  var dateToCheck = new Date();
+  dateToCheck.setYear(year);
+  dateToCheck.setDate(1);
+  dateToCheck.setMonth(month-1);
+  var dayOfFirstOfMonth = dateToCheck.getDay();
+
+  var row = tbody.appendChild(document.createElement("tr"));
+  // Loop through empty Days before first Day of Month and fill with 'outOfRange' Cells.
+       for (var i = 0; i < dayOfFirstOfMonth; i++) {
+               $(row).append('<td class="outOfRange"><div class="calDayLabel"> ' + (previousMonthLength - (dayOfFirstOfMonth - i-1)) + '</div></td>');
+       }
+  
+  for (var i = 1; i <= currentMonthLength; i++) {
+    if (row.childNodes.length == 7) {
+      row = tbody.appendChild(document.createElement("tr"));
+    }
+    if(row.childNodes.length == 0 ||row.childNodes.length == 6){
+       $(days[i]).addClass('weekend');
+       }       
+    row.appendChild(days[i]);
+  }
+  // fill in next month's days to end
+  newmonth = 1;
+  while (row.childNodes.length < 7) {
+      $(row).append('<td class="outOfRange"><div class="calDayLabel">' + newmonth + '</div></td>');
+       newmonth++;
+  }
+  return monthTable;
+}
+
+$(document).ready(findHCalendarEvents);