打造基于jQuery的日期选择控件(上)


终于把jQuery拼写正确了哈,哈哈javascript也是区分大小写的,所以确实不能写错,今天我来和大家分享的是日期选择控件的实现,功能也许不够强大,但是能够满足需求。

  我之前也写过,看下截图哈,也很酷的,windows风格哦。

  

  但是也有些问题,第一画日历有点慢,第二兼容性不太好IE Only,第三它不是基于jQuery的哈哈。

  那还是老规矩,做之前先看下效果

   

  这下是更酷的Ext风格了。

  从上图我们可以看出这个控件其实有两个视图一个日期月视图,还有一个是年月选择视图。

  1:还是先从HTML入手

  日期控件确定HTML其实还是比较简单,因为明摆着是列表的数据格式,当然主要是采用table了。

  两个视图分别用两个Div包裹,控制div的显示隐藏即可以切换视图了。完整的HTMl结构大家可以用IEDeveloper看一下Demo的结构,我自己截了一个图

  

2:根据HTML和效果图编写CSS

  其实因为是Ext风格的,所以直接copy的ext的css和图片。。

  CSS也就不分析了,直接上代码。

  因为博客园的语法高亮不支持CSS,所以就不贴出来了,给个下载地址吧:

  http://xuanye.cloudapp.net/Theme/Default/dp.css

  所有用到的图片:

  

  3:搞定了CSS之后呢,就开始编写我们javascript了。

  上来就是一个完整代码

