自己动手做WEB控件(二)

来源:互联网 发布:广联达装饰预算软件 编辑:程序博客网 时间:2024/06/08 22:31

上次写了一个《自己动手做WEB控件》引来众多网友评论,更有几个朋友指出问题,非常感谢大家。

其实上篇只是一个简单的用户自定义控件,后来项目中的日历我是用JS重写的,并且用的是WEB控件,现贴出来同大家分享:

JS:

// JScript 文件
<!--
//本程序根据好友提供的代码改造而来!
//wrt by lw 2010-3-8

var preImg_Month="";
var preImg_Year="";
var nextImg_Month="";
var nextImg_Year="";

var curShowCalendar;                //当前激活的日历控件
var allowCloseCalendar = 0;         //是否允许关闭当前激活的日历控件

//显示日历:
function activeCalendar(inputControlID,language,imgObj)
{
    eval(inputControlID+"_obj=new createCalendarObject('"+inputControlID+"')");
    eval(inputControlID+"_obj.calendarSpan=imgObj.nextSibling");
    eval(inputControlID+"_obj.language='"+language+"'");
    eval(inputControlID+"_obj.showDateTable()"); 
}

//显示日历选择表:
function showDateTable()
{
    this.calendarSpan.style.visibility="visible";
    this.calendarSpan.style.border="2px solid #cacaca";
    this.createDateTable();
}

