This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

修复框架子对象中数组无法监听的bug;日期选择组件完成适配;

old
宇天 2017-09-11 05:43:00 +08:00
parent 3f925843ad
commit 10d5df4dad
11 changed files with 504 additions and 464 deletions

View File

@ -1,46 +1,6 @@
# 日历组件文档 ## 更新日志
## 配置说明 v1.0.0 (2017-09-11)
============
```json First Release.
{
showTime: false, //对话框上显示时间
showCalendar: false, //显示日历对话框
disabled: false, //是否禁用
exclass: '', //输入框拓展样式, 用于外部调整输入框样式以适配各种场景
duplex: '',
format: '', // 日期显示格式
radius: 0, //日历输入框边框圆角半径
border: 1, //日历输入框边框大小
btns: { //切换年份/月份的按钮上的字符
prevYear: '<<',
nextYear: '>>',
prevMonth: '<',
nextMonth: '>'
},
callback: function(date){/*...*/}, //日期被修改后的回调,参数是被修改后的值
}
```
## 用法
```html
<!-- 把do:datepicker 标签放到想要放的地方即可 -->
<section>
<span class="label">示例1:</span>
<do:datepicker config="dp" duplex="ex1" border="1" class="date" radius="3"></do:datepicker>
</section>
<!--
其中config属性是指定日历组件的配置会自动从上一层controller里找,如果该属性为空则自动从上层controller中找与组件同名的属性找不到则使用组件默认配置;
其他的属性(除$id, config, id, class, tabindex, style, ms-*属性,data-*属性外,也可以用以配置组件,且优先级最高);
$id或identifier属性可以设定组件的$id值方便各模块之间进行通讯
-->
<!-- 引入分页组件 -->
<script>
require(['存放路径/doui.datepicker'], function(){
})
</script>
```

View File

