Zhiqim UI是一套集成Javascript库、Css库、Font库、常用ico图标等,并在其上开发的大量UI组件组成的前端开发套件。
森中灵 最后提交于3月前 整理V8.0.6
zhiqim_calendar.js19KB
/*
* 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
*
* https://zhiqim.org/project/zhiqim_framework/zhiqim_ui.htm
*
* Zhiqim UI is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
+(function(Z)
{//BEGIN
// @version v1.1.0 @author zouzhigang 2015-11-12 新建与整理
// 调用举例:
// <input type="text" name="date" focus="Z.date(this)" onchange="alert(this.value);">
// <input type="text" name="datetime" focus="Z.datetime(this)" onchange="alert(this.value);">
// <input type="text" name="datetimeNoSecond" focus="Z.datetimeNoSecond(this)" onchange="alert(this.value);">
Z.Calendar = Z.Class.newInstance();
Z.Calendar.v = "8.0.4";
Z.Calendar.prototype =
{
defaults:
{
hasTime: false, //默认不显示时间
hasSecond: true, //默认显示时间时有秒
selectYear: null, //选中的年,要求数字
selectMonth: null, //选中的月,要求数字
selectDay: null, //选中的日期,要求数字
selectHour: null, //选中的小时,要求2位字符串
selectMinute: null, //选中的分钟,要求2位字符串
selectSecond: null, //选中的秒,要求2位字符串
elem: null, //当前对象
styles: null, //自定义样式
elemDate: null, //选中的时间
currDate: new Date(), //保存当前时间
dateMap: new Z.HashMap() //42个日期和ID对应关系
},
init: function()
{
this.$elem = Z.$elem(this.elem, "Z.Calendar");
this.random = Z.random(10);//日历ID,为保证唯一在init随机生成
this.html ='<div id="Z_Calendar_'+this.random+'" style="position:absolute;display:none;z-index:1000;">';
this.html+='<table class="z-table z-calendar">';
//选择年月
this.html+='<tr>';
this.html+=' <td>';
this.html+=' <table class="z-table z-top">';
this.html+=' <tr>';
this.html+=' <td width="30" align="center" class="z-pointer" id="Z_Calendar_prev_'+this.random+'"><div class="z-arrow z-left"></div></td>';
this.html+=' <td width="*" align="center" class="z-year-month" id="Z_Calendar_yearMonth_'+this.random+'"><span class="z-default"></span></td>';
this.html+=' <td width="30" align="center" class="z-pointer" id="Z_Calendar_next_'+this.random+'"><div class="z-arrow z-right"></td>';
this.html+=' </tr>';
this.html+=' </table>';
this.html+=' </td>';
this.html+='</tr>';
//当前星期
this.html+='<tr>';
this.html+=' <td>';
this.html+=' <table class="z-table z-week z-px14">';
this.html+=' <tr>';
this.html+=' <td>日</td><td>一</td><td>二</td><td>三</td><td>四</td><td>五</td><td>六</td>';
this.html+=' </tr>';
this.html+=' </table>';
this.html+=' </td>';
this.html+='</tr>';
//当前星期日期,6行7列
this.html+='<tr>';
this.html+=' <td height="180" valign="top">';
this.html+=' <table class="z-table z-day">';
var i, j, n = 0;
for (i=0;i<6;i++)
{
this.html+= '<tr>';
for (j=0;j<7;j++)
{
this.html+=' <td id="Z_Calendar_day_'+this.random+'_'+(++n)+'"></td>';
}
this.html+='</tr>';
}
this.html+=' </table>';
this.html+=' </td>';
this.html+='</tr>';
//选择时分秒
if (this.isTime())
{
this.html+='<tr>';
this.html+= '<td valign="top">';
this.html+= '<table class="z-table z-timebox">';
this.html+= '<tr>';
this.html+= '<td>';
this.html+= '<dl class="z-sliderline">';
this.html+= '<dt>小时:</dt>';
this.html+= '<span class="z-scrollbar"></span>';
this.html+= '<span class="z-sliderbox""><span class="z-slider" id="Z_Calendar_hour_'+this.random+'"></span></span>';
this.html+= '</dl>';
this.html+= '</td>';
this.html+= '</tr>';
this.html+= '<tr>';
this.html+= '<td>';
this.html+= '<dl class="z-sliderline">';
this.html+= '<dt>分钟:</dt>';
this.html+= '<span class="z-scrollbar"></span>';
this.html+= '<span class="z-sliderbox"><span class="z-slider" id="Z_Calendar_minute_'+this.random+'"></span></span>';
this.html+= '</dl>';
this.html+= '</td>';
this.html+= '</tr>';
if (this.isSecond())
{
this.html+= '<tr>';
this.html+= '<td>';
this.html+= '<dl class="z-sliderline">';
this.html+= '<dt>秒数:</dt>';
this.html+= '<span class="z-scrollbar"></span>';
this.html+= '<span class="z-sliderbox"><span class="z-slider" id="Z_Calendar_second_'+this.random+'"></span></span>';
this.html+= '</dl>';
this.html+= '</td>';
this.html+= '</tr>';
}
this.html+= '<tr>';
this.html+= '<td>';
this.html+= '<div class="z-time">时间:<span class="z-mg-l8" id="Z_Calendar_time_'+this.random+'">15:12:52</span></div>';
this.html+= '<div class="z-close"><div class="z-button z-blue z-small" id="Z_Calendar_close_'+this.random+'">完成</div></div>';
this.html+= '</td>';
this.html+= '</tr>';
}
//结束
this.html+='</table>';
this.html+='</div>';
},
execute: function()
{
//解析对象中日期时间,如果不是日期时间格式置为当天
if ((this.hasTime && !Z.V.isDateTime(this.elem.value)) || (!this.hasTime && !Z.V.isDate(this.elem.value)))
this.elemDate = this.currDate;
else
this.elemDate = Z.DT.toDate(this.elem.value);
this.selectYear = this.elemDate.getFullYear();
this.selectMonth = this.elemDate.getMonth()+1;
this.selectDay = this.elemDate.getDate();
this.selectHour = Z.S.prefixZero(this.elemDate.getHours(), 2);
this.selectMinute = Z.S.prefixZero(this.elemDate.getMinutes(), 2);
this.selectSecond = this.isSecond()?Z.S.prefixZero(this.elemDate.getSeconds(), 2):0;
//组装日历DIV,和设置好位置和事件
if (!this.hasTime)
this.height = 253;
else if (!this.hasSecond)
this.height = 344;
else
this.height = 374;
//判断位置
var $appendParent = "body";
var setCss = {display: "block"};
var top, left;
//判断是不是在 dialog 内部
var $parent = this.$elem.parent();
var isInDialog = false;
while ($parent[0].tagName.toLowerCase() !== "body")
{
$parent = $parent.parent();
if ($parent.hasClass("z-dialog")) {
isInDialog = true;
break;
}
}
//dialog 弹窗内的日历插件
if (isInDialog)
{
$appendParent = $parent;
setCss.zIndex = "20002";
top = this.$elem.offsetTopBody() - $parent.offsetTopBody() + this.$elem.offsetHeight() + Z.D.scrollTop();
left = this.$elem.offsetLeftBody() - $parent.offsetLeftBody() + Z.D.scrollLeft();
if (this.$elem.offsetTopBody() > this.height &&
Z.D.clientHeight() - this.$elem.offsetTopBody() - this.$elem.offsetHeight() - this.height < 0)
{//如果顶部够高,底部不够高时,则向上弹出
top = top - this.height - this.$elem.offsetHeight();
}
if (left + 283 + $parent.offsetLeftBody() > Z.D.clientWidth() &&
left + $parent.offsetLeftBody() > 283 - this.$elem.offsetWidth())
{//如果右侧不够宽,则靠左弹出
left = left - 283 + this.$elem.offsetWidth();
}
}
//普通的日历插件
else
{
top = this.$elem.offsetTopBody() + this.$elem.offsetHeight();
left = this.$elem.offsetLeftBody();
if (top > this.height && Z.D.clientHeight() + Z.D.scrollTop() - top - this.height < 0)
{//如果顶部够高,底部不够高时,则向上弹出
top = top - this.height - this.$elem.offsetHeight();
}
if (left + 283 > Z.D.clientWidth() && left > 283 - this.$elem.offsetWidth())
{//如果右侧不够宽,则靠左弹出
left = left - 283 + this.$elem.offsetWidth();
}
}
setCss.top = top;
setCss.left = left;
var $calendar = Z(this.html);
$calendar.appendTo($appendParent).css(setCss);
// 插入自定义样式
var styles = this.styles || {};
for (var i in styles)
{
$calendar.css(i, styles[i]);
}
//当前点击时阻止冒泡,其他点击时关闭
$calendar.on("mousedown click", Z.E.forbidden);
this.$elem.on("blur", this.close, this);
//设置向左和向右移动一个月
Z("#Z_Calendar_prev_"+this.random).click(this.doPrevMonth, this);
Z("#Z_Calendar_next_"+this.random).click(this.doNextMonth, this);
//设置清空,关闭
Z("#Z_Calendar_clear_"+this.random).click(function(){this.elem.value="";}, this);
Z("#Z_Calendar_close_"+this.random).click(function(e){this.close(e);}, this);
//设置选择年份月份时打开年份列表事件
Z("#Z_Calendar_yearMonth_"+this.random).click(this.doOpenYearList, this);
//最后显示选择年份,月份和日期信息
this.showYearMonth();
this.showDay();
if (this.isTime())
{
//初始化滑块位置和滑动动作
var hour = this.selectHour * 200 / 23;
var minute = this.selectMinute * 200 / 59;
Z("#Z_Calendar_hour_"+this.random).css("left", hour+"px");
Z("#Z_Calendar_minute_"+this.random).css("left", minute+"px");
Z("#Z_Calendar_hour_"+this.random).drag({left:0,top:0,width:200,height:0,cursor:"pointer"}, this.onSlideHour, this);
Z("#Z_Calendar_minute_"+this.random).drag({left:0,top:0,width:200,height:0,cursor:"pointer"}, this.onSlideMinute, this);
if (this.isSecond())
{
var second = this.selectSecond * 200 / 59;
Z("#Z_Calendar_second_"+this.random).css("left", second+"px");
Z("#Z_Calendar_second_"+this.random).drag({left:0,top:0,width:200,height:0,cursor:"pointer"}, this.onSlideSecond, this);
}
//显示当前时间
this.showTime();
}
},
doOpenYearList: function(e)
{//打开选择年份列表
var $list = Z("#Z_Calendar_yearMonth_"+this.random).find("ul");
if ($list.length > 0)
$list.remove();
else
{
var min = this.selectYear - 50;
var max = this.selectYear + 50;
var $ul = Z("<ul></ul>").addClass("z-year-list");
for (var i=min;i<=max;i++)
{
var $option = Z("<span value='" + i + "'>" + i + "年" + "</span>");
$option.click(this.onChangeYear, this);
if (i == this.selectYear)
$option.addClass("z-selected");
$ul.append($option);
}
$ul.append("<span class='z-close'>关闭</span>");
Z("#Z_Calendar_yearMonth_"+this.random).append($ul);
//把滚动条移到中间位置
$ul[0].scrollTop = $ul[0].scrollHeight/2 - 117;
}
},
onChangeYear: function(e)
{//修改年份
var value = Z(Z.E.target(e)).val();
this.selectYear = parseInt(value);
Z("#Z_Calendar_yearMonth_"+this.random).find("ul").hide().remove();
this.showYearMonth();
this.showDay();
Z.E.stop(e);
},
onSlideHour: function(e)
{//滑动小时
var left = Z("#Z_Calendar_hour_"+this.random).css("left");
left = parseFloat(Z.S.trimRight(left, "px"));
this.selectHour = Math.floor(left * 23 / 200);
this.showTime();
this.setSelectValue();
},
onSlideMinute: function(e)
{//滑动分钟
var left = Z("#Z_Calendar_minute_"+this.random).css("left");
left = parseFloat(Z.S.trimRight(left, "px"));
this.selectMinute = Math.floor(left * 59 / 200);
this.showTime();
this.setSelectValue();
},
onSlideSecond: function(e)
{//滑动秒
var left = Z("#Z_Calendar_second_"+this.random).css("left");
left = parseFloat(Z.S.trimRight(left, "px"));
this.selectSecond = Math.floor(left * 59 / 200);
this.showTime();
this.setSelectValue();
},
doPrevMonth: function()
{//上一月
this.selectYear = this.selectMonth==1?this.selectYear-1:this.selectYear;
this.selectMonth = this.selectMonth==1?12:this.selectMonth-1;
//重置年月日
this.showYearMonth();
this.showDay();
},
doNextMonth: function()
{//下一月
this.selectYear = this.selectMonth==12?this.selectYear+1:this.selectYear;
this.selectMonth = this.selectMonth==12?1:this.selectMonth+1;
//重置年月日
this.showYearMonth();
this.showDay();
},
close: function(e)
{//关闭
this.$elem.off("blur", this.close, this);
this.$elem.blur();
Z("#Z_Calendar_"+this.random).remove();
},
showYearMonth: function()
{//显示年月
Z("#Z_Calendar_yearMonth_"+this.random).find(".z-default").html(this.selectYear+"年"+this.selectMonth+"月");
},
showDay: function()
{//显示日期,6行7列的日期显示
var i,id,day;
var lastYear = this.selectMonth==1?this.selectYear-1:this.selectYear;
var lastMonth = this.selectMonth==1?12:this.selectMonth-1;
var nextYear = this.selectMonth==12?this.selectYear+1:this.selectYear;
var nextMonth = this.selectMonth==12?1:this.selectMonth+1;
var firstWeek = new Date(this.selectYear, this.selectMonth-1, 1).getDay(); //某月第一天的星期几
if (firstWeek == 0)
firstWeek = 7;//星期天是1号则向后推7天
var curMonthMaxDay = Z.DT.getMonthDays(this.selectYear, this.selectMonth);
var lastMonthMaxDay = Z.DT.getMonthDays(lastYear, lastMonth);
//先统一背景等数据
for (i=1;i<=42;i++)
{
id = "Z_Calendar_day_"+this.random+"_"+i;
Z("#"+id).removeClass("z-nomonth").removeClass("z-tomonth").removeClass("z-today").removeClass("z-selected");
}
//1到firstWeek表示上月
for (i=1;i<=firstWeek;i++)
{
id = "Z_Calendar_day_"+this.random+"_"+i;
day = lastMonthMaxDay-firstWeek+i;
this.dateMap.put(id, this.formatDate(lastYear, lastMonth, day));
Z("#"+id).text(day);
}
//firstWeek+1到firstWeek+1+curMonthMaxDay表示当月
for (i=firstWeek+1;i<firstWeek+1+curMonthMaxDay;i++)
{
id = "Z_Calendar_day_"+this.random+"_"+i;
day = i-firstWeek;//日期从1到curMonthMaxDay
this.dateMap.put(id, this.formatDate(this.selectYear, this.selectMonth, day));
var $day = Z("#"+id).text(day);
if (this.currDate.getDate() == day && this.currDate.getMonth()+1 == this.selectMonth && this.currDate.getFullYear() == this.selectYear)
{//当天
$day.text("今天").addClass("z-today");
}
if (this.elemDate.getDate() == day && this.elemDate.getMonth()+1 == this.selectMonth && this.elemDate.getFullYear() == this.selectYear)
{//选中的
$day.addClass("z-selected");
}
else
{
$day.addClass("z-tomonth");
}
}
//firstWeek+1+curMonthMaxDay+1到42表示下月
for (i=firstWeek+1+curMonthMaxDay;i<=41;i++)
{
id = "Z_Calendar_day_"+this.random+"_"+i;
day = i-curMonthMaxDay-firstWeek;//日期从1到显示的最后一天
this.dateMap.put(id, this.formatDate(nextYear, nextMonth, day));
Z("#"+id).addClass("z-nomonth").html(day);
}
//最后对所有日期增加点击事件
for (i=1;i<=41;i++)
{
id = "Z_Calendar_day_"+this.random+"_"+i;
Z("#"+id).click(function(e)
{
var id = Z.E.target(e).id;
this.setIdValue(id);
this.close(e);
}, this);
}
//最后一个表示清空
id = "Z_Calendar_day_"+this.random+"_"+42;
Z("#"+id).css("color", "#339a99").html("清空").click(function(e){this.elem.value="";this.close(e);}, this);
},
showTime: function()
{//显示时间
Z("#Z_Calendar_time_"+this.random).text(this.formatTime());
},
setSelectValue: function()
{
if (this.hasTime === true)
this.setValue(this.formatDate() + " " + this.formatTime());
else
this.setValue(this.formatDate());
},
setIdValue: function(id)
{
var date = (!id)?Z.DT.toDateString(this.currDate):this.dateMap.get(id);
if (this.hasTime === true)
this.setValue(date + " " + this.formatTime());
else
this.setValue(date);
},
setValue: function(newValue)
{
var oldValue = this.elem.value;
this.elem.value = newValue;
if (this.elem.onchange && oldValue != this.elem.value)
this.elem.onchange();
},
formatDate: function(year, month, day)
{
if (!year && !month && !day)
return this.selectYear + "-" + Z.S.prefixZero(this.selectMonth, 2) + "-" + Z.S.prefixZero(this.selectDay, 2);
else
return year + "-" + Z.S.prefixZero(month, 2) + "-" + Z.S.prefixZero(day, 2);
},
formatTime: function()
{
return Z.S.prefixZero(this.selectHour, 2) + ":" + Z.S.prefixZero(this.selectMinute, 2) + ":" + Z.S.prefixZero(this.selectSecond, 2);
},
isTime: function()
{
return this.hasTime === true;
},
isSecond: function()
{
return this.hasSecond === true;
}
};
Z.date = function(elem, styles)
{
return new Z.Calendar({immediate:true, elem:elem, styles:styles});
}
Z.datetime = function(elem, styles)
{
return new Z.Calendar({immediate:true, elem:elem, hasTime:true, styles:styles});
}
Z.datetimeNoSecond = function(elem, styles)
{
return new Z.Calendar({immediate:true, elem:elem, hasTime:true, hasSecond:false, styles:styles});
}
//END
})(zhiqim);