//创建日历选择框:
function createDateTable()
{
    var str="";
    var obj=this;
//    str+=" <table  onmouseover='"+this.inputID+"_obj.stopTimer();' onmouseout='"+this.inputID+"_obj.startTimer()'>"; //使用定时关闭
    str+=" <table style=/"font-size:16px/">";
    var preMonth=this.month - 1;
    if(preMonth <=0)
        preMonth=12;
    var nextMonth=this.month + 1;
    if(nextMonth>12)
        nextMonth=1;
    str+="<tr bgcolor=#d0d1f6 onclick='allowCloseCalendar = 0;'> " +
            "<td align='center' onclick='allowCloseCalendar = 0;'>" +
                "<img title='" + Number(this.year-1) + "' onmouseover='this.style.cursor=/"pointer/"'  src='" + preImg_Year + "' onclick='"
                                                        +this.inputID+"_obj.goToPrevYear()' />" +
            "</td>" +
            "<td align='center' onclick='allowCloseCalendar = 0;'>" +
                "<img title='"+Number(preMonth) + "' onmouseover='this.style.cursor=/"pointer/"' src='" + preImg_Month +
                                    "'onclick='"+this.inputID + "_obj.goToPrevMonth()' />" +
            "</td>" +
            "<td colspan='3' align='center' onclick='allowCloseCalendar = 0;'>"+this.year + "年" + this.month + "月" +
            "</td>" +
            "<td align='center' onclick='allowCloseCalendar = 0;'>" +
                "<img title=/""+nextMonth+"/" onmouseover='this.style.cursor=/"pointer/"' src='" + nextImg_Month
                    +"' onclick='"+this.inputID+"_obj.goToNextMonth()' />" +
            "</td>" +
            "<td align='center' onclick='allowCloseCalendar = 0;'>" +
                "<img title='"+Number(this.year+1) + "' onmouseover='this.style.cursor=/"pointer/"' src='" + nextImg_Year
                            +"' onclick='"+this.inputID+"_obj.goToNextYear()' />" +
            "</td></tr>";
    var langRow="";
    if(this.language=="en")
        langRow="<tr bgcolor=#d0d1f6 onclick='allowCloseCalendar = 0;'><td onclick='allowCloseCalendar = 0;'>Su</td>" +
                    "<td onclick='allowCloseCalendar = 0;'>Mo</td><td onclick='allowCloseCalendar = 0;'>Tu</td>" +
                    "<td onclick='allowCloseCalendar = 0;'>We</td><td onclick='allowCloseCalendar = 0;'>Th</td>" +
                    "<td onclick='allowCloseCalendar = 0;'>Fr</td><td onclick='allowCloseCalendar = 0;'>Sa</td></tr>";
    if(this.language=="zh") 
        langRow="<tr bgcolor=#f6e7d0 onclick='allowCloseCalendar = 0;'>" +
                "<td onclick='allowCloseCalendar = 0;' align='center' width=30px>日</td> " +
                "<td onclick='allowCloseCalendar = 0;' align='center' width=30px>一</td>" +
                "<td onclick='allowCloseCalendar = 0;' align='center' width=30px>二</td>" +
                "<td onclick='allowCloseCalendar = 0;' align='center' width=30px>三</td>" +
                "<td onclick='allowCloseCalendar = 0;' align='center' width=30px>四</td>" +
                "<td onclick='allowCloseCalendar = 0;' align='center' width=30px>五</td>" +
                "<td onclick='allowCloseCalendar = 0;' align='center' width=30px>六</td> </tr>";
    str += langRow;
 
    var monthDaysArr = [31,28,31,30,31,30,31,31,30,31,30,31];
    var dateObj = new Date(this.year,this.month-1,1);
    var firstDay = dateObj.getDay();
    var dayCountAtFirstRow = 7 - firstDay; //第1行的天数
    var rowCount=0;

    //闰年的计算方法:公元纪年的年数可以被四整除,即为闰年;被100整除而不能被400整除为平年;被100整除也可被400整除的为闰年。
    var daysOfThisMonth;    //本月天数
    if (this.month == 2)
        daysOfThisMonth = ((0 == this.year % 4) && (0 != (this.year % 100))) ||(0 == this.year % 400) ? 29 : 28;
    else
        daysOfThisMonth = monthDaysArr[this.month-1];
       
    var restDayCount = daysOfThisMonth - dayCountAtFirstRow; //除第1行外的天数

    //今天:
    var today = new Date();
    var todayDate = today.getDate();
    var todayYear = today.getFullYear();
    var todayMonth = today.getMonth()+1;
   
    if(restDayCount%7==0)
        rowCount=restDayCount/7+1;
    else
        rowCount=Math.floor(restDayCount/7)+2;
       
    for(var i=0;i <rowCount;i++)
    {
        if(i==0)    //第一行特殊处理
        {
            str+="<tr onclick='allowCloseCalendar = 0;'>";
            for(var k=1;k <=7;k++)
            {
                if (k <= firstDay)
                    str+=" <td onclick='allowCloseCalendar = 0;'></td>";
                else
                {
                    if(this.year==todayYear && this.month==todayMonth && (k-firstDay)==todayDate)   //今天特殊显示
                        str+="<td align='center' style='background:red;' onmouseover='this.style.cursor=/"pointer/";" +
                                    "this.style.borderLeft=/"1px solid gray/";this.style.borderTop=/"1px solid gray/";' " +
                                    "onmouseout='this.style.borderLeft=/"0px solid white/";this.style.borderTop=/"0px solid white/";'" +
                                    " onclick='"+this.inputID+"_obj.fillInDate(/""+(k-firstDay)+"/")'>"+(k-firstDay)+
                             "</td>";//onmouseout='this.style.borderLeft=/"1px solid white/";this.style.borderTop=/"1px solid white/"'
                    else
                        str+="<td align='center' onmouseover='this.style.cursor=/"pointer/";this.style.borderLeft=/"1px solid gray/";" +
                                    "this.style.borderTop=/"1px solid gray/";' onmouseout='this.style.borderLeft=/"0px solid white/";" +
                                    "this.style.borderTop=/"0px solid white/";' " +
                                    "onclick='"+this.inputID+"_obj.fillInDate(/""+(k-firstDay)+"/")'>"+(k-firstDay) +
                             "</td>";//onmouseout='this.style.borderLeft=/"1px solid white/";this.style.borderTop=/"1px solid white/"'
                }
            }
            str+=" </tr>";
        }
        else
        {
            str+=" <tr onclick='allowCloseCalendar = 0;'>";
            for(var k=1;k <=7;k++)
            {
                var currentDay=(i-1)*7+k+dayCountAtFirstRow;
                if(currentDay <= daysOfThisMonth)
                {
                    if(this.year==todayYear&&this.month==todayMonth&&currentDay==todayDate) //今天特殊显示
                        str += "<td align='center' style='background:red;' onmouseover='this.style.cursor=/"pointer/";" +
                                    "this.style.borderLeft=/"1px solid gray/";this.style.borderTop=/"1px solid gray/";'" +
                                    " onmouseout='this.style.borderLeft=/"0px solid white/";this.style.borderTop=/"0px solid white/";'  " +
                                    "onclick='"+this.inputID+"_obj.fillInDate(/""+currentDay+"/")'>"+currentDay+"</td>" ;
                    else
                        str+=" <td align='center' onmouseover='this.style.cursor=/"pointer/";this.style.borderLeft=/"1px solid gray/";" +
                                    "this.style.borderTop=/"1px solid gray/";' onmouseout='this.style.borderLeft=/"0px solid white/";" +
                                    "this.style.borderTop=/"0px solid white/";'  " +
                                    "onclick='"+this.inputID+"_obj.fillInDate(/""+currentDay+"/")'>"+currentDay+"</td>" ;
                }
                else
                {
                    str += "<td onclick='allowCloseCalendar = 0;'></td>";
                }
            }
            str+=" </tr>";
        }
    }
    str+=" </table>";
    this.calendarSpan.innerHTML=str;
//    //调试用的文本框:
//    var p = document.getElementById("TextBox1");
//    p.value = str;

//    this.stopTimer();
}