001.;(function($) {
002.    var userAgent = window.navigator.userAgent.toLowerCase();
003.    $.browser.msie8 = $.browser.msie && /msie 8\.0/i.test(userAgent);
004.    $.browser.msie7 = $.browser.msie && /msie 7\.0/i.test(userAgent);
005.    $.browser.msie6 = !$.browser.msie8 && !$.browser.msie7 && $.browser.msie && /msie 6\.0/i.test(userAgent);
006. 
007.    Date.prototype.Format = function(format) {
008.        var o = {
009.            "M+": this.getMonth() + 1,
010.            "d+": this.getDate(),
011.            "h+": this.getHours(),
012.            "H+": this.getHours(),
013.            "m+": this.getMinutes(),
014.            "s+": this.getSeconds(),
015.            "q+": Math.floor((this.getMonth() + 3) / 3),
016.            "w": "0123456".indexOf(this.getDay()),
017.            "S": this.getMilliseconds()
018.        };
019.        if (/(y+)/.test(format)) {
020.            format = format.replace(RegExp.{GetProperty(Content)}, (this.getFullYear() + "").substr(4 - RegExp.{GetProperty(Content)}.length));
021.        }
022.        for (var k in o) {
023.            if (new RegExp("(" + k + ")").test(format))
024.                format = format.replace(RegExp.{GetProperty(Content)},
025.          RegExp.{GetProperty(Content)}.length == 1 ? o[k] :
026.            ("00" + o[k]).substr(("" + o[k]).length));
027.        }
028.        return format;
029.    };
030.    function DateAdd(interval, number, idate) {
031.        number = parseInt(number);
032.        var date;
033.        if (typeof (idate) == "string") {
034.            date = idate.split(/\D/);
035.            eval("var date = new Date(" + date.join(",") + ")");
036.        }
037. 
038.        if (typeof (idate) == "object") {
039.            date = new Date(idate.toString());
040.        }
041.        switch (interval) {
042.            case "y": date.setFullYear(date.getFullYear() + number); break;
043.            case "m": date.setMonth(date.getMonth() + number); break;
044.            case "d": date.setDate(date.getDate() + number); break;
045.            case "w": date.setDate(date.getDate() + 7 * number); break;
046.            case "h": date.setHours(date.getHours() + number); break;
047.            case "n": date.setMinutes(date.getMinutes() + number); break;
048.            case "s": date.setSeconds(date.getSeconds() + number); break;
049.            case "l": date.setMilliseconds(date.getMilliseconds() + number); break;
050.        }
051.        return date;
052.    };
053.    $.fn.datepicker = function(o) {
054.        var def = {
055.            weekStart: 0,
056.            weekName: ["日", "一", "二", "三", "四", "五", "六"], //星期的格式
057.            monthName: ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"], //月份的格式
058.            monthp: "月",
059.            Year: new Date().getFullYear(), //定义年的变量的初始值
060.            Month: new Date().getMonth() + 1, //定义月的变量的初始值
061.            Day: new Date().getDate(), //定义日的变量的初始值
062.            today: new Date(),
063.            btnOk: " 确定 ",
064.            btnCancel: " 取消 ",
065.            btnToday: "今天",
066.            inputDate: null,
067.            onReturn: false,
068.            version: "1.1",
069.            applyrule: false, //function(){};return rule={startdate,endate};
070.            showtarget: null,
071.            picker: ""
072.        };
073.        $.extend(def, o);
074.        var cp = $("#BBIT_DP_CONTAINER");
075.        if (cp.length == 0) {
076.            var cpHA = [];
077.            cpHA.push("<div id='BBIT_DP_CONTAINER' class='bbit-dp' style='width:175px;z-index:999;'>");
078.            if ($.browser.msie6) {
079.                cpHA.push('<iframe style="position:absolute;z-index:-1;width:100%;height:100%;top:0;left:0;scrolling:no;" frameborder="0" src="about:blank"></iframe>');
080.            }
081.            cpHA.push("<table class='dp-maintable' cellspacing='0' cellpadding='0' style='width:175px;'><tbody><tr><td>");
082.            //头哟
083.            cpHA.push("<table class='bbit-dp-top' cellspacing='0'><tr><td class='bbit-dp-top-left'> <a id='BBIT_DP_LEFTBTN' href='javascript:void(0);' title='向前一个月'>&nbsp;</a></td><td class='bbit-dp-top-center' align='center'><em><button id='BBIT_DP_YMBTN'>九月 2009</button></em></td><td class='bbit-dp-top-right'><a id='BBIT_DP_RIGHTBTN' href='javascript:void(0);' title='向后一个月'>&nbsp;</a></td></tr></table& gt;");
084.            cpHA.push("</td></tr>");
085.            cpHA.push("<tr><td>");
086.            //周
087.            cpHA.push("<table id='BBIT_DP_INNER' class='bbit-dp-inner' cellspacing='0'><thead><tr>");
088.            //生成周
089.            for (var i = def.weekStart, j = 0; j < 7; j++) {
090.                cpHA.push("<th><span>", def.weekName[i], "</span></th>");
091.                if (i == 6) { i = 0; } else { i++; }
092.            }
093.            cpHA.push("</tr></thead>");
094.            //生成tBody,需要重新生成的
095.            cpHA.push("<tbody></tbody></table>");
096.            //生成tBody结束
097.            cpHA.push("</td></tr>");
098.            cpHA.push("<tr><td class='bbit-dp-bottom' align='center'><button id='BBIT-DP-TODAY'>", def.btnToday, "</button></td></tr>");
099.            cpHA.push("</tbody></table>");
100.            //输出下来框
101.            cpHA.push("<div id='BBIT-DP-MP' class='bbit-dp-mp'  style='z-index:auto;'><table id='BBIT-DP-T' style='width: 175px; height: 193px' border='0' cellspacing='0'><tbody>");
102.            cpHA.push("<tr>");
103.            //1月,7月 按钮两个
104.            cpHA.push("<td class='bbit-dp-mp-month' xmonth='0'><a href='javascript:void(0);'>", def.monthName[0], "</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='6'><a href='javascript:void(0);'>", def.monthName[6], "</a></td><td class='bbit-dp-mp-ybtn' align='middle'><a id='BBIT-DP-MP-PREV' class='bbit-dp-mp-prev'></a></td><td class='bbit-dp-mp-ybtn' align='middle'><a id='BBIT-DP-MP-NEXT' class='bbit-dp-mp-next'></a></td>");
105.            cpHA.push("</tr>");
106.            cpHA.push("<tr>");
107.            cpHA.push("<td class='bbit-dp-mp-month' xmonth='1'><a href='javascript:void(0);'>", def.monthName[1], "</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='7'><a href='javascript:void(0);'>", def.monthName[7], "</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>");
108.            cpHA.push("</tr>");
109.            cpHA.push("<tr>");
110.            cpHA.push("<td class='bbit-dp-mp-month' xmonth='2'><a href='javascript:void(0);'>", def.monthName[2], "</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='8'><a href='javascript:void(0);'>", def.monthName[8], "</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>");
111.            cpHA.push("</tr>");
112.            cpHA.push("<tr>");
113.            cpHA.push("<td class='bbit-dp-mp-month' xmonth='3'><a href='javascript:void(0);'>", def.monthName[3], "</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='9'><a href='javascript:void(0);'>", def.monthName[9], "</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>");
114.            cpHA.push("</tr>");
115. 
116.            cpHA.push("<tr>");
117.            cpHA.push("<td class='bbit-dp-mp-month' xmonth='4'><a href='javascript:void(0);'>", def.monthName[4], "</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='10'><a href='javascript:void(0);'>", def.monthName[10], "</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>");
118.            cpHA.push("</tr>");
119. 
120.            cpHA.push("<tr>");
121.            cpHA.push("<td class='bbit-dp-mp-month' xmonth='5'><a href='javascript:void(0);'>", def.monthName[5], "</a></td><td class='bbit-dp-mp-month bbit-dp-mp-sep' xmonth='11'><a href='javascript:void(0);'>", def.monthName[11], "</a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td><td class='bbit-dp-mp-year'><a href='javascript:void(0);'></a></td>");
122.            cpHA.push("</tr>");
123.            cpHA.push("<tr class='bbit-dp-mp-btns'>");
124.            cpHA.push("<td colspan='4'><button id='BBIT-DP-MP-OKBTN' class='bbit-dp-mp-ok'>", def.btnOk, "</button><button id='BBIT-DP-MP-CANCELBTN' class='bbit-dp-mp-cancel'>", def.btnCancel, "</button></td>");
125.            cpHA.push("</tr>");
126. 
127.            cpHA.push("</tbody></table>");
128.            cpHA.push("</div>");
129.            cpHA.push("</div>");
130. 
131.            var s = cpHA.join("");
132.            $(document.body).append(s);
133.            var cp = $("#BBIT_DP_CONTAINER");
134. 
135.            initevents();
136.        }
137.        function initevents() {
138.            //1 today btn;
139.            $("#BBIT-DP-TODAY").click(returntoday);
140.            cp.click(returnfalse);
141.            $("#BBIT_DP_INNER tbody").click(tbhandler);
142.            $("#BBIT_DP_LEFTBTN").click(prevm);
143.            $("#BBIT_DP_RIGHTBTN").click(nextm);
144.            $("#BBIT_DP_YMBTN").click(showym);
145.            $("#BBIT-DP-MP").click(mpclick);
146.            $("#BBIT-DP-MP-PREV").click(mpprevy);
147.            $("#BBIT-DP-MP-NEXT").click(mpnexty);
148.            $("#BBIT-DP-MP-OKBTN").click(mpok);
149.            $("#BBIT-DP-MP-CANCELBTN").click(mpcancel);
150.        }
151.        function mpcancel() {
152.            $("#BBIT-DP-MP").animate({ top: -193 }, { duration: 200, complete: function() { $("#BBIT-DP-MP").hide(); } });
153.            return false;
154.        }
155.        function mpok() {
156.            def.Year = def.cy;
157.            def.Month = def.cm + 1;
158.            def.Day = 1;
159.            $("#BBIT-DP-MP").animate({ top: -193 }, { duration: 200, complete: function() { $("#BBIT-DP-MP").hide(); } });
160.            writecb();
161.            return false;
162.        }
163.        function mpprevy() {
164.            var y = def.ty - 10
165.            def.ty = y;
166.            rryear(y);
167.            return false;
168.        }
169.        function mpnexty() {
170.            var y = def.ty + 10
171.            def.ty = y;
172.            rryear(y);
173.            return false;
174.        }
175.        function rryear(y) {
176.            var s = y - 4;
177.            var ar = [];
178.            for (var i = 0; i < 5; i++) {
179.                ar.push(s + i);
180.                ar.push(s + i + 5);
181.            }
182.            $("#BBIT-DP-MP td.bbit-dp-mp-year").each(function(i) {
183.                if (def.Year == ar[i]) {
184.                    $(this).addClass("bbit-dp-mp-sel");
185.                }
186.                else {
187.                    $(this).removeClass("bbit-dp-mp-sel");
188.                }
189.                $(this).html("<a href='javascript:void(0);'>" + ar[i] + "</a>").attr("xyear", ar[i]);
190.            });
191.        }
192.        function mpclick(e) {
193.            var panel = $(this);
194.            var et = e.target || e.srcElement;
195.            var td = getTd(et);
196.            if (td == null) {
197.                return false;
198.            }
199.            if ($(td).hasClass("bbit-dp-mp-month")) {
200.                if (!$(td).hasClass("bbit-dp-mp-sel")) {
201.                    var ctd = panel.find("td.bbit-dp-mp-month.bbit-dp-mp-sel");
202.                    if (ctd.length > 0) {
203.                        ctd.removeClass("bbit-dp-mp-sel");
204.                    }
205.                    $(td).addClass("bbit-dp-mp-sel")
206.                    def.cm = parseInt($(td).attr("xmonth"));
207.                }
208.            }
209.            if ($(td).hasClass("bbit-dp-mp-year")) {
210.                if (!$(td).hasClass("bbit-dp-mp-sel")) {
211.                    var ctd = panel.find("td.bbit-dp-mp-year.bbit-dp-mp-sel");
212.                    if (ctd.length > 0) {
213.                        ctd.removeClass("bbit-dp-mp-sel");
214.                    }
215.                    $(td).addClass("bbit-dp-mp-sel")
216.                    def.cy = parseInt($(td).attr("xyear"));
217.                }
218.            }
219.            return false;
220.        }
221.        function showym() {
222.            var mp = $("#BBIT-DP-MP");
223.            var y = def.Year;
224.            def.cy = def.ty = y;
225.            var m = def.Month - 1;
226.            def.cm = m;
227.            var ms = $("#BBIT-DP-MP td.bbit-dp-mp-month");
228.            for (var i = ms.length - 1; i >= 0; i--) {
229.                var ch = $(ms[i]).attr("xmonth");
230.                if (ch == m) {
231.                    $(ms[i]).addClass("bbit-dp-mp-sel");
232.                }
233.                else {
234.                    $(ms[i]).removeClass("bbit-dp-mp-sel");
235.                }
236.            }
237.            rryear(y);
238.            mp.css("top", -193).show().animate({ top: 0 }, { duration: 200 });
239.        }
240.        function getTd(elm) {
241.            if (elm.tagName.toUpperCase() == "TD") {
242.                return elm;
243.            }
244.            else if (elm.tagName.toUpperCase() == "BODY") {
245.                return null;
246.            }
247.            else {
248.                var p = $(elm).parent();
249.                if (p.length > 0) {
250.                    if (p[0].tagName.toUpperCase() != "TD") {
251.                        return getTd(p[0]);
252.                    }
253.                    else {
254.                        return p[0];
255.                    }
256.                }
257.            }
258.            return null;
259.        }
260.        function tbhandler(e) {
261.            var et = e.target || e.srcElement;
262.            var td = getTd(et);
263.            if (td == null) {
264.                return false;
265.            }
266.            var $td = $(td);
267.            if (!$(td).hasClass("bbit-dp-disabled")) {
268.                var s = $td.attr("xdate");
269.                var arrs = s.split("-");
270.                cp.data("indata", new Date(arrs[0], parseInt(arrs[1], 10) - 1, arrs[2]));
271.                returndate();
272.            }
273.            return false;
274.        }
275.        function returnfalse() {
276.            return false;
277.        }
278.        function prevm() {
279.            if (def.Month == 1) {
280.                def.Year--;
281.                def.Month = 12;
282.            }
283.            else {
284.                def.Month--
285.            }
286.            writecb();
287.            return false;
288.        }
289.        function nextm() {
290.            if (def.Month == 12) {
291.                def.Year++;
292.                def.Month = 1;
293.            }
294.            else {
295.                def.Month++
296.            }
297.            writecb();
298.            return false;
299.        }
300.        function returntoday() {
301.            cp.data("indata", new Date());
302.            returndate();
303.        }
304.        function returndate() {
305.            var ct = cp.data("ctarget");
306.            var ck = cp.data("cpk");
307.            var re = cp.data("onReturn");
308.            var ndate = cp.data("indata")
309.            var ads = cp.data("ads");
310.            var ade = cp.data("ade");
311.            var dis = false;
312.            if (ads && ndate < ads) {
313.                dis = true;
314.            }
315.            if (ade && ndate > ade) {
316.                dis = true;
317.            }
318.            if (dis) {
319.                return;
320.            }
321.            if (re && jQuery.isFunction(re)) {
322.                re.call(ct[0], cp.data("indata"));
323.            }
324.            else {
325.                ct.val(cp.data("indata").Format("yyyy-MM-dd"));
326.            }
327.            ck.attr("isshow", "0");
328.            cp.removeData("ctarget").removeData("cpk").removeData("indata").removeData("onReturn")
329.            .removeData("ads").removeData("ade");
330.            cp.css("visibility", "hidden");
331.            ct = ck = null;
332.        }
333.        function writecb() {
334.            var tb = $("#BBIT_DP_INNER tbody");
335.            $("#BBIT_DP_YMBTN").html(def.monthName[def.Month - 1] + def.monthp + " " + def.Year);
336.            var firstdate = new Date(def.Year, def.Month - 1, 1);
337. 
338.            var diffday = def.weekStart - firstdate.getDay();
339.            var showmonth = def.Month - 1;
340.            if (diffday > 0) {
341.                diffday -= 7;
342.            }
343.            var startdate = DateAdd("d", diffday, firstdate);
344.            var enddate = DateAdd("d", 42, startdate);
345.            var ads = cp.data("ads");
346.            var ade = cp.data("ade");
347.            var bhm = [];
348.            var tds = def.today.Format("yyyy-MM-dd");
349.            var indata = cp.data("indata");
350.            var ins = indata != null ? indata.Format("yyyy-MM-dd") : "";
351.            for (var i = 1; i <= 42; i++) {
352.                if (i % 7 == 1) {
353.                    bhm.push("<tr>");
354.                }
355.                var ndate = DateAdd("d", i - 1, startdate);
356.                var tdc = [];
357.                var dis = false;
358.                if (ads && ndate < ads) {
359.                    dis = true;
360.                }
361.                if (ade && ndate > ade) {
362.                    dis = true;
363.                }
364.                if (ndate.getMonth() < showmonth) {
365.                    tdc.push("bbit-dp-prevday");
366.                }
367.                else if (ndate.getMonth() > showmonth) {
368.                    tdc.push("bbit-dp-nextday");
369.                }
370. 
371.                if (dis) {
372.                    tdc.push("bbit-dp-disabled");
373.                }
374.                else {
375.                    tdc.push("bbit-dp-active");
376.                }
377. 
378.                var s = ndate.Format("yyyy-MM-dd");
379.                if (s == tds) {
380.                    tdc.push("bbit-dp-today");
381.                }
382.                if (s == ins) {
383.                    tdc.push("bbit-dp-selected");
384.                }
385. 
386.                bhm.push("<td class='", tdc.join(" "), "' title='", ndate.Format("yyyy-MM-dd"), "' xdate='", ndate.Format("yyyy-M-d"), "'><a href='javascript:void(0);'><em><span>", ndate.getDate(), "</span></em></a></td>");
387.                if (i % 7 == 0) {
388.                    bhm.push("</tr>");
389.                }
390.            }
391.            tb.html(bhm.join(""));
392.        }
393.        var dateReg = /^(\d{1,4})(-|\/|.)(\d{1,2})\2(\d{1,2})$/;
394. 
395.        return $(this).each(function() {
396. 
397.            var obj = $(this).addClass("bbit-dp-input");
398.            var picker = $(def.picker);
399.            def.showtarget == null && obj.after(picker);
400.            picker.click(function(e) {
401.                var isshow = $(this).attr("isshow");
402.                //先隐藏
403.                var me = $(this);
404. 
405.                if (cp.css("visibility") == "visible") {
406.                    cp.css(" visibility", "hidden");
407.                }
408.                if (isshow == "1") {
409.                    me.attr("isshow", "0");
410.                    cp.removeData("ctarget").removeData("cpk").removeData("indata").removeData("onReturn");
411.                    return false;
412.                }
413.                var v = obj.val();
414.                if (v != "") {
415.                    v = v.match(dateReg);
416.                }
417.                if (v == null || v == "") {
418.                    def.Year = new Date().getFullYear();
419.                    def.Month = new Date().getMonth() + 1;
420.                    def.Day = new Date().getDate();
421.                    def.inputDate = null
422.                }
423.                else {
424.                    def.Year = parseInt(v[1], 10);
425.                    def.Month = parseInt(v[3], 10);
426.                    def.Day = parseInt(v[4], 10);
427.                    def.inputDate = new Date(def.Year, def.Month - 1, def.Day);
428.                }
429.                cp.data("ctarget", obj).data("cpk", me).data("indata", def.inputDate).data("onReturn", def.onReturn);
430.                if (def.applyrule && $.isFunction(def.applyrule)) {
431.                    var rule = def.applyrule.call(obj, obj[0].id);
432.                    if (rule) {
433.                        if (rule.startdate) {
434.                            cp.data("ads", rule.startdate);
435.                        }
436.                        else {
437.                            cp.removeData("ads");
438.                        }
439.                        if (rule.enddate) {
440.                            cp.data("ade", rule.enddate);
441.                        }
442.                        else {
443.                            cp.removeData("ade");
444.                        }
445.                    }
446.                }
447.                else {
448.                    cp.removeData("ads").removeData("ade")
449.                }
450.                writecb();
451. 
452. 
453.                $("#BBIT-DP-T").height(cp.height());
454.                var t = def.showtarget || obj;
455.                var pos = t.offset();
456. 
457. 
458.                var height = t.outerHeight();
459.                var newpos = { left: pos.left, top: pos.top + height };
460.                var w = cp.width();
461.                var h = cp.height();
462.                var bw = document.documentElement.clientWidth;
463.                var bh = document.documentElement.clientHeight;
464.                if ((newpos.left + w) >= bw) {
465.                    newpos.left = bw - w - 2;
466.                }
467.                if ((newpos.top + h) >= bh) {
468.                    newpos.top = pos.top - h - 2;
469.                }
470.                if (newpos.left < 0) {
471.                    newpos.left = 10;
472.                }
473.                if (newpos.top < 0) {
474.                    newpos.top = 10;
475.                }
476.                $("#BBIT-DP-MP").hide();
477.                newpos.visibility = "visible";
478.                cp.css(newpos);
479. 
480. 
481. 
482.                //cp.show();
483.                $(this).attr("isshow", "1");
484. 
485.                $(document).one("click", function(e) {
486.                    me.attr("isshow", "0");
487.                    cp.removeData("ctarget").removeData("cpk").removeData("indata");
488.                    cp.css("visibility", "hidden");
489.                });
490. 
491.                return false;
492.            });
493.        });
494.    };
495.})(jQuery);


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3