/**
*
* @authors yutent (yutent@doui.cc)
* @date 2016-02-14 13:58:39
*
*/
"use strict";
define(['avalon',
'css!./doui.datepicker.min'
],
function(av){
//父级vm
var parentVm = null
av.component('do:datepicker', {
$replace: true,
$template: '
',
$construct: function(opts, b, c){
var vm = av.mix(b, c)
/********** 获取上一级vm ***********/
var pctrl = vm.duplex.slice(0, vm.duplex.indexOf('.'))
parentVm = av.vmodels[pctrl]
/**********************************/
//获取初始值
vm.duplex = vm.duplex.slice(vm.duplex.indexOf('.') + 1)
var defaultVal = (new Function('v', 'return v.' + vm.duplex))(parentVm)
//日期格式化, 默认会调用过滤器的格式'Y-m-d H:i:s'
if(!vm.showTime && !vm.format){
vm.format = 'Y-m-d';
}
if(defaultVal === undefined){
if(vm.minDate){
defaultVal = vm.minDate, vm.format;
}else if(opts.maxDate){
defaultVal = vm.maxDate, vm.format;
}
}
opts.dateVal = defaultVal && av.filters.date(defaultVal, vm.format)
opts.calendar = {
list: [],
year: av.filters.date(opts.dateVal, 'Y'),
month: av.filters.date(opts.dateVal, 'm'),
day: av.filters.date(opts.dateVal, 'd') || 0,
hour: av.filters.date(opts.dateVal, 'H') || 0,
minute: av.filters.date(opts.dateVal, 'i') || 0,
second: av.filters.date(opts.dateVal, 's') || 0,
minYear: vm.minDate && av.filters.date(vm.minDate, 'Y') >> 0,
minMonth: vm.minDate && av.filters.date(vm.minDate, 'm') >> 0,
minDay: vm.minDate && av.filters.date(vm.minDate, 'd') >> 0 || 1,
maxYear: vm.maxDate && av.filters.date(vm.maxDate, 'Y') >> 0,
maxMonth: vm.maxDate && av.filters.date(vm.maxDate, 'm') >> 0,
maxDay: vm.maxDate && av.filters.date(vm.maxDate, 'd') >> 0
}
//移除部分属性
delete vm.minDate;
delete vm.maxDate;
return av.mix(opts, vm)
},
$init: function(vm, ele){
// av.log(vm)
var lastDate = {
year: vm.calendar.year >> 0,
month: vm.calendar.month >> 0,
day: vm.calendar.day >> 0
}
var timer
getCalendar() //初始化日历显示
//日历按钮,未超出限制时切换日历
vm.$turn = function(type, step){
var year = vm.calendar.year >> 0,
month = vm.calendar.month >> 0;
if(type === 1){
year += step;
}else{
month += step;
if(month < 1){
month = 12;
year--
}
if(month > 12){
month = 1;
year++
}
}
if(isLimited(year, month) === true){
vm.tips = '日期超出限制';
return;
}
vm.calendar.year = year;
vm.calendar.month = numberFormat(month, 2);
}
//选择日期
vm.$getDate = function(disabled, day){
if(disabled)
return;
vm.calendar.day = day;
changeStyle(day);
updateTime();
vm.showCalendar = !1;
}
//输入框获取焦点时,显示日历
vm.$focus = function(){
vm.showCalendar = !0;
}
//获取当前时间
vm.$now = function(){
var year = av.filters.date(null, 'Y') >> 0,
month = av.filters.date(null, 'm') >> 0,
day = av.filters.date(null, 'd') >> 0;
var isLimitYM = isLimited(year, month),
disabled = disabledDay(day, isLimitYM);
if(disabled){
vm.tips = '今天超出了限制日期';
return;
}
vm.calendar.year = year;
vm.calendar.month = month;
vm.calendar.day = day;
vm.calendar.hour = av.filters.date(null, 'H');
vm.calendar.minute = av.filters.date(null, 'i');
vm.calendar.second = av.filters.date(null, 's');
changeStyle(day);
updateTime();
vm.showCalendar = !1;
}
/******************************************************************************/
//计算日历数组
function getCalendar(){
var year = vm.calendar.year >> 0
var month = vm.calendar.month >> 0
var nums = getNumsOfYearMonth(year, month)
var numsFixed = -getDayByYearMonth(year, month) + 1
var isLimitYM = isLimited(year, month)
vm.calendar.list.clear();
for(var i = numsFixed; i <= nums; i++){
var day = {
weeken: !1,
day: '',
selected: !1,
disable: !0
}
if(i > 0){
var d = getDayByYearMonth(year, month, i)
day = {
weeken: d == 0 || d == 6,
day: i,
selected: isSelected(i),
disable: disabledDay(i, isLimitYM)
}
}
vm.calendar.list.push(day)
}
}
//判断当前年/月是否超出限制
function isLimited(year, month){
var limit = {
Y: vm.calendar.minYear,
M: vm.calendar.minMonth,
mY: vm.calendar.maxYear,
mM: vm.calendar.maxMonth,
}
var res = ''
if((!limit.Y && !limit.mY) || (!limit.M && !limit.mM))
return false
if(year){
if((limit.Y && year < limit.Y) || (limit.mY && year > limit.mY))
return true
}else{
return false
}
if(month){
if(year === limit.Y){
if(limit.M && month < limit.M)
return true
if(month == limit.M)
res += '-'
}
if(year === limit.mY){
if(limit.mM && month > limit.mM)
return true
if(month == limit.mM)
res += '+'
}
}
return res
}
//判断指定天数是否有效
function disabledDay(day, limitedYM){
var minD = vm.calendar.minDay
var maxD = vm.calendar.maxDay
if(limitedYM === '-')
return day < minD
if(limitedYM === '+')
return maxD && day > maxD
if(limitedYM === '-+')
return day < minD || (maxD && day > maxD)
return limitedYM
}
//判断指定天数是否被选中
function isSelected(day){
var year = vm.calendar.year >> 0
var month = vm.calendar.month >> 0
return !(lastDate.year !== year || lastDate.month !== month || lastDate.day !== day)
}
//修改当前选中日期的样式
function changeStyle(day){
vm.calendar.list.forEach(function(item){
if(item.day != day){
item.selected = !1
}else{
item.selected = !0
}
})
}
//更新时间
function updateTime(){
var cal = vm.calendar
var year = cal.year
var month = cal.month
var day = cal.day
var hour = cal.hour
var minute = cal.minute
var second = cal.second
var date = year + '-' + month + '-' + day
if(vm.showTime){
date += ' ' + hour + ':' + minute + ':' + second
}
lastDate = {
year: year >> 0,
month: month >> 0,
day: day >> 0
}
vm.dateVal = av.filters.date(date, vm.format)
}
/******************************************************************************/
vm.$watch('calendar.year', function(){
getCalendar();
})
vm.$watch('calendar.month', function(){
getCalendar();
})
vm.$watch('calendar.hour', function(v){
vm.calendar.hour = v
updateTime()
})
vm.$watch('calendar.minute', function(v){
vm.calendar.minute = v
updateTime()
})
vm.$watch('calendar.second', function(v){
vm.calendar.second = v
updateTime()
})
vm.$watch('showCalendar', function(v){
if(v || !vm.duplex)
return;
eval('parentVm.' + vm.duplex + ' = "' + vm.dateVal + '"');
vm.callback && vm.callback(vm.dateVal);
})
vm.$watch('tips', function(v){
if(!v)
return;
clearTimeout(timer);
timer = setTimeout(function(){
vm.tips = '';
}, 1500)
})
document.addEventListener('click', function(){
vm.showCalendar = !1;
})
},
showTime: false, //对话框上显示时间
showCalendar: false, //显示日历对话框
disabled: false, //是否禁用
exclass: '', //输入框拓展样式, 用于外部调整输入框样式以适配各种场景
tips: '',
duplex: '',
format: '', // 日期显示格式
dateVal: '',
radius: 0, //日历输入框边框圆角半径
border: 1, //日历输入框边框大小
btns: { //切换年份/月份的按钮上的字符
prevYear: '<<',
nextYear: '>>',
prevMonth: '<',
nextMonth: '>'
},
$focus: av.noop,
$turn: av.noop,
$getDate: av.noop,
$now: av.noop,
$cancelBubble: function(event){
event.stopPropagation && event.stopPropagation() || (event.cancelBubble = true);
},
callback: null, //日期被修改后的回调
})
//获取今年的年份/月份,返回的是数组
function getThisYearMonth(){
var oDate = new Date()
return [oDate.getFullYear(), oDate.getMonth() + 1]
}
//根据年份获取指定月份天数
function getNumsOfYearMonth(year, month){
return new Date(year, month, 0).getDate()
}
//判断指定年月第一天是星期几
function getDayByYearMonth(year, month, day){
day = day || 1
return new Date(year, month - 1, day).getDay()
}
//数字长度补全(前面加0)
function numberFormat(num, len){
num += ''
if(num.length === len)
return num
while(num.length < len)
num = '0' + num
return num
}
return av
})