//前一月:
//wrt by lw 2010-3-8
function goToPrevMonth()
{
    if(this.month > 1)
        this.month--;
    else
    {
        this.month=12;
        this.year--;
    }
    this.createDateTable();
}

//前一年:
function goToPrevYear()
{
    this.year--;
    this.month=12;
    this.createDateTable();
}

//后一月:
function goToNextMonth()
{
    if(this.month <12)
        this.month++;
    else
    {
        this.month=1;
        this.year++;
    }
    this.createDateTable();
}

//后一年:
function goToNextYear()
{
    this.year++;
    this.month=1;
    this.createDateTable();
}

//显示选择的日历:
function fillInDate(date)
{
    this.inputControl.value=this.year+"-"+this.month+"-"+date;
    this.calendarSpan.style.visibility="hidden";
}

//关闭弹出窗口:
function closeMe()
{
    if (this.calendarSpan != null)
        this.calendarSpan.style.visibility="hidden";
}

//创建日历对象:
function createCalendarObject(inputControlID)
{
    this.inputID=inputControlID;
    this.language="zh";
    this.format="YYYY-MM-DD";
    var today=new Date();
    this.year=today.getFullYear();
    this.month=today.getMonth()+1;
    this.date=today.getDate();
    this.day=today.getDay();
    this.calendarSpan=null;
    this.interval=null;
    this.inputControl=document.getElementById(this.inputID);
 
    this.createDateTable=createDateTable;
    this.goToPrevMonth=goToPrevMonth;
    this.goToPrevYear=goToPrevYear;
    this.goToNextMonth=goToNextMonth;
    this.goToNextYear=goToNextYear;
    this.showDateTable=showDateTable;
    this.fillInDate=fillInDate;
   
    curShowCalendar = this;
    allowCloseCalendar = 0;
    this.closeMe = closeMe;

    //自动定时关闭
//    this.startTimer=startTimer;
//    this.stopTimer=stopTimer;
}

//在其他地方鼠标click关闭日历:
//wrt by lw 2010-3-8
function document.onclick()
{
    if(allowCloseCalendar == 1 && curShowCalendar != null)
    {
        curShowCalendar.closeMe();
        curShowCalendar = null;
    }       
    else
    {
        allowCloseCalendar= 1;
    }
}

var isKeyDownClear=0;   //清除按键的判断开关量
//按ESC键关闭日历:
//wrt by lw 2010-3-8
function document.onkeydown()
{
    var e = event? event:window.event;
    if(e.keyCode == 27 && curShowCalendar != null)
        curShowCalendar.closeMe();
}


//日期格式检查:
//wrt by lw 2010-3-8
function regexpCheck()
{
    e = event? event:window.event;
    if (e.keyCode == 13 || e.keyCode == 9)
    {
        var s = e.srcElement.value;
//        //格式:YYYY-MM-DD
//        var r= new RegExp("(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})" +
//                          "[-/](((0[13578]|1[02])[-/](0[1-9]|[12][0-9]|3[01]))" + //大月
//                          "|((0[469]|11)[-/](0[1-9]|[12][0-9]|30))" +  //小月
//                          "|(02[-/](0[1-9]|[1][0-9]|2[0-8]))))" +  //2月28号以前的日期
//                          "|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))[-/]02[-/]29)");//闰年处理
//        if (!(r.test(s) && s.match(r)[0]==s))
//        {
//            e.srcElement.value = "你输入的日期格式不对!";
//            e.srcElement.select();
//            e.srcElement.focus();
//        }
        var r= new Array;
        //格式:YYYY-MM-DD:
        r[0] = new RegExp("(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})" +
               "[-/](((0[13578]|1[02])[-/](0[1-9]|[12][0-9]|3[01]))" + //大月
               "|((0[469]|11)[-/](0[1-9]|[12][0-9]|30))" +  //小月
               "|(02[-/](0[1-9]|[1][0-9]|2[0-8]))))" +  //2月28号以前的日期
               "|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))[-/]02[-/]29)");//闰年处理
        //格式:YYYY-M-DD:
        r[1] = new RegExp("(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})" +
               "[-/](([13578][-/](0[1-9]|[12][0-9]|3[01]))" + //大月
               "|([469][-/](0[1-9]|[12][0-9]|30))" +  //小月
               "|(2[-/](0[1-9]|[1][0-9]|2[0-8]))))" +  //2月28号以前的日期
               "|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))[-/]2[-/]29)");//闰年处理
        //格式:YYYY-MM-D:
        r[2] = new RegExp("([0-9]{4}[-/](0[123456789]|1[012])[-/][1-9])");
        //格式:YYYY-M-D:
        r[3] = new RegExp("([0-9]{4}[-/][123456789][-/][1-9])");
        for (var i = 0; i < 4; i++)
        {
            if (r[i].test(s) && s.match(r[i])[0]==s)
            {
                r = null;
                return true;
            }
        }
        e.srcElement.value = "你输入的日期格式不对!";
        e.srcElement.select();
        e.srcElement.focus();
        r = null;
        e.keyCode = 0;
        e.returnValue=false;
        return false;
    }
}

