GUI Components JavaScript DHTML




//  written  by Tan Ling Wee
//  last updated 28 July 2003
//  Web Site:  http://64.246.32.44/~admin59/index.htm
//  email :  info@sparrowscripts.com
//      url : www.sparrowscripts.com
//  TabSize: 4
//
//  modified by ALQUANTO 30 July 2003 - german language included.
//                    - modified languageLogic with the ISO-2letter-strings
//                    - changes in in showCalendar: defaultLanguage is already set...
//                    - js and html corrected... more xhtml-compliant... simplier css
//  email: popcalendar@alquanto.de
//
//  modified by PinoToy 25 July 2003  - new logic for multiple languages (English, Spanish and ready for more).
//                    - changes in popUpMonth & popDownMonth methods for hidding  popup.
//                    - changes in popDownYear & popDownYear methods for hidding  popup.
//                    - new logic for disabling dates in  the past.
//                    - new method showCalendar, dynamic  configuration of language, enabling  past & position.
//                    - changes in the styles.
//  email  : pinotoy@yahoo.com
  var language = 'en';  // Default Language: en - english ; es - spanish; de - german
  var enablePast = 0;    // 0 - disabled ; 1 - enabled
  var fixedX = -1;    // x position (-1 if to appear below control)
  var fixedY = -1;    // y position (-1 if to appear below control)
  var startAt = 1;    // 0 - sunday ; 1 - monday
  var showWeekNumber = 0;  // 0 - don't show; 1 - show
  var showToday = 1;    // 0 - don't show; 1 - show
  var imgDir = '';    // directory for images ... e.g. var imgDir="/img/"
  var dayName = '';
  var gotoString = {
    en : 'Go To Current Month',
    es : 'Ir al Mes Actual',
    de : 'Gehe zu aktuellem Monat'
  };
  var todayString = {
    en : 'Today is',
    es : 'Hoy es',
    de : 'Heute ist'
  };
  var weekString = {
    en : 'Wk',
    es : 'Sem',
    de : 'KW'
  };
  var scrollLeftMessage = {
    en : 'Click to scroll to previous month. Hold mouse button to scroll automatically.',
    es : 'Presione para pasar al mes anterior. Deje presionado para pasar varios meses.',
    de : 'Klicken um zum vorigen Monat zu gelangen. Gedruckt halten, um automatisch weiter zu scrollen.'
  };
  var scrollRightMessage = {
    en : 'Click to scroll to next month. Hold mouse button to scroll automatically.',
    es : 'Presione para pasar al siguiente mes. Deje presionado para pasar varios meses.',
    de : 'Klicken um zum nachsten Monat zu gelangen. Gedruckt halten, um automatisch weiter zu scrollen.'
  };
  var selectMonthMessage = {
    en : 'Click to select a month.',
    es : 'Presione para seleccionar un mes',
    de : 'Klicken um Monat auszuwahlen'
  };
  var selectYearMessage = {
    en : 'Click to select a year.',
    es : 'Presione para seleccionar un ano',
    de : 'Klicken um Jahr auszuwahlen'
  };
  var selectDateMessage = {    // do not replace [date], it will be replaced by date.
    en : 'Select [date] as date.',
    es : 'Seleccione [date] como fecha',
    de : 'Wahle [date] als Datum.'
  };
  var  monthName = {
    en : new Array('January','February','March','April','May','June','July','August','September','October','November','December'),
    es : new Array('Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'),
    de : new Array('Januar','Februar','Marz','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember')
  };
  var  monthName2 = {
    en : new Array('JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'),
    es : new Array('ENE','FEB','MAR','ABR','MAY','JUN','JUL','AGO','SEP','OCT','NOV','DIC'),
    de : new Array('JAN','FEB','MRZ','APR','MAI','JUN','JUL','AUG','SEP','OKT','NOV','DEZ')
  };
  if (startAt==0) {
    dayName = {
      en : new Array('Sun','Mon','Tue','Wed','Thu','Fri','Sat'),
      es : new Array('Dom','Lun','Mar','Mie','Jue','Vie','Sab'),
      de : new Array('So','Mo','Di','Mi','Do','Fr','Sa')
    };
  } else {
    dayName = {
      en : new Array('Mon','Tue','Wed','Thu','Fri','Sat','Sun'),
      es : new Array('Lun','Mar','Mie','Jue','Vie','Sab','Dom'),
      de : new Array('Mo','Di','Mi','Do','Fr','Sa','So')
    };
  }
  var crossobj, crossMonthObj, crossYearObj, monthSelected, yearSelected, dateSelected, omonthSelected, oyearSelected, odateSelected, monthConstructed, yearConstructed, intervalID1, intervalID2, timeoutID1, timeoutID2, ctlToPlaceValue, ctlNow, dateFormat, nStartingYear, selDayAction, isPast;
  var visYear  = 0;
  var visMonth = 0;
  var bPageLoaded = false;
  var ie  = document.all;
  var dom = document.getElementById;
  var ns4 = document.layers;
  var today    = new Date();
  var dateNow  = today.getDate();
  var monthNow = today.getMonth();
  var yearNow  = today.getYear();
  var imgsrc   = new Array('drop1.gif','drop2.gif','left1.gif','left2.gif','right1.gif','right2.gif');
  var img      = new Array();
  var bShow    = false;
  /* hides  and  objects (for IE only)
  */
  function showElement(elmID) {
    if(ie) {
      for(i = 0; i < document.all.tags( elmID ).length; i++) {
        obj = document.all.tags(elmID)[i];
        if(!obj || !obj.offsetParent) continue;
        obj.style.visibility = '';
      }
    }
  }
  function HolidayRec (d, m, y, desc) {
    this.d = d;
    this.m = m;
    this.y = y;
    this.desc = desc;
  }
  var HolidaysCounter = 0;
  var Holidays = new Array();
  function addHoliday (d, m, y, desc) {
    Holidays[HolidaysCounter++] = new HolidayRec (d, m, y, desc);
  }
  if (dom) {
    for  (i=0;i      img[i] = new Image;
      img[i].src = imgDir + imgsrc[i];
    }
    document.write ('');
    if (showToday == 1) {
      document.write ('');
    }
      
    document.write ('');
  }
  var  styleAnchor = 'text-decoration:none;color:black;';
  var  styleLightBorder = 'border:1px solid #a0a0a0;';
  function swapImage(srcImg, destImg) {
    if (ie) document.getElementById(srcImg).setAttribute('src',imgDir + destImg);
  }
  function init() {
    if (!ns4)
    {
      if (!ie) yearNow += 1900;
      crossobj=(dom)?document.getElementById('calendar').style : ie? document.all.calendar : document.calendar;
      hideCalendar();
      crossMonthObj = (dom) ? document.getElementById('selectMonth').style : ie ? document.all.selectMonth : document.selectMonth;
      crossYearObj = (dom) ? document.getElementById('selectYear').style : ie ? document.all.selectYear : document.selectYear;
      monthConstructed = false;
      yearConstructed = false;
      if (showToday == 1) {
        document.getElementById('lblToday').innerHTML =  '' + todayString[language] + ' '+dayName[language][(today.getDay()-startAt==-1)?6:(today.getDay()-startAt)]+', ' + dateNow + ' ' + monthName[language][monthNow].substring(0,3) + ' ' + yearNow + '';
      }
      sHTML1 = '   ';
      sHTML1 += '   ';
      sHTML1 += ' ';
      sHTML1 += ' ';
      document.getElementById('caption').innerHTML = sHTML1;
      bPageLoaded=true;
    }
  }
  function hideCalendar() {
    crossobj.visibility = 'hidden';
    if (crossMonthObj != null) crossMonthObj.visibility = 'hidden';
    if (crossYearObj  != null) crossYearObj.visibility = 'hidden';
    showElement('SELECT');
    showElement('APPLET');
  }
  function padZero(num) {
    return (num  < 10) ? '0' + num : num;
  }
  function constructDate(d,m,y) {
    sTmp = dateFormat;
    sTmp = sTmp.replace ('dd','');
    sTmp = sTmp.replace ('d','');
    sTmp = sTmp.replace ('',padZero(d));
    sTmp = sTmp.replace ('',d);
    sTmp = sTmp.replace ('mmmm','

');
    sTmp = sTmp.replace ('mmm','');
    sTmp = sTmp.replace ('mm','');
    sTmp = sTmp.replace ('m','');
    sTmp = sTmp.replace ('',m+1);
    sTmp = sTmp.replace ('',padZero(m+1));
    sTmp = sTmp.replace ('',monthName[language][m]);
    sTmp = sTmp.replace ('

',monthName2[language][m]);
    sTmp = sTmp.replace ('yyyy',y);
    return sTmp.replace ('yy',padZero(y%100));
  }
  function closeCalendar() {
    hideCalendar();
    ctlToPlaceValue.value = constructDate(dateSelected,monthSelected,yearSelected);
  }
  /*** Month Pulldown  ***/
  function StartDecMonth() {
    intervalID1 = setInterval("decMonth()",80);
  }
  function StartIncMonth() {
    intervalID1 = setInterval("incMonth()",80);
  }
  function incMonth () {
    monthSelected++;
    if (monthSelected > 11) {
      monthSelected = 0;
      yearSelected++;
    }
    constructCalendar();
  }
  function decMonth () {
    monthSelected--;
    if (monthSelected < 0) {
      monthSelected = 11;
      yearSelected--;
    }
    constructCalendar();
  }
  function constructMonth() {
    popDownYear()
    if (!monthConstructed) {
      sHTML = "";
      for (i=0; i<12; i++) {
        sName = monthName[language][i];
        if (i == monthSelected){
          sName = '' + sName + '';
        }
        sHTML += ' ' + sName + ' ';
      }
      document.getElementById('selectMonth').innerHTML = '' + sHTML + '';
      monthConstructed = true;
    }
  }
  function popUpMonth() {
    if (visMonth == 1) {
      popDownMonth();
      visMonth--;
    } else {
      constructMonth();
      crossMonthObj.visibility = (dom||ie) ? 'visible' : 'show';
      crossMonthObj.left = parseInt(crossobj.left) + 50;
      crossMonthObj.top =  parseInt(crossobj.top) + 26;
      hideElement('SELECT', document.getElementById('selectMonth'));
      hideElement('APPLET', document.getElementById('selectMonth'));
      visMonth++;
    }
  }
  function popDownMonth() {
    crossMonthObj.visibility = 'hidden';
    visMonth = 0;
  }
  /*** Year Pulldown ***/
  function incYear() {
    for  (i=0; i<7; i++) {
      newYear  = (i + nStartingYear) + 1;
      if (newYear == yearSelected)
        txtYear = ' ' + newYear + ' ';
      else
        txtYear = ' ' + newYear + ' ';
      document.getElementById('y'+i).innerHTML = txtYear;
    }
    nStartingYear++;
    bShow=true;
  }
  function decYear() {
    for  (i=0; i<7; i++) {
      newYear = (i + nStartingYear) - 1;
      if (newYear == yearSelected)
        txtYear = ' ' + newYear + ' ';
      else
        txtYear = ' ' + newYear + ' ';
      document.getElementById('y'+i).innerHTML = txtYear;
    }
    nStartingYear--;
    bShow=true;
  }
  function selectYear(nYear) {
    yearSelected = parseInt(nYear + nStartingYear);
    yearConstructed = false;
    constructCalendar();
    popDownYear();
  }
  function constructYear() {
    popDownMonth();
    sHTML = '';
    if (!yearConstructed) {
      sHTML = '-';
      j = 0;
      nStartingYear =  yearSelected - 3;
      for ( i = (yearSelected-3); i <= (yearSelected+3); i++ ) {
        sName = i;
        if (i == yearSelected) sName = '' + sName + '';
        sHTML += ' ' + sName + ' ';
        j++;
      }
      sHTML += '+';
      document.getElementById('selectYear').innerHTML = '' + sHTML + '';
      yearConstructed = true;
    }
  }
  function popDownYear() {
    clearInterval(intervalID1);
    clearTimeout(timeoutID1);
    clearInterval(intervalID2);
    clearTimeout(timeoutID2);
    crossYearObj.visibility= 'hidden';
    visYear = 0;
  }
  function popUpYear() {
    var leftOffset
    if (visYear==1) {
      popDownYear();
      visYear--;
    } else {
      constructYear();
      crossYearObj.visibility  = (dom||ie) ? 'visible' : 'show';
      leftOffset = parseInt(crossobj.left) + document.getElementById('spanYear').offsetLeft;
      if (ie) leftOffset += 6;
      crossYearObj.left = leftOffset;
      crossYearObj.top = parseInt(crossobj.top) + 26;
      visYear++;
    }
  }
  /*** calendar ***/
  function WeekNbr(n) {
    // Algorithm used:
    // From Klaus Tondering's Calendar document (The Authority/Guru)
    // http://www.tondering.dk/claus/calendar.html
    // a = (14-month) / 12
    // y = year + 4800 - a
    // m = month + 12a - 3
    // J = day + (153m + 2) / 5 + 365y + y / 4 - y / 100 + y / 400 - 32045
    // d4 = (J + 31741 - (J mod 7)) mod 146097 mod 36524 mod 1461
    // L = d4 / 1460
    // d1 = ((d4 - L) mod 365) + L
    // WeekNumber = d1 / 7 + 1
    year = n.getFullYear();
    month = n.getMonth() + 1;
    if (startAt == 0) {
      day = n.getDate() + 1;
    } else {
      day = n.getDate();
    }
    a = Math.floor((14-month) / 12);
    y = year + 4800 - a;
    m = month + 12 * a - 3;
    b = Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400);
    J = day + Math.floor((153 * m + 2) / 5) + 365 * y + b - 32045;
    d4 = (((J + 31741 - (J % 7)) % 146097) % 36524) % 1461;
    L = Math.floor(d4 / 1460);
    d1 = ((d4 - L) % 365) + L;
    week = Math.floor(d1/7) + 1;
    return week;
  }
  function constructCalendar () {
    var aNumDays = Array (31,0,31,30,31,30,31,31,30,31,30,31);
    var dateMessage;
    var startDate = new Date (yearSelected,monthSelected,1);
    var endDate;
    if (monthSelected==1) {
      endDate = new Date (yearSelected,monthSelected+1,1);
      endDate = new Date (endDate - (24*60*60*1000));
      numDaysInMonth = endDate.getDate();
    } else {
      numDaysInMonth = aNumDays[monthSelected];
    }
    datePointer = 0;
    dayPointer = startDate.getDay() - startAt;
    
    if (dayPointer<0) dayPointer = 6;
    sHTML = '';
    if (showWeekNumber == 1) {
      sHTML += '' + weekString[language] + '';
    }
    for (i = 0; i<7; i++) {
      sHTML += '' + dayName[language][i] + '';
    }
    sHTML += '';
    
    if (showWeekNumber == 1) {
      sHTML += '' + WeekNbr(startDate) + ' ';
    }
    for  ( var i=1; i<=dayPointer;i++ ) {
      sHTML += ' ';
    }
  
    for  ( datePointer=1; datePointer <= numDaysInMonth; datePointer++ ) {
      dayPointer++;
      sHTML += '';
      sStyle=styleAnchor;
      if ((datePointer == odateSelected) && (monthSelected == omonthSelected) && (yearSelected == oyearSelected))
      { sStyle+=styleLightBorder }
      sHint = '';
      for (k = 0;k < HolidaysCounter; k++) {
        if ((parseInt(Holidays[k].d) == datePointer)&&(parseInt(Holidays[k].m) == (monthSelected+1))) {
          if ((parseInt(Holidays[k].y)==0)||((parseInt(Holidays[k].y)==yearSelected)&&(parseInt(Holidays[k].y)!=0))) {
            sStyle+= 'background-color:#fdd;';
            sHint += sHint=="" ? Holidays[k].desc : "\n"+Holidays[k].desc;
          }
        }
      }
      sHint = sHint.replace('/\"/g', '"');
      dateMessage = 'onmousemove="window.status=\''+selectDateMessage[language].replace('[date]',constructDate(datePointer,monthSelected,yearSelected))+'\'" onmouseout="window.status=\'\'" ';
      //////////////////////////////////////////////
      //////////  Modifications PinoToy  //////////
      //////////////////////////////////////////////
      if (enablePast == 0 && ((yearSelected < yearNow) || (monthSelected < monthNow) && (yearSelected == yearNow) || (datePointer < dateNow) && (monthSelected == monthNow) && (yearSelected == yearNow))) {
        selDayAction = '';
        isPast = 1;
      } else {
        selDayAction = 'href="javascript:dateSelected=' + datePointer + ';closeCalendar();"';
        isPast = 0;
      }
      if ((datePointer == dateNow) && (monthSelected == monthNow) && (yearSelected == yearNow)) {  ///// today
        sHTML += " " + datePointer + " ";
      } else if (dayPointer % 7 == (startAt * -1)+1) {                  ///// SI ES DOMINGO
        if (isPast==1)
          sHTML += " " + datePointer + " ";
        else
          sHTML += " " + datePointer + " ";
      } else if ((dayPointer % 7 == (startAt * -1)+7 && startAt==1) || (dayPointer % 7 == startAt && startAt==0)) {  ///// SI ES SABADO
        if (isPast==1)
          sHTML += " " + datePointer + " ";
        else
          sHTML += " " + datePointer + " ";
      } else {                                      ///// CUALQUIER OTRO DIA
        if (isPast==1)
          sHTML += " " + datePointer + " ";
        else
          sHTML += " " + datePointer + " ";
      }
      sHTML += '';
      if ((dayPointer+startAt) % 7 == startAt) {
        sHTML += '';
        if ((showWeekNumber == 1) && (datePointer < numDaysInMonth)) {
          sHTML += '' + (WeekNbr(new Date(yearSelected,monthSelected,datePointer+1))) + ' ';
        }
      }
    }
    document.getElementById('content').innerHTML   = sHTML
    document.getElementById('spanMonth').innerHTML = ' ' +  monthName[language][monthSelected] + ' '
    document.getElementById('spanYear').innerHTML  = ' ' + yearSelected  + ' ';
  }
  function showCalendar(ctl, ctl2, format, lang, past, fx, fy) {
    if (lang != null && lang != '') language = lang;
    if (past != null) enablePast = past;
    else enablePast = 0;
    if (fx != null) fixedX = fx;
    else fixedX = -1;
    if (fy != null) fixedY = fy;
    else fixedY = -1;
    if (showToday == 1) {
      document.getElementById('lblToday').innerHTML = '' + todayString[language] + ' '+dayName[language][(today.getDay()-startAt==-1)?6:(today.getDay()-startAt)]+', ' + dateNow + ' ' + monthName[language][monthNow].substring(0,3) + ' ' + yearNow + '';
    }
    popUpCalendar(ctl, ctl2, format);
  }
  function popUpCalendar(ctl, ctl2, format) {
    var leftpos = 0;
    var toppos  = 0;
    if (bPageLoaded) {
      if (crossobj.visibility == 'hidden') {
        ctlToPlaceValue = ctl2;
        dateFormat = format;
        formatChar = ' ';
        aFormat = dateFormat.split(formatChar);
        if (aFormat.length < 3) {
          formatChar = '/';
          aFormat = dateFormat.split(formatChar);
          if (aFormat.length < 3) {
            formatChar = '.';
            aFormat = dateFormat.split(formatChar);
            if (aFormat.length < 3) {
              formatChar = '-';
              aFormat = dateFormat.split(formatChar);
              if (aFormat.length < 3) {
                formatChar = '';          // invalid date format
              }
            }
          }
        }
        tokensChanged = 0;
        if (formatChar != "") {
          aData =  ctl2.value.split(formatChar);      // use user's date
          for (i=0; i<3; i++) {
            if ((aFormat[i] == "d") || (aFormat[i] == "dd")) {
              dateSelected = parseInt(aData[i], 10);
              tokensChanged++;
            } else if ((aFormat[i] == "m") || (aFormat[i] == "mm")) {
              monthSelected = parseInt(aData[i], 10) - 1;
              tokensChanged++;
            } else if (aFormat[i] == "yyyy") {
              yearSelected = parseInt(aData[i], 10);
              tokensChanged++;
            } else if (aFormat[i] == "mmm") {
              for (j=0; j<12; j++) {
                if (aData[i] == monthName[language][j]) {
                  monthSelected=j;
                  tokensChanged++;
                }
              }
            } else if (aFormat[i] == "mmmm") {
              for (j=0; j<12; j++) {
                if (aData[i] == monthName2[language][j]) {
                  monthSelected = j;
                  tokensChanged++;
                }
              }
            }
          }
        }
        if ((tokensChanged != 3) || isNaN(dateSelected) || isNaN(monthSelected) || isNaN(yearSelected)) {
          dateSelected  = dateNow;
          monthSelected = monthNow;
          yearSelected  = yearNow;
        }
        odateSelected  = dateSelected;
        omonthSelected = monthSelected;
        oyearSelected  = yearSelected;
        aTag = ctl;
        do {
          aTag     = aTag.offsetParent;
          leftpos += aTag.offsetLeft;
          toppos  += aTag.offsetTop;
        } while (aTag.tagName != 'BODY');
        crossobj.left = (fixedX == -1) ? ctl.offsetLeft + leftpos : fixedX;
        crossobj.top = (fixedY == -1) ? ctl.offsetTop + toppos + ctl.offsetHeight + 2 : fixedY;
        constructCalendar (1, monthSelected, yearSelected);
        crossobj.visibility = (dom||ie) ? "visible" : "show";
        hideElement('SELECT', document.getElementById('calendar'));
        hideElement('APPLET', document.getElementById('calendar'));      
        bShow = true;
      } else {
        hideCalendar();
        if (ctlNow!=ctl) popUpCalendar(ctl, ctl2, format);
      }
      ctlNow = ctl;
    }
  }
  document.onkeypress = function hidecal1 () {
    if (event.keyCode == 27) hideCalendar();
  }
  document.onclick = function hidecal2 () {
    if (!bShow) hideCalendar();
    bShow = false;
  }
  if(ie) {
    init();
  } else {
    window.onload = init;
  }


  body{
    color: black;
    font-size: 11px;
  }
  ADDRESS,BLOCKQUOTE,BODY,CAPTION,CENTER,DD,DIR,DIV,DL,DT,FORM,H1,H2,H3,H4,H5,H6,INPUT,MENU,OL,P,SELECT,TD,TEXTAREA,TH,UL{
    color: black;
    font-family: Verdana,Geneva,Arial,Helvetica,sans-serif;
  }








  

Demonstration # 1


    This demonstration caters for Netscape 4, but showing the date value in a text box. The trigger is a button, and the data container is the text box.


    

    
      
      
      
      
    
    

    
    
  

Demonstration # 2


    The following demonstration uses a button as both a trigger and data container. Selected language is german.
    (You will not see anything below if you are using Netscape Navigator 4)
    

      
    



           
         
  
popupcal.zip( 8 k)