Special XML conversion code for Firefox >= 20.0
[infodrom/rico3] / minsrc / ricoCalendar.js
index 28e4bce..8a30143 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  (c) 2005-2009 Richard Cowin (http://openrico.org)
- *  (c) 2005-2009 Matt Brown (http://dowdybrown.com)
+ *  (c) 2005-2011 Richard Cowin (http://openrico.org)
+ *  (c) 2005-2011 Matt Brown (http://dowdybrown.com)
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
  *  file except in compliance with the License. You may obtain a copy of the License at
@@ -39,6 +39,8 @@ Rico.CalendarControl.prototype = {
   initialize: function(id,options) {
     this.id=id;
     var today=new Date();
+    this.defaultMin = new Date(today.getFullYear()-50,0,1);
+    this.defaultMax = new Date(today.getFullYear()+50,11,31);
     Rico.extend(this, new Rico.Popup());
     Rico.extend(this.options, {
       ignoreClicks:true,
@@ -46,21 +48,16 @@ Rico.CalendarControl.prototype = {
       showWeekNumber : 0,
       showToday : 1,
       dateFmt : 'ISO8601',
-      minDate : new Date(today.getFullYear()-50,0,1),
-      maxDate : new Date(today.getFullYear()+50,11,31)
+      minDate : this.defaultMin,
+      maxDate : this.defaultMax
     });
     Rico.extend(this.options, options || {});
-    /**
-     * alias for closePopup
-     * @function
-     */
-    this.close=this.closePopup;
     this.bPageLoaded=false;
-    this.img=[];
     this.Holidays={};
-    this.weekString=Rico.getPhraseById("calWeekHdg");
     this.re=/^\s*(\w+)(\W)(\w+)(\W)(\w+)/i;
     this.setDateFmt(this.options.dateFmt);
+    var self=this;
+    Rico.onLoad(function() { self.atLoad(); })
   },
 
 
@@ -103,67 +100,89 @@ Rico.CalendarControl.prototype = {
       this.container.id=this.id;
     }
     Rico.addClass(this.content, Rico.theme.calendar || 'ricoCalContainer');
-    this.content.style.display='block';  // override jquery ui
+    this.direction=Rico.direction(this.container);
 
+    var r,c,i,j,dow,a,s,tab;
+    this.colStart=this.options.showWeekNumber ? 1 : 0;
+    var colcnt=7+this.colStart
     this.maintab=document.createElement("table");
     this.maintab.cellSpacing=2;
     this.maintab.cellPadding=0;
     this.maintab.border=0;
     this.maintab.style.borderCollapse='separate';
-    this.maintab.className='ricoCalTab';
-    if (Rico.theme.calendarTable) Rico.addClass(this.maintab,Rico.theme.calendarTable)
-    this.tbody=Rico.getTBody(this.maintab);
+    this.maintab.className=Rico.theme.calendarTable || 'ricoCalTab';
 
-    var r,c,i,j,img,dow,a,s,tab;
-    this.colStart=this.options.showWeekNumber ? 1 : 0;
-    for (i=0; i<7; i++) {
-      r=this.tbody.insertRow(-1);
-      r.className='row'+i;
-      for (c=0; c<7+this.colStart; c++) {
-        r.insertCell(-1);
-      }
-    }
-    r=this.tbody.rows[0];
-    r.className='ricoCalDayNames';
-    if (this.options.showWeekNumber) {
-      r.cells[0].innerHTML=this.weekString;
-      for (i=0; i<7; i++) {
-        this.tbody.rows[i].cells[0].className='ricoCalWeekNum';
-      }
-    }
-    this.styles=[];
-    for (i=0; i<7; i++) {
-      dow=(i+this.options.startAt) % 7;
-      r.cells[i+this.colStart].innerHTML=Rico.dayAbbr(dow);
-      this.styles[i]='ricoCal'+dow;
-    }
-    
-    // Navigation controls
-    this.heading=this.content.appendChild(document.createElement("div"));
+    // thead (Navigation controls)
+    this.thead=this.maintab.createTHead();
+    r=this.thead.insertRow(-1);
+    this.heading=r.insertCell(-1);
+    this.heading.colSpan=colcnt;
+    //this.heading=this.content.appendChild(document.createElement("div"));
     this.heading.className='RicoCalHeading';
     if (Rico.theme.calendarHeading) Rico.addClass(this.heading,Rico.theme.calendarHeading)
-    var d2=this.heading.appendChild(document.createElement("div"));
-    d2.className='RicoCalHeadingInner';
-    d2.appendChild(this._createTitleSection('Month'));
-    d2.appendChild(this._createTitleSection('Year'));
-    new Rico.HoverSet(this.heading.getElementsByTagName('a'));
-    new Rico.HoverSet(this.tbody.getElementsByTagName('td'),{ hoverNodes: function(e) { return e.innerHTML.match(/^\d+$/) ? [e] : []; } });
-    if (this.position == 'absolute') this.heading.appendChild(Rico.closeButton(Rico.eventHandle(this,'close')));
 
     // table footer (today)
     if (this.options.showToday) {
       this.tfoot=this.maintab.createTFoot();
+      this.tfoot.className='ricoCalFoot';
       r=this.tfoot.insertRow(-1);
       this.todayCell=r.insertCell(-1);
-      this.todayCell.colSpan=7+this.colStart;
-      if (Rico.theme.calendarFooter) Rico.addClass(this.todayCell,Rico.theme.calendarFooter);
+      this.todayCell.colSpan=colcnt;
+      this.todayCell.className=Rico.theme.calendarFooter || 'ricoCalFoot';
       Rico.eventBind(this.todayCell,"click", Rico.eventHandle(this,'selectNow'), false);
     }
+
+    this.tbody=Rico.getTBody(this.maintab);
+    this.tbody.className='ricoCalBody';
+
+    this.content.style.display='block';
+    if (this.position == 'absolute') {
+      this.content.style.width='auto';
+      this.maintab.style.width='auto';
+    } else {
+      this.container.style.position='relative';
+      this.heading.style.position='static';  // fixes issue with ie7
+      this.content.style.padding='0px';
+      this.content.style.width='15em';
+      this.maintab.style.width='100%';
+    }
+
+    this.styles=[];
+    for (i=0; i<7; i++) {
+      r=this.tbody.insertRow(-1);
+      r.className=i==0 ? 'ricoCalDayNames' : 'row'+i;
+      if (this.options.showWeekNumber) {
+        c=r.insertCell(-1);
+        c.className='ricoCalWeekNum';
+        if (i==0) c.innerHTML=Rico.getPhraseById("calWeekHdg");
+      }
+      for (j=0; j<7; j++) {
+        c=r.insertCell(-1);
+        if (i==0) {
+          dow=(j+this.options.startAt) % 7;
+          c.innerHTML=Rico.dayAbbr(dow);
+          this.styles[j]='ricoCal'+dow;
+        } else {
+          c.className=this.styles[j];
+          if (Rico.theme.calendarDay) Rico.addClass(c,Rico.theme.calendarDay);
+        }
+      }
+    }
+    
     this.content.appendChild(this.maintab);
+    new Rico.HoverSet(this.tbody.getElementsByTagName('td'),{ hoverNodes: function(e) { return e.innerHTML.match(/^\d+$/) ? [e] : []; } });
+
+    this.navtab=this.heading.appendChild(document.createElement("table"));
+    this.navrow=this.navtab.insertRow(-1);
+    this._createTitleSection('Month');
+    this.navrow.insertCell(-1).innerHTML="&nbsp;&nbsp;";
+    this._createTitleSection('Year');
+    new Rico.HoverSet(this.heading.getElementsByTagName('a'));
+    if (this.position == 'absolute') this.heading.appendChild(Rico.closeButton(Rico.eventHandle(this,'close')));
     
     // month selector
-    this.monthPopup=new Rico.Popup(document.createElement("div"));
-    this.monthPopup.closePopup();
+    this.monthPopup=new Rico.Popup(document.createElement("div"),{shim:false,zIndex:10});
+    this.monthPopup.content.className='ricoCalMonthPrompt';
     tab=document.createElement("table");
     tab.className='ricoCalMenu';
     if (Rico.theme.calendarPopdown) Rico.addClass(tab,Rico.theme.calendarPopdown);
@@ -187,41 +206,27 @@ Rico.CalendarControl.prototype = {
     new Rico.HoverSet(tab.getElementsByTagName('a'));
     this.monthPopup.content.appendChild(tab);
     this.container.appendChild(this.monthPopup.container);
+    this.monthPopup.closePopup();
     
     // year selector
-    this.yearPopup=new Rico.Popup(document.createElement("div"));
-    this.yearPopup.closePopup();
+    this.yearPopup=new Rico.Popup(document.createElement("div"),{shim:false,zIndex:10});
     this.yearPopup.content.className='ricoCalYearPrompt';
     if (Rico.theme.calendarPopdown) Rico.addClass(this.yearPopup.content,Rico.theme.calendarPopdown);
-    var tab=document.createElement("table");
-    tab.cellPadding=2;
-    tab.cellSpacing=0;
-    tab.border=0;
-    tab.style.borderCollapse='separate';
-    tab.style.margin='0px';
-    r=tab.insertRow(-1);
-    this.yearLabel=r.insertCell(-1);
-    this.yearLabel.colSpan=3;
-    this.yearLabel.innerHTML=Rico.getPhraseById("calYearRange",this.options.minDate.getFullYear(),this.options.maxDate.getFullYear());
-    r=tab.insertRow(-1);
-    c=r.insertCell(-1);
-    this.yearInput=c.appendChild(document.createElement("input"));
+    this.yearPrompt=document.createElement("p");
+    this.yearPrompt.innerHTML="&nbsp;";
+    var p2=document.createElement("p");
+    this.yearInput=p2.appendChild(document.createElement("input"));
     this.yearInput.maxlength=4;
     this.yearInput.size=4;
     Rico.eventBind(this.yearInput,"keyup", Rico.eventHandle(this,'yearKey'), false);
-    c=r.insertCell(-1);
-    var a=Rico.floatButton('Checkmark', Rico.eventHandle(this,'processPopUpYear'));
-    Rico.setStyle(a.firstChild,{ margin:"0px", padding:"0px", border:"none" });
-    c.appendChild(a);
-    c=r.insertCell(-1);
+    a=Rico.floatButton('Checkmark', Rico.eventHandle(this,'processPopUpYear'));
+    p2.appendChild(a);
     a=Rico.floatButton('Cancel', Rico.eventHandle(this,'popDownYear'));
-    Rico.setStyle(a.firstChild,{ margin:"0px", padding:"0px", border:"none" });
-    c.appendChild(a);
-    this.yearPopup.content.appendChild(tab);
+    p2.appendChild(a);
+    this.yearPopup.content.appendChild(this.yearPrompt);
+    this.yearPopup.content.appendChild(p2);
     this.container.appendChild(this.yearPopup.container);
-    this.yearPopup.container.style.left='';
-    this.yearPopup.container.style.right='5px';
-    this.yearPopup.container.style.zIndex=10;
+    this.yearPopup.closePopup();
 
     // fix anchors so they work in IE6
     a=this.content.getElementsByTagName('a');
@@ -230,32 +235,37 @@ Rico.CalendarControl.prototype = {
     }
     
     Rico.eventBind(this.tbody,"click", Rico.eventHandle(this,'saveAndClose'));
-    this.close();
     this.bPageLoaded=true;
   },
 
   _createTitleSection : function(section) {
-    var s=document.createElement("span");
-    s.className='RicoCal'+section+'Heading';
-    if (Rico.theme.calendarSubheading) Rico.addClass(s,Rico.theme.calendarSubheading);
-
-    var a=s.appendChild(document.createElement("a"));
-    a.className='Rico_leftArrow';
-    if (Rico.theme.leftArrowAnchor) Rico.addClass(a,Rico.theme.leftArrowAnchor);
-    a.appendChild(this.createNavArrow('dec'+section,'left'));
+    var arrows=['left','right'];
+    if (this.direction=='rtl') arrows.reverse();
+    var c=this.navrow.insertCell(-1);
+    var a=c.appendChild(document.createElement("a"));
+    a.className='Rico_'+arrows[0]+'Arrow';
+    a.appendChild(this._createNavArrow(arrows[0]));
+    Rico.eventBind(a,"click", Rico.eventHandle(this,'dec'+section), false);
 
-    a=s.appendChild(document.createElement("a"));
-    a.style.display='inline';
+    c=this.navrow.insertCell(-1);
+    a=c.appendChild(document.createElement("a"));
     Rico.eventBind(a,"click", Rico.eventHandle(this,'popUp'+section), false);
     this['title'+section]=a;
 
-    a=s.appendChild(document.createElement("a"));
-    a.className='Rico_rightArrow';
-    if (Rico.theme.rightArrowAnchor) Rico.addClass(a,Rico.theme.rightArrowAnchor);
-    a.appendChild(this.createNavArrow('inc'+section,'right'));
-    return s
+    c=this.navrow.insertCell(-1);
+    a=c.appendChild(document.createElement("a"));
+    a.className='Rico_'+arrows[1]+'Arrow';
+    a.appendChild(this._createNavArrow(arrows[1]));
+    Rico.eventBind(a,"click", Rico.eventHandle(this,'inc'+section), false);
   },
   
+  _createNavArrow: function(direction) {
+    var span=document.createElement("span");
+    span.className=Rico.theme[direction+'Arrow'] || 'rico-icon Rico_'+direction+'Arrow';
+    span.style.display="inline-block";
+    return span;
+  },
+
   selectNow : function() {
     var today = new Date();
     this.dateNow  = today.getDate();
@@ -266,14 +276,6 @@ Rico.CalendarControl.prototype = {
     this.constructCalendar();
   },
   
-/** @private */
-  createNavArrow: function(funcname,direction) {
-    var span=document.createElement("span");
-    span.className=Rico.theme[direction+'Arrow'] || 'rico-icon Rico_'+direction+'Arrow';
-    Rico.eventBind(span,"click", Rico.eventHandle(this,funcname), false);
-    return span;
-  },
-
 /**
  * @returns true if yr/mo is within minDate/MaxDate
  */
@@ -285,7 +287,8 @@ Rico.CalendarControl.prototype = {
     return true;
   },
 
-  incMonth : function() {
+  incMonth : function(e) {
+    if (e) Rico.eventStop(e);
     var newMonth=this.monthSelected+1;
     var newYear=this.yearSelected;
     if (newMonth>11) {
@@ -298,7 +301,8 @@ Rico.CalendarControl.prototype = {
     this.constructCalendar();
   },
 
-  decMonth : function() {
+  decMonth : function(e) {
+    if (e) Rico.eventStop(e);
     var newMonth=this.monthSelected-1;
     var newYear=this.yearSelected;
     if (newMonth<0) {
@@ -318,21 +322,23 @@ Rico.CalendarControl.prototype = {
     this.constructCalendar();
     Rico.eventStop(e);
   },
+  
+  // position: 0=left, 1=right
+  openYrMo : function(popup,position) {
+    if (this.direction=='rtl') position=1-position;
+    popup.openPopup();
+    var left=position ? this.content.offsetWidth - popup.container.offsetWidth - 5 : 3;
+    popup.move(left, this.heading.offsetHeight+2);
+  },
 
   popUpMonth : function(e) {
     Rico.eventStop(e);
     if (this.monthPopup.visible()) {
       this.popDownMonth();
-      return;
+      return false;
     }
     this.popDownYear();
-    if (Rico.isIE && Rico.ieVersion < 7) {
-      // fix position absolute inside container without hasLayout
-      this.monthPopup.openPopup(null, this.heading.offsetHeight+2);
-      this.monthPopup.container.style.left='';
-    } else {
-      this.monthPopup.openPopup(3, this.heading.offsetHeight+2);
-    }
+    this.openYrMo(this.monthPopup,0);
     return false;
   },
 
@@ -352,13 +358,15 @@ Rico.CalendarControl.prototype = {
     Rico.eventStop(e);
     if (this.yearPopup.visible()) {
       this.popDownYear();
-      return;
+      return false;
     }
     this.popDownMonth();
-    this.yearPopup.openPopup(null, this.heading.offsetHeight+2);
+    this.yearPrompt.innerHTML=Rico.getPhraseById("calYearRange",this.options.minDate.getFullYear(),this.options.maxDate.getFullYear());
     this.yearInput.disabled=false;
     this.yearInput.value='';   // this.yearSelected
-    this.yearInput.focus();
+    this.openYrMo(this.yearPopup,1);
+    var self=this;
+    setTimeout(function() { self.yearInput.focus(); }, 10);  // ie8 has issues without this delay
     return false;
   },
   
@@ -382,13 +390,15 @@ Rico.CalendarControl.prototype = {
     }
   },
   
-  incYear : function() {
+  incYear : function(e) {
+    if (e) Rico.eventStop(e);
     if (this.yearSelected>=this.options.maxDate.getFullYear()) return;
     this.yearSelected++;
     this.constructCalendar();
   },
 
-  decYear : function() {
+  decYear : function(e) {
+    if (e) Rico.eventStop(e);
     if (this.yearSelected<=this.options.minDate.getFullYear()) return;
     this.yearSelected--;
     this.constructCalendar();
@@ -467,6 +477,7 @@ Rico.CalendarControl.prototype = {
       c.style.color=h ? h.txtColor : '';
       c.style.backgroundColor=h ? h.bgColor : '';
       c.title=h ? h.desc : '';
+      c.style.visibility='visible';
       if (colnum==6) r++;
     }
     while (dayPointer<42) {
@@ -486,10 +497,13 @@ Rico.CalendarControl.prototype = {
 /** @private */
   resetCell: function(c) {
     c.innerHTML="&nbsp;";
-    c.className='ricoCalEmpty';
-    c.style.color='';
-    c.style.backgroundColor='';
     c.title='';
+    c.style.visibility='hidden';
+  },
+  
+  close: function(e) {
+    if (e) Rico.eventStop(e);
+    this.closePopup();
   },
   
 /** @private */
@@ -504,12 +518,17 @@ Rico.CalendarControl.prototype = {
     var dateStr=Rico.formatDate(d,this.dateFmt=='ISO8601' ? 'yyyy-mm-dd' : this.dateFmt);
     if (this.returnValue) {
       this.returnValue(dateStr);
-      this.close();
+      this.closePopup();
     }
   },
 
-  open : function(curval) {
+  open : function(curval,column) {
     if (!this.bPageLoaded) return;
+    if (column) {
+      this.setDateFmt(column.format.dateFmt);
+      this.options.minDate=column.format.min || this.defaultMin;
+      this.options.maxDate=column.format.max || this.defaultMax;
+    }
     var today = new Date();
     this.dateNow  = today.getDate();
     this.monthNow = today.getMonth();