//-->

js代码感谢limii提供的思路,我修正了一些错误,增加了窗口关闭的处理,原来他给的方案自动定时关闭不好;另增加了日期的格式检查,现基本可以处理1600年内的闰年了,但是好像更多的情况还有些问题。欢迎大家讨论。

 

后台的构造函数如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

[assembly: WebResource("myTools.images.calendar.jpg", "image/jpeg")]
[assembly: WebResource("myTools.images.calendar_next.gif", "image/gif")]
[assembly: WebResource("myTools.images.calendar_nextYear.gif", "image/gif")]
[assembly: WebResource("myTools.images.calendar_prev.gif", "image/gif")]
[assembly: WebResource("myTools.images.calendar_prevYear.gif", "image/gif")]
[assembly: WebResource("myTools.scripts.calendar.js", "application/x-javascript")]
namespace myTools
{

    //[DefaultProperty("Date")]
    [ToolboxData("<{0}:myCalendar runat=server></{0}:myCalendar>")]
    [System.Drawing.ToolboxBitmap(typeof(myTools.Resources.Icon), "calendar.jpg")]
    public class myCalendar : Control
    {
        //选择的日期:
        private string _date = "";
        public string Date
        {
            get { return this._date; }
            set { this._date = value; }
        }
        //日期语言:
        public enum DateLang { en, zh };
        private DateLang language = DateLang.zh;
        public DateLang Language
        {
            get { return this.language; }
            set { this.language = value; }
        }
        //日期格式:
        private string format = "YYYY-MM-DD";//DateFormat.format1;
        public string Format
        {
            get { return this.format; }
            set { this.format = value; }
        }
        //输入栏宽度:
        private string _width = "100px";
        public string width
        {
            get { return this._width; }
            set { this._width = value; }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            string imgPath = Page.ClientScript.GetWebResourceUrl(this.GetType(), "myTools.images.calendar.jpg");

            string strControl = "<input type='text' name='" + this.ID + "' id='" + this.ID + "' " +
                                    " value='" + _date + "' onkeydown='regexpCheck();' style=/"width:" + _width + "/"  />" +   //输入框'
                                "<img src='" + imgPath + "' onmouseover='this.style.cursor=/"pointer/"'" +
                                " onclick='activeCalendar(/"" + this.ID + "/",/"" + this.Language.ToString() + "/",this)'/>" +          //下拉按钮
                                "<span id='dateSpan_" + this.ID + "' style='position:absolute;z-index:9999;width:240px;height:180px;" + //弹出窗口
                                            "border:2px solid gray;background:#E5E7EB;visibility:hidden;margin:0 auto;'>" +
                                "</span>";

            writer.Write(strControl);
        }

        protected override void OnLoad(EventArgs e)
        {
            if (Page.IsPostBack)
                this.Date = Page.Request[this.ID];
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            //注入JS:
            ClientScriptManager cs = Page.ClientScript;
            cs.RegisterClientScriptResource(this.GetType(), "myTools.scripts.calendar.js");

            //注入图片:
            string prevMonth = Page.ClientScript.GetWebResourceUrl(this.GetType(), "myTools.images.calendar_prev.gif");
            string prevYear = Page.ClientScript.GetWebResourceUrl(this.GetType(), "myTools.images.calendar_prevYear.gif");
            string nextMonth = Page.ClientScript.GetWebResourceUrl(this.GetType(), "myTools.images.calendar_next.gif");
            string nextYear = Page.ClientScript.GetWebResourceUrl(this.GetType(), "myTools.images.calendar_nextYear.gif");
            Page.ClientScript.RegisterStartupScript(this.GetType(), "image", "<script type='text/javascript'>preImg_Month='" + prevMonth
                                + "';preImg_Year='" + prevYear + "';nextImg_Month='" + nextMonth + "';nextImg_Year='" + nextYear + "'</script>");
        }
    }

}
整个项目的文件我打包放在了我的资源空间里了,需要使用的朋友请去下载!

原创粉丝点击