SoFunction
Updated on 2025-03-10

javascript calendar reminder system (compatible with all browsers)


/*
* Calendar
* Language 0: Chinese, 1: English
* calendar into the element html use 'show()'
* -up calendar use 'pop()'
*/

var Calendar = function( instanceId, language, startYear, endYear ){
    if( typeof instanceId == "string" ){
             = new Date();
             = ();
             = ();
            = ();
            = ();

         = instanceId;
            = language     || 1;
            = startYear || - 5;
            = endYear     || + 1;

        // If instance is input[type='text'] object
        this.popContainer_id = 'popCalendarContainer';

        // Message store
         = [];

        this.caleContainer_id = 'calendarContainer';
         = {
            today_view_id:        'calendarTodayView',
            week_view_id:        'calendarWeekView',
            lq_year_id:            'linkQuickYear',
            lq_month_id:        'linkQuickMonth',
            sq_year_id:            'selectQuickYear',
            sq_month_id:        'selectQuickMonth',
            close_id:            'calendarClose',
            prev_month_id:        'toPrevMonth',
            back_today_id:        'backToday',
            next_month_id:        'toNextMonth'
        }
        this.daysContainer_id = 'calendarDaysContainer';
        this.msgContainer_id = 'calendarTipsContainer';

         =         'calendarCurrentDay';
         =        'calendarTipDay';
         =    'calendarOldTipDay';
    }
};
/* Calendar language */
= {
weeks:     [
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
                ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
            ],
weeksMenu:[
["Sun","One","Two","Three","Four","Five","Five","Six",
             ["SUN","MON","TUR","WED","THU","FRI","SAT"]
    ]
};
/* Create calendar element */
._getViewElement = function(){
    // Create page html element
    var caleElem = "";
        // Create Start
        caleElem+= '<div id='+this.caleContainer_id+'>';

        // <Top>
        caleElem+= '<div ><table cellpadding="0" cellspacing="0"><tr>';

        // Top day view
        caleElem+= '<td id='+.today_view_id+'></td>';

        // Link or select control
        caleElem+= '<td>';
        caleElem+= '<div id='+.week_view_id+'></div>';
        caleElem+= '<table cellpadding="0" cellspacing="0">';
        caleElem+= '<tr>';
        caleElem+= '<td>';
        caleElem+= '<a id='+.lq_year_id+' href="javascript:void(0);"></a>';
        caleElem+= '<select id='+.sq_year_id+'></select>';
        caleElem+= '</td>';
        caleElem+= '<td>.</td>';
        caleElem+= '<td>';
        caleElem+= '<a id='+.lq_month_id+' href="javascript:void(0);"></a>';
        caleElem+= '<select id='+.sq_month_id+'></select>';
        caleElem+= '</td>';
        caleElem+= '</tr>';
        caleElem+= '</table>';
        caleElem+= '</td>';

        // Quick control
        caleElem+= '<td>';
        caleElem+= '<div >';
        caleElem+= '<a id='+.close_id+' href="javascript:void(0);">x</a>';
        caleElem+= '</div>';

        caleElem+= '<div >';
        caleElem+= '<a id='+.prev_month_id+' href="javascript:void(0);">&laquo;</a>';
        caleElem+= '<a id='+.back_today_id+' href="javascript:void(0);">&nbsp;</a>';
        caleElem+= '<a id='+.next_month_id+' href="javascript:void(0);">&raquo;</a>';
        caleElem+= '</div>';
        caleElem+= '</td>';

        caleElem+= '</tr></table cellpadding="0" cellspacing="0"></div>';
        // </Top>

        // <Calendar View>
        caleElem+= '<div >';
        // Week menu
        caleElem+= '<div >';
        for(var i = 0; i < 7; i ++){
        caleElem+= '<span>'+["weeksMenu"][][i]+'</span>';
        }
        caleElem+= '</div>';

        // Days view
        caleElem+= '<table id='+this.daysContainer_id+' cellpadding="0" cellspacing="0">';
        for(var tr = 0; tr < 6; tr ++){
        caleElem+= '<tr>';
        for(var td = 0; td < 7; td ++){
        caleElem+= '<td><span></span></td>';
        }
        caleElem+= '</tr>';
        }
        caleElem+= '</table>';

        caleElem+= '</div>';
        // </Calendar View>

        caleElem+= '</div>';

        // <Calendar msg>
        caleElem+= '<div id='+this.msgContainer_id+'></div>';
        // </Calendar msg>

        // Create End
    return caleElem;
};
/* Get Month Data */
._getMonthViewArray = function( year, month ){
    var monthArray = [];
    // From the beginning day of the week
    var beginDayOfWeek = new Date( year, month, 1).getDay();

    // This month total days
    var daysOfMonth = new Date( year, month + 1, 0).getDate();

    // 42: 7*6 matrix
    for( var i = 0; i < 42; i ++ )
     monthArray[i] = "&nbsp;";

    for( var j = 0; j < daysOfMonth; j ++ )
        monthArray[j + beginDayOfWeek] = j + 1 ;

    return monthArray;
};
/* Search the index of option in the select */
._getOptionIndex = function( selectObject, value ){
    for( var j = 0; j < ; j ++ ){
        if( value == [j].value )
            return j;
    }
};
/* Bind year data into 'Year select' */
._bindYearIntoSelect = function(){
    var oYear = ( .sq_year_id );
    var oYearLen = 0;
    for( var i = ; i <= ; i ++, oYearLen ++ )
        [oYearLen] = new Option( i , i );
};
/* Bind Month data into 'Month select' */
._bindMonthIntoSelect = function(){
    var oMonth = ( .sq_month_id );
    var oMonthLen = 0;
    for( var i = 0; i < 12; i ++, oMonthLen ++ )
        [oMonthLen] = new Option( i + 1 , i + 1 );
};
/* Bind data */
._bindAllData = function( curYear, curMonth ){
    var cr = this;
    // Bind default Data into 'select:Year'
    this._bindYearIntoSelect();

    // Bind default Data into 'select:Month'
    this._bindMonthIntoSelect();

    // Change the 'select:Year' and 'select:Month' value
    ( curYear, curMonth );

    // Bind default data into 'current day view and current week view'
    ( .week_view_id ).innerHTML = ['weeks'][][];
    ( .today_view_id ).innerHTML = ;

    // Get days and bind into 'CalendarMain'
    // Add current day class and mouse event
    var daysOfMonthArray = this._getMonthViewArray( curYear, curMonth );
    var spans = ( this.daysContainer_id, "span" );
    var curYMD = + "" + ( + 1 ) + "" + ;
    var selectYear = ( .sq_year_id ).value;
    var selectMonth = ( .sq_month_id ).value;
    for( var i = 0; i < ; i ++ ){
        spans[i].innerHTML = daysOfMonthArray[i];
        var selectYMD = selectYear + "" + selectMonth + "" + spans[i].innerHTML;
        if( curYMD == selectYMD )
            spans[i].className = ;
        else
            spans[i].className = "";
    }
    // If not some days has pop message
    if( != "" )
        this._initPopMsg( );
}
/* Bind event */
._bindAllEvent = function(){
    var cr = this;
    // 'toPrevMonth, toNextMonth, backToday, today view' event
    ( .prev_month_id ).onclick = function(){ (this); };
    ( .next_month_id ).onclick = function(){ (this); };
    ( .back_today_id ).onclick    = function(){ (); };
    ( .today_view_id ).onclick = function(){ (); };

    // 'year and month select' onchange event
    ( .sq_year_id ).onchange = function(){ (); };
    ( .sq_month_id ).onchange    = function(){ (); };

    // Quick link event
    ( .lq_year_id ).onclick = function(){
        ( .lq_year_id, "none" );
        ( .sq_year_id, "block" );
    };
    ( .lq_month_id ).onclick = function(){
        ( .lq_month_id, "none" );
        ( .sq_month_id, "block" );
    };

    // Remove the link dotted line
    var oLink = ( this.caleContainer_id, "a" )
    for( var i = 0; i < ; i ++ ){
        oLink[i].onfocus = function(){ (); }
    }
}
/* Bind calendar for calendar view */
._initCalendar = function(){
    this._bindAllEvent();
    this._bindAllData( , );
};
/* Change the quick select value */
= function( year, month ){
    var ymArray = [], selectArray = [], linkArray = [];
    // Store the 'year' and 'month' to Array
    ymArray[0] = year; ymArray[1] = month + 1;

    // Store the 'selectYear_id' and 'selectMonth_id' to Array
    selectArray[0] = .sq_year_id; selectArray[1] = .sq_month_id;

    linkArray[0] = .lq_year_id; linkArray[1] = .lq_month_id;

    for( var i = 0; i < ; i ++ ){
        var selectObject = ( selectArray[i] );
        // Get the return index
        var index = this._getOptionIndex( selectObject, ymArray[i] );
        // Reset the 'year', 'month' select and link value
        [index].selected = "selected";

        ( linkArray[i] ).innerHTML = ;
    }

    ();
};
/* Search next or previons month */
= function( obj ){
    var curMonthSelect = ( .sq_month_id );
    var curMonth = parseInt( );
    var curYear = ( .sq_year_id ).value;
    // If 'next' get current month select + 1
    // If 'prev' get current month select - 1
    if( == .next_month_id )
         = curMonth + 1;
    else
         = curMonth - 1;

    var getNowMonth = - 1;
    if( getNowMonth == -1 && curMonth == 1)     getNowMonth = 0;
    if( getNowMonth == -1 && curMonth == 12 )     getNowMonth = 11;

    this._bindAllData( curYear, getNowMonth );
};
/* If 'select:Year' and 'select:Month' change value update data */
= function(){
    var yearSelectValue     = ( .sq_year_id ).value;
    var monthSelectValue = ( .sq_month_id ).value;
    // Re-bind Panel Data
    this._bindAllData( yearSelectValue, monthSelectValue - 1 );

};
/* Back to taday: re-load '_bindAllData()' */
= function(){
    this._bindAllData( , );
};
/* Find the instance object or children of instance object by Id */
= function( elemId, childTag ){
    if( !childTag )
        // Return: object
        return ( elemId );
    else
        // Return: object array
        return ( elemId ).getElementsByTagName( childTag );
};
/* Set element css */
= function( oId, selector ){
    var o = ( oId );
    selector['left']? = selector['left']:"";
    selector['top']? = selector['top']:"";
    selector['position']? = selector['position']:"";
}
/* Check calendar show or hidden */
= function( objectId, dis ){
    return ( objectId ). = dis;
};
/* Init the top quick menu link and select */
= function(){
    ( .sq_year_id, "none" );
    ( .sq_month_id, "none" );
    ( .lq_year_id, "block" );
    ( .lq_month_id, "block" );
};
/* Put this calendar into the html of instance */
= function( msgData ){
    var obj = ( );
    if( obj ){
         = this._getViewElement();
        // Init calendar event and data
        this._initCalendar();

        // This function don't have 'close'
        ( .close_id, "none" );
        if( typeof msgData == 'object'){
             = msgData;
            this._initPopMsg( );
        }
    }
};
/* Init pop message */
._initPopMsg = function(){
    var cr = this;
    var selectYear = ( .sq_year_id ).value;
    var selectMonth = ( .sq_month_id ).value;
    var daysOfMonthArray = this._getMonthViewArray( selectYear, selectMonth );
    var spans = ( this.daysContainer_id, "span" );
    for( var key in ){
        var keyMD = ( 4 );
        var keyY = ( 0, 4 );
        for( var i = 0; i < ; i ++){
            var getMD = selectMonth + "" + spans[i].innerHTML;
            if( getMD == keyMD ){
                if( selectYear == keyY )
                    spans[i].className = +" "+ keyY;
                else
                    spans[i].className = +" "+ keyY;    
                spans[i].onmouseover = function(){
                    var hoverDate = (" ")[1] + "" + selectMonth + "" + ;
                    var y = (" ")[1],
                        m = selectMonth,
                        d = ;
                    ( cr.msgContainer_id ).innerHTML = cr._getMsgHtml( y, m, d );
                    ( cr.msgContainer_id, "block" );
                }
            }
        }
    }
    ( cr.caleContainer_id ).onmouseout = function(){
        ( cr.msgContainer_id, "none" );
    }
};
/* Get message */
._getMsgHtml =function( y, m, d ){
    var date = y + m + d;
    var showDate = y + "-" + m + "-" + d;
    var msgHtml = '<div>'+showDate+':</div><div>'+ [date] +'</div>';
    return msgHtml;
}
/* Pop-up the calendar */
= function(){
    var cr = this;
    var obj    = ( );
    if( obj ){
        // Instance object click then pop-up the calendar
         = function( e ){
            var e = || e;
            var x = || ,
                y = || ;
            if( !( cr.popContainer_id ) ){
                // Create the pop-up div
                var oDiv = ("div");
                 = cr.popContainer_id;
                ( oDiv );
            }else{
                ( cr.popContainer_id, "block" );
            }
            ( cr.popContainer_id ).innerHTML = cr._getViewElement();

            // Init calendar event and data
            cr._initCalendar();

            // Set days click event
            ( obj );

            // Set position
            ( cr.popContainer_id, {position: "absolute", left: x + "px", top: y + "px"});

            // Close panel event
            ( .close_id ).onclick = function(){ ( cr.popContainer_id, "none" ); };
        };
    }
};
/* Click the pop calendar days event [For INPUT] */
= function( obj ){
    var cr = this;
    var spans = ( cr.daysContainer_id, "span" );
    for( var i = 0; i < ; i ++ )
        spans[i].onclick = function(){
            if( != "&nbsp;" ){
                var getYear     = ( .sq_year_id ).value;
                var getMonth = ( .sq_month_id ).value;
                 = getYear +"-"+ getMonth +"-" + ;
                ( cr.popContainer_id, "none" );
            }
        }
};