rolldate-full
Version:
rolldate Multi-format, powerful mobile date selection plugin
225 lines (208 loc) • 8.7 kB
JavaScript
import './rolldate.less';
import IScroll from './iscroll/iscroll5';
let pkg = require('../package.json');
export class Date{
constructor(config){
if(!config || !config.el){return;}
let _this = this,
el = _this.$(config.el)[0];
if(!el){return;}
_this.extend(config);
el.addEventListener('click', function() {
if(el.nodeName == 'INPUT'){el.blur();}
if(_this.config.tapBefore && _this.config.tapBefore.call(_this,el) === false){return false;}
_this.createUi();
})
}
baseData(){
return {
date:new window.Date(),
emptyli:'<li> </li>',
dateFormat:['YYYY-MM','YYYY-MM-DD','YYYY-MM-DD hh:mm','YYYY-MM-DD hh:mm:ss','YYYY'],//支持的日期格式
domClass:['rolldate-year','rolldate-month','rolldate-day','rolldate-hour','rolldate-min','rolldate-sec'],
opts:{//插件默认配置
el:'',
format:'YYYY-MM-DD',
beginYear:2000,
endYear:2100,
theme:'',
tapBefore:null,
moveEnd:null,
confirmBefore:null,
confirmEnd:null
}
};
}
extend(config){
let _this = this,
opts = _this.baseData().opts;
for(let key in opts){
opts[key] = config[key] || opts[key];
}
_this.config = opts;
}
createUi(){
let _this = this,
data = _this.baseData(),
index = data.dateFormat.indexOf(_this.config.format);
index = index > 1? index+1 : index;
let $class = index == 5? [data.domClass[0]]:data.domClass.slice(0,index + 2),
len = $class.length,
ul = '',
el = _this.$(_this.config.el)[0],
hasDate = !!el.date,
date = hasDate? new window.Date(el.date.replace(/-/g,'/')):data.date;
for(let i=0; i<len; i++){
ul += '<div class="'+ $class[i]+'"><ul>' + data.emptyli;
if(i == 0){
for(let j=_this.config.beginYear; j<=_this.config.endYear; j++){
ul += '<li'+(j==date.getFullYear()?' class="active"':'')+'>'+ j +'年</li>';
}
}else if(i == 1){
for(let k=1; k<=12; k++){
ul += '<li'+(k==date.getMonth() + 1?' class="active"':'')+'>'+ (k<10? '0'+k : k) +'月</li>';
}
}else if(i == 2){
let day = _this.bissextile(date.getFullYear(),date.getMonth() + 1);
for(let l=1; l<=day; l++){
ul += '<li'+(l==date.getDate()?' class="active"':'')+'>'+ (l<10? '0'+l : l) +'日</li>';
}
}else if(i == 3){
for(let m=0; m<=23; m++){
ul += '<li'+(m==date.getHours()?' class="active"':'')+'>'+ (m<10? '0'+m : m) +'时</li>';
}
}else if(i == 4){
for(let n=0; n<=59; n++){
ul += '<li'+(n==date.getMinutes()?' class="active"':'')+'>'+ (n<10? '0'+n : n) +'分</li>';
}
}else if(i == 5){
for(let o=0; o<=59; o++){
ul += '<li'+(o==date.getSeconds()?' class="active"':'')+'>'+ (o<10? '0'+o : o) +'秒</li>';
}
}
ul += data.emptyli +'</ul></div>'
}
let $html = `<div class="rolldate-mask"></div>
<div class="rolldate-wrapper">
<header>选择日期</header>
<section class="rolldate-content">
<div class="rolldate-frame">${ul}</div>
</section>
<footer>
<button class="rolldate-btn rolldate-cancel">取消</button>
<button class="rolldate-btn rolldate-confirm">确定</button>
</footer>
</div>`,
box = document.createElement("div"),
className = index == 0? 'rolldate-two':index == 3? 'rolldate-five':index == 4? 'rolldate-six':index == 5? 'rolldate-one':'';
box.className = 'rolldate-container ' + className;
box.innerHTML = $html;
document.body.append(box);
_this.setTheme();
_this.iscroll = [];
for(let i=0; i<len; i++){
_this.iscroll[i] = new IScroll('.'+$class[i], {
snap: 'li',
checkDOMChanges:i==2
});
let li = _this.$('.'+$class[i]+' .active')[0].previousSibling;
_this.iscroll[i].scrollToElement(li);
_this.iscroll[i].on('scrollEnd', function(){
if(_this.config.moveEnd){
_this.config.moveEnd.call(_this,_this.$(_this.config.el)[0],this);
}
if(data.domClass.slice(0,2).indexOf(this.wrapper.className) != -1 && _this.iscroll[2]){
let prevDay = _this.getIscrollDay(_this.iscroll[2]),
day = _this.bissextile(_this.getIscrollDay(_this.iscroll[0]),_this.getIscrollDay(_this.iscroll[1])),
li = '';
if(day+2 != _this.$('.'+data.domClass[2]+' li').length){
for(let l=1; l<=day; l++){
li += '<li>'+ (l<10? '0'+l : l) +'日</li>';
}
li = data.emptyli + li + data.emptyli;
_this.$('.'+data.domClass[2]+' ul')[0].innerHTML = li;
if(prevDay > day){
_this.iscroll[2].scrollToElement(_this.$('.'+data.domClass[2]+' li')[day-1]);
}
}
}
});
}
_this.event();
}
$(selector){
return document.querySelectorAll(selector);
}
event(){
let _this = this,
mask = _this.$('.rolldate-mask')[0],
cancel = _this.$('.rolldate-cancel')[0],
confirm = _this.$('.rolldate-confirm')[0];
mask.addEventListener('click', function(){_this.destroy();})
cancel.addEventListener('click', function(){_this.destroy();})
confirm.addEventListener('click', function(){
let el = _this.$(_this.config.el)[0],
date = _this.config.format;
_this.iscroll.forEach(function(v,i){
let d = _this.getIscrollDay(v),
str = i == 0? 'YYYY':i == 1? 'MM':i == 2? 'DD':i == 3? 'hh':i == 4? 'mm':'ss';
date = date.replace(str,d);
})
el.date = date;
if(_this.config.confirmBefore){
var flag = _this.config.confirmBefore.call(_this,el,date);
if(flag === false){
if(_this.config.confirmEnd){_this.config.confirmEnd.call(_this);}
return false
}else if(flag){
date = flag;
}
}
if(el.nodeName == 'INPUT'){
el.value = date;
}else{
el.innerText = date;
}
if(_this.config.confirmEnd){_this.config.confirmEnd();}
_this.destroy();
})
}
bissextile(year,month){
let day;
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
day = 31
} else if (month == 4 || month == 6 || month == 11 || month == 9) {
day = 30
} else if (month == 2) {
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) { //闰年
day = 29
} else {
day = 28
}
}
return day;
}
destroy(){
let _this = this;
_this.iscroll.forEach(function(v,i){v.destroy();})
document.body.removeChild(_this.$('.rolldate-container')[0]);
}
getIscrollDay(iscroll){
return this.$('.'+iscroll.wrapper.className+' li')[Math.abs(iscroll.y)/40+1].innerText.replace(/\D/g,'');
}
setTheme(){
let _this = this,
theme = _this.config.theme,
defaultTheme = {blue:'#16a1d3',red:'#d91600',green:'#009688',black:'#393D49'},
header = _this.$('.rolldate-container header')[0],
btn = _this.$('.rolldate-container .rolldate-confirm')[0];
if(theme){
if(defaultTheme[theme]){
header.style.background = btn.style.background = defaultTheme[theme];
}else{
header.style.background = btn.style.background = theme;
}
}
}
}
export let version = pkg.version;