@ -1,40 +0,0 @@
@charset "UTF-8";
/**
*
* @authors yutent (yutent@doui.cc)
* @date 2016-02-14 14:00:06
*
*/
.do-ui-datepicker {position:relative;z-index:65534;width:100%;height:100%;}
.do-ui-datepicker a {text-decoration:none;}
.do-ui-datepicker .date-input {float:left;width:100%;height:100%;border:1px solid #ddd;line-height:18px;padding:0 5px;}
.do-ui-datepicker .calendar {position:absolute;z-index:65534;left:0;top:98%;width:230px;height:auto;min-height:60px;padding:10px;border:1px solid #ddd;background:#fff;font-size:13px;box-shadow:0 0 5px rgba(0,0,0,.1)}
.do-ui-datepicker .calendar-hd {width:100%;height:30px;line-height:30px;background:#f3f3f3;color:#666;text-align:center;}
.do-ui-datepicker .calendar-contrl {position:relative;width:90%;height:30px;margin:0 5%;line-height:30px;border-bottom:1px solid #eee;color:#09f;text-align:center;}
.do-ui-datepicker .calendar-contrl a {position:absolute;top:0;left:0;width:30px;color:#09f;}
.do-ui-datepicker .calendar-contrl .prev-month {left:30px;}
.do-ui-datepicker .calendar-contrl .next-month {left:auto;right:30px;}
.do-ui-datepicker .calendar-contrl .next-year {left:auto;right:0;}
.do-ui-datepicker .calendar-table {position:relative;width:90%;height:auto;margin:0 5%;line-height:25px;color:#888;text-align:center;}
.do-ui-datepicker .calendar-table .tr {width:100%;height:auto;min-height:25px;}
.do-ui-datepicker .calendar-table .tr.tr-hd {border-bottom:1px solid #eee;margin-bottom:3px;}
.do-ui-datepicker .calendar-table .tr .td {float:left;width:14.28%;height:25px;}
.do-ui-datepicker .calendar-table .tr .do-st-hand:hover {background:#b6def9;}
.do-ui-datepicker .calendar-table .tr .td.weeken {color:#f30;}
.do-ui-datepicker .calendar-table .tr .td.selected {background:#09f;color:#fff;}
.do-ui-datepicker .calendar-table .tr .td.disabled {color:#ddd;cursor:default;}
.do-ui-datepicker .time-contrl {position:relative;width:90%;height:30px;margin:5px 5%;line-height:30px;border-top:1px solid #eee;color:#888;}
.do-ui-datepicker .time-contrl label {float:left;height:20px;margin:5px 5px 5px 0;}
.do-ui-datepicker .time-contrl input {float:left;width:25px;height:20px;padding:0 3px;line-height:17px;outline:none;}
.do-ui-datepicker .time-contrl label:after {float:right;height:20px;line-height:20px;font-size:12px;}
.do-ui-datepicker .time-contrl .hours:after {content:"时"}
.do-ui-datepicker .time-contrl .minutes:after {content:"分"}
.do-ui-datepicker .time-contrl .seconds:after {content:"秒"}
.do-ui-datepicker .time-contrl .now {float:right;width:40px;height:20px;margin:5px;border:1px solid #ddd;border-radius:3px;line-height:20px;background:#f7f7f7;color:#888;text-align:center;}
.do-ui-datepicker .time-contrl .now:hover {background:#eee;}
.do-ui-datepicker .time-contrl .now:active {background:#e7e7e7;}
.do-ui-datepicker .calendar-tips {position:absolute;z-index:65535;left:25%;top:40%;width:50%;height:30px;line-height:30px;background:rgba(0,0,0,.7);color:#fff;font-size:12px;text-align:center;}

View File

@ -1,375 +0,0 @@
/**
*
* @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: '<div class="do-ui-datepicker do-fn-noselect"><input class="date-input" type="text" ms-duplex="dateVal" ms-on-focus="$focus" ms-click="$cancelBubble" ms-attr-disabled="disabled" ms-css="{borderWidth: border, borderRadius: radius}"><div class="calendar" ms-if="showCalendar" ms-click="$cancelBubble"><div class="calendar-hd">请选择日期</div><div class="calendar-contrl"><a href="javascript:;" ms-click="$turn(1, -1)" class="prev-year">{{btns.prevYear}}</a><a href="javascript:;" ms-click="$turn(0, -1)" class="prev-month">{{btns.prevMonth}}</a><a href="javascript:;" ms-click="$turn(0, 1)" class="next-month">{{btns.nextMonth}}</a><a href="javascript:;" ms-click="$turn(1, 1)" class="next-year">{{btns.nextYear}}</a><span class="date-display">{{calendar.year + \'-\' + calendar.month}}</span></div><ul class="calendar-table"><li class="tr tr-hd"><span class="td">日</span><span class="td">一</span><span class="td">二</span><span class="td">三</span><span class="td">四</span><span class="td">五</span><span class="td">六</span></li><li class="tr list do-fn-cl"><span class="td" ms-class="{weeken:el.weeken, \'do-st-hand\': !el.disable, disabled: el.disable, selected: el.selected}" ms-repeat="calendar.list" ms-click="$getDate(el.disable, el.day)">{{el.day}}</span></li></ul><div class="time-contrl" ms-if="showTime"><label class="hours"><input type="text" ms-duplex-time="calendar.hour" data-format="hour"></label><label class="minutes"><input type="text" ms-duplex-time="calendar.minute" data-format="minute"></label><label class="seconds"><input type="text" ms-duplex-time="calendar.second" data-format="second"></label><a href="javascript:;" class="now" ms-click="$now">现在</a></div><span class="calendar-tips" ms-if="tips">{{tips}}</span></div></div>',
$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
})

View File

@ -1 +0,0 @@
@charset "UTF-8";.do-ui-datepicker{position:relative;z-index:65534;width:100%;height:100%}.do-ui-datepicker a{text-decoration:none}.do-ui-datepicker .date-input{float:left;width:100%;height:100%;border:1px solid #ddd;line-height:18px;padding:0 5px}.do-ui-datepicker .calendar{position:absolute;z-index:65534;left:0;top:98%;width:230px;height:auto;min-height:60px;padding:10px;border:1px solid #ddd;background:#fff;font-size:13px;box-shadow:0 0 5px rgba(0,0,0,.1)}.do-ui-datepicker .calendar-hd{width:100%;height:30px;line-height:30px;background:#f3f3f3;color:#666;text-align:center}.do-ui-datepicker .calendar-contrl{position:relative;width:90%;height:30px;margin:0 5%;line-height:30px;border-bottom:1px solid #eee;color:#09f;text-align:center}.do-ui-datepicker .calendar-contrl a{position:absolute;top:0;left:0;width:30px;color:#09f}.do-ui-datepicker .calendar-contrl .prev-month{left:30px}.do-ui-datepicker .calendar-contrl .next-month{left:auto;right:30px}.do-ui-datepicker .calendar-contrl .next-year{left:auto;right:0}.do-ui-datepicker .calendar-table{position:relative;width:90%;height:auto;margin:0 5%;line-height:25px;color:#888;text-align:center}.do-ui-datepicker .calendar-table .tr{width:100%;height:auto;min-height:25px}.do-ui-datepicker .calendar-table .tr.tr-hd{border-bottom:1px solid #eee;margin-bottom:3px}.do-ui-datepicker .calendar-table .tr .td{float:left;width:14.28%;height:25px}.do-ui-datepicker .calendar-table .tr .do-st-hand:hover{background:#b6def9}.do-ui-datepicker .calendar-table .tr .td.weeken{color:#f30}.do-ui-datepicker .calendar-table .tr .td.selected{background:#09f;color:#fff}.do-ui-datepicker .calendar-table .tr .td.disabled{color:#ddd;cursor:default}.do-ui-datepicker .time-contrl{position:relative;width:90%;height:30px;margin:5px 5%;line-height:30px;border-top:1px solid #eee;color:#888}.do-ui-datepicker .time-contrl label{float:left;height:20px;margin:5px 5px 5px 0}.do-ui-datepicker .time-contrl input{float:left;width:25px;height:20px;padding:0 3px;line-height:17px;outline:0}.do-ui-datepicker .time-contrl label:after{float:right;height:20px;line-height:20px;font-size:12px}.do-ui-datepicker .time-contrl .hours:after{content:"时"}.do-ui-datepicker .time-contrl .minutes:after{content:"分"}.do-ui-datepicker .time-contrl .seconds:after{content:"秒"}.do-ui-datepicker .time-contrl .now{float:right;width:40px;height:20px;margin:5px;border:1px solid #ddd;border-radius:3px;line-height:20px;background:#f7f7f7;color:#888;text-align:center}.do-ui-datepicker .time-contrl .now:hover{background:#eee}.do-ui-datepicker .time-contrl .now:active{background:#e7e7e7}.do-ui-datepicker .calendar-tips{position:absolute;z-index:65535;left:25%;top:40%;width:50%;height:30px;line-height:30px;background:rgba(0,0,0,.7);color:#fff;font-size:12px;text-align:center}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,50 @@
<div class="do-datepicker do-fn-noselect">
<input class="date-input"
type="text"
:duplex="value"
:focus="$focus"
:click="$cancelBubble"
:attr-disabled="disabled">
<dl class="calendar-box"
:if="showCalendar"
:click="$cancelBubble">
<dt class="title">请选择日期</dt>
<dd class="contrl">
<a href="javascript:;"
:click="$turn(1, -1)"
:text="btns.prevYear"></a>
<a href="javascript:;" class="prev-month"
:click="$turn(0, -1)" :text="btns.prevMonth"></a>
<a href="javascript:;" class="next-month"
:click="$turn(0, 1)" :text="btns.nextMonth"></a>
<a href="javascript:;" class="next-year"
:click="$turn(1, 1)" :text="btns.nextYear"></a>
<span :text="calendar.year + '-' + calendar.month"></span>
</dd>
<dd class="calendar">
<section class="week"><span class="td"></span><span class="td"></span><span class="td"></span><span class="td"></span><span class="td"></span><span class="td"></span><span class="td"></span></section>
<section class="list do-fn-cl">
<span class="td"
:class="{weeken:el.weeken, disabled: el.disable, selected: el.selected}"
:repeat="calendar.list"
:click="$getDate(el.disable, el.day)"
:text="el.day"></span>
</section>
</dd>
<dd class="time" :if="showTime">
<label>
<input type="text" :duplex-time="calendar.hour" data-format="hour">
</label>
<label>
<input type="text" :duplex-time="calendar.minute" data-format="minute">
</label>
<label>
<input type="text" :duplex-time="calendar.second" data-format="second">
</label>
<a href="javascript:;" class="now" :click="$now">现在</a>
</dd>
<dd class="tips" :if="tips" :text="tips"></dd>
</dl>
</div>

391
js/lib/datepicker/main.js Normal file
View File

@ -0,0 +1,391 @@
/**
*
* @authors yutent (yutent@doui.cc)
* @date 2016-02-14 13:58:39
*
*/
"use strict";
define([
'text!./main.htm',
'css!./style.css',
], function(tpl){
yua.ui.datepicker = '1.0.0'
yua.component('datepicker', {
$template: tpl,
$construct: function(sys, option, attr){
// 先合并config的配置及元素的属性
var opts = Object.assign({}, option, attr),
defVal;
if(!opts.value){
return yua.error('日历组件必须设置value属性')
}
//获取初始值
defVal = sys.$up[opts.value]
//日期格式化, 默认会调用过滤器的格式'Y-m-d H:i:s'
if(!opts.showTime && !opts.format){
opts.format = 'Y-m-d';
}
// 修正默认值, 如果不是Date对象, 则转为Date对象
if(!defVal){
if(opts.minDate){
defVal = opts.minDate;
}else if(opts.maxDate){
defVal = opts.maxDate;
}else{
defVal = new Date()
}
}
if(!Date.isDate(defVal)){
defVal = new Date(defVal)
}
opts.update_value = opts.value
opts.value = defVal.format(opts.format)
opts.calendar = {
list: [1],
year: defVal.format('Y'),
month: defVal.format('m'),
day: defVal.format('d'),
hour: defVal.format('H'),
minute: defVal.format('i'),
second: defVal.format('s'),
minYear: 0,
minMonth: 0,
minDay: 0,
maxYear: 0,
maxMonth: 0,
maxDay: 0
}
if(opts.minDate){
if(!Date.isDate(opts.minDate)){
opts.minDate = new Date(opts.minDate)
}
opts.calendar.minYear = opts.minDate.format('Y')
opts.calendar.minMonth = opts.minDate.format('m')
opts.calendar.minDay = opts.minDate.format('d')
}
if(opts.maxDate){
if(!Date.isDate(opts.maxDate)){
opts.maxDate = new Date(opts.maxDate)
}
opts.calendar.maxYear = opts.maxDate.format('Y')
opts.calendar.maxMonth = opts.maxDate.format('m')
opts.calendar.maxDay = opts.maxDate.format('d')
}
log(opts)
//移除部分属性
delete opts.minDate;
delete opts.maxDate;
return yua.mix(sys, opts)
},
$ready: function(vm, ele){
var last = {
year: +vm.calendar.year,
month: +vm.calendar.month,
day: +vm.calendar.day
},
timer;
getCalendar(vm, last) //初始化日历显示
//日历按钮,未超出限制时切换日历
vm.$turn = function(type, step){
var year = +vm.calendar.year,
month = +vm.calendar.month;
if(type === 1){
year += step;
}else{
month += step;
if(month < 1){
month = 12;
year--
}
if(month > 12){
month = 1;
year++
}
}
if(isLimited(vm.calendar, 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(vm.calendar, day);
updateTime(vm, last);
vm.showCalendar = !1;
}
//输入框获取焦点时,显示日历
vm.$focus = function(){
vm.showCalendar = !0;
}
//获取当前时间
vm.$now = function(){
var now = new Date(),
year = now.format('Y'),
month = now.format('m'),
day = now.format('d');
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 = now.format('H');
vm.calendar.minute = now.format('i');
vm.calendar.second = now.format('s');
changeStyle(vm.calendar, day);
updateTime(vm, last);
vm.showCalendar = !1;
}
/************************************************************/
vm.$watch('calendar.year', function(){
getCalendar(vm, last);
})
vm.$watch('calendar.month', function(){
getCalendar(vm, last);
})
vm.$watch('calendar.hour', function(v){
vm.calendar.hour = v
updateTime(vm, last)
})
vm.$watch('calendar.minute', function(v){
vm.calendar.minute = v
updateTime(vm, last)
})
vm.$watch('calendar.second', function(v){
vm.calendar.second = v
updateTime(vm, last)
})
vm.$watch('showCalendar', function(v){
if(v || !vm.value)
return;
vm.$up[vm.update_value] = vm.value
vm.$onUpdate(vm.value);
})
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, //是否禁用
tips: '',
format: '', // 日期显示格式
value: '', // 用于显示在输入框里的日期变量
btns: { //切换年份/月份的按钮上的字符
prevYear: '<<',
nextYear: '>>',
prevMonth: '<',
nextMonth: '>'
},
$focus: yua.noop,
$turn: yua.noop,
$getDate: yua.noop,
$now: yua.noop,
$cancelBubble: function(event){
event.stopPropagation && event.stopPropagation() || (event.cancelBubble = true);
},
$onUpdate: yua.noop, //日期被修改后的回调
})
/**************** 公共函数 *****************/
//计算日历数组
function getCalendar(vm, last){
var year = +vm.calendar.year,
month = +vm.calendar.month,
nums = getTotalDays(year, month),
numsFixed = -getFirstDay(year, month) + 1,
isLimitYM = isLimited(vm.calendar, 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 = getFirstDay(year, month, i)
day = {
weeken: d == 0 || d == 6,
day: i,
selected: isSelected(vm.calendar, last, i),
disable: disabledDay(vm.calendar, i, isLimitYM)
}
}
vm.calendar.list.push(day)
}
}
//判断当前年/月是否超出限制
function isLimited(calendar, year, month){
var limit = {
Y: +calendar.minYear,
M: +calendar.minMonth,
mY: +calendar.maxYear,
mM: +calendar.maxMonth,
},
res = '';
if((!limit.Y && !limit.mY) || (!limit.M && !limit.mM) || !year){
return false
}
if((limit.Y && year < limit.Y) || (limit.mY && year > limit.mY)){
return true
}
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(calendar, day, limitedYM){
var minD = calendar.minDay,
maxD = 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(calendar, last, day){
var year = +calendar.year,
month = +calendar.month;
return !(last.year !== year || last.month !== month || last.day !== day)
}
//修改当前选中日期的样式
function changeStyle(calendar, day){
calendar.list.forEach(function(item){
if(item.day != day){
item.selected = !1
}else{
item.selected = !0
}
})
}
//更新时间
function updateTime(vm, last){
var hour = minute = second = 0;
last = {
year: +vm.calendar.year,
month: +vm.calendar.month,
day: +vm.calendar.day
}
if(vm.showTime){
hour = vm.calendar.hour
minute = vm.calendar.minute
second = vm.calendar.second
}
vm.value = new Date(last.year, last.month - 1, last.day, hour, minute, second).format(vm.format)
}
//获取今年的年份/月份,返回的是数组
function getThisYearMonth(){
var oDate = new Date()
return [oDate.getFullYear(), oDate.getMonth() + 1]
}
//根据年份获取指定月份天数
function getTotalDays(year, month){
return new Date(year, month, 0).getDate()
}
//判断指定年月第一天是星期几
function getFirstDay(year, month, day){
return new Date(year, month - 1, day || 1).getDay()
}
//数字长度补全前面加0
function numberFormat(num, len){
num += ''
if(num.length === len)
return num
while(num.length < len)
num = '0' + num
return num
}
return yua
})

View File

@ -0,0 +1 @@
.do-datepicker{position:relative;z-index:65534;width:100%;height:100%}.do-datepicker a{text-decoration:none}.do-datepicker .date-input{display:block;width:100%;height:100%;padding:0 5px;line-height:18px;border:1px solid #e7e8eb;transition:all .1s ease-in-out}.do-datepicker .date-input:focus{border-color:#1abc9c}.do-datepicker .calendar-box{position:absolute;left:0;top:100%;width:267px;height:auto;min-height:60px;padding:10px;line-height:35px;border:1px solid #ddd;background:#fff;font-size:14px;color:#34495e;text-align:center;box-shadow:0 1px 5px rgba(0,0,0,0.1)}.do-datepicker .calendar-box dt.title{width:100%;height:35px;background:#e7e8eb}.do-datepicker .calendar-box dd.contrl{position:relative;width:90%;height:35px;margin:0 5%}.do-datepicker .calendar-box dd.contrl a{position:absolute;left:0;top:0;width:35px;height:35px;color:#34495e;font-weight:bold}.do-datepicker .calendar-box dd.contrl a:hover{color:#1abc9c}.do-datepicker .calendar-box dd.contrl a.prev-month{left:35px}.do-datepicker .calendar-box dd.contrl a.next-month{left:auto;right:35px}.do-datepicker .calendar-box dd.contrl a.next-year{left:auto;right:0}.do-datepicker .calendar-box dd.calendar{width:100%;height:auto}.do-datepicker .calendar-box dd.calendar .week{width:100%;height:35px;margin-bottom:5px;border-bottom:1px solid #eee}.do-datepicker .calendar-box dd.calendar span.td{float:left;width:35px}.do-datepicker .calendar-box dd.calendar .list span.td{height:30px;line-height:30px;cursor:pointer;transition:all .1s ease-in-out}.do-datepicker .calendar-box dd.calendar .list span.td:hover{background:#e7e8eb}.do-datepicker .calendar-box dd.calendar .list span.td.weeken{color:#e74c3c}.do-datepicker .calendar-box dd.calendar .list span.td.selected{background:#48c9b0;color:#fff}.do-datepicker .calendar-box dd.calendar .list span.td.disabled{color:#bdc3c7;cursor:default}.do-datepicker .calendar-box dd.calendar .list span.td.disabled:hover{background:none}.do-datepicker .calendar-box dd.time{position:relative;width:100%;height:41px;padding:5px 0;margin-top:5px;line-height:30px;border-top:1px solid #eee}.do-datepicker .calendar-box dd.time label{float:left;width:60px;height:30px}.do-datepicker .calendar-box dd.time label input{width:30px;height:30px;border:1px solid #e7e8eb;text-align:center}.do-datepicker .calendar-box dd.time .now{float:right;width:50px;height:30px;border-radius:3px;background:#1abc9c;color:#fff;text-align:center}.do-datepicker .calendar-box dd.time .now:hover{background:#48c9b0}.do-datepicker .calendar-box dd.time .now:active{background:#16a085}.do-datepicker .calendar-box dd.tips{position:absolute;z-index:65535;left:25%;top:40%;width:50%;height:30px;line-height:30px;background:rgba(0,0,0,0.7);color:#fff;font-size:12px;text-align:center}

View File

@ -0,0 +1,56 @@
@charset "UTF-8";
/**
*
* @authors yutent (yutent@doui.cc)
* @date 2016-02-14 14:00:06
*
*/
@import "../../../css/var.scss";
.do-datepicker {position:relative;z-index:65534;width:100%;height:100%;
a {text-decoration:none;}
.date-input {display:block;width:100%;height:100%;padding:0 5px;line-height:18px;border:1px solid nth($cp, 1);@include ts();
&:focus {border-color:nth($cg, 1)}
}
.calendar-box {position:absolute;left:0;top:100%;width:267px;height:auto;min-height:60px;padding:10px;line-height:35px;border:1px solid #ddd;background:#fff;font-size:14px;color:nth($cgr, 1);text-align:center;box-shadow:0 1px 5px rgba(0,0,0,.1);
dt.title {width:100%;height:35px;background:#e7e8eb;}
dd.contrl {position:relative;width:90%;height:35px;margin:0 5%;
a {position:absolute;left:0;top:0;width:35px;height:35px;color:nth($cgr, 1);font-weight:bold;}
a:hover {color:nth($cg, 1)}
a.prev-month {left:35px;}
a.next-month {left:auto;right:35px;}
a.next-year {left:auto;right:0;}
}
dd.calendar {width:100%;height:auto;
.week {width:100%;height:35px;margin-bottom:5px;border-bottom:1px solid #eee;}
span.td {float:left;width:35px;}
.list span.td {height:30px;line-height:30px;cursor:pointer;@include ts();
&:hover {background:nth($cp, 1);}
&.weeken {color:nth($cr, 1)}
&.selected {background:nth($cg, 2);color:#fff}
&.disabled {color:nth($cp, 3);cursor:default;}
&.disabled:hover {background:none;}
}
}
dd.time {position:relative;width:100%;height:41px;padding:5px 0;margin-top:5px;line-height:30px;border-top:1px solid #eee;
label {float:left;width:60px;height:30px;
input {width:30px;height:30px;border:1px solid nth($cp, 1);text-align:center;}
}
.now {float:right;width:50px;height:30px;border-radius:3px;background:nth($cg, 1);color:#fff;text-align:center;
&:hover {background:nth($cg, 2);}
&:active {background:nth($cg, 3);}
}
}
dd.tips {position:absolute;z-index:65535;left:25%;top:40%;width:50%;height:30px;line-height:30px;background:rgba(0,0,0,.7);color:#fff;font-size:12px;text-align:center;}
}
}

View File

@ -1178,7 +1178,7 @@ function $emit(key, args) {
var path = p + "." + key; var path = p + "." + key;
arr = path.split("."); arr = path.split(".");
args = args.concat([path, key]) args = args && args.concat([path, key]) || [path, key]
if (arr.indexOf("*") === -1) { if (arr.indexOf("*") === -1) {
$emit.call(parent, path, args)//以确切的值往上冒泡 $emit.call(parent, path, args)//以确切的值往上冒泡

View File

@ -1177,7 +1177,7 @@ function $emit(key, args) {
var path = p + "." + key; var path = p + "." + key;
arr = path.split("."); arr = path.split(".");
args = args.concat([path, key]) args = args && args.concat([path, key]) || [path, key]
if (arr.indexOf("*") === -1) { if (arr.indexOf("*") === -1) {
$emit.call(parent, path, args)//以确切的值往上冒泡 $emit.call(parent, path, args)//以确切的值往上冒泡
@ -1711,7 +1711,6 @@ var newProto = {
}, },
clear: function () { clear: function () {
this.removeAll() this.removeAll()
return this
} }
} }