| /** | 
|  @ Name:layui.cron Cron表达式解析器 | 
|  @ Author:贝哥哥 | 
|  @ License:MIT | 
|  */ | 
|   | 
| layui.define(['lay', 'element', 'form'], function(exports){ //假如该组件依赖 layui.form | 
|   var $ = layui.$ | 
|       ,layer = layui.layer | 
|       ,lay = layui.lay | 
|       ,element = layui.element | 
|       ,form = layui.form | 
|   | 
|   | 
|       //字符常量 | 
|       ,MOD_NAME = 'cron', ELEM = '.layui-cron', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide' | 
|   | 
|       ,ELEM_STATIC = 'layui-cron-static', ELEM_FOOTER = 'layui-cron-footer', ELEM_CONFIRM = '.cron-btns-confirm', ELEM_HINT = 'layui-cron-hint' | 
|   | 
|       ,ELEM_RUN_HINT = 'layui-cron-run-hint' | 
|   | 
|       //外部接口 | 
|       ,cron = { | 
|         v:'2.0.0' // cron 组件当前版本 | 
|         ,index: layui.cron ? (layui.cron.index + 10000) : 0 // corn 实例标识 | 
|   | 
|         //设置全局项 | 
|         ,set: function(options){ | 
|           var that = this; | 
|           that.config = $.extend({}, that.config, options); | 
|           return that; | 
|         } | 
|   | 
|         //事件监听 | 
|         ,on: function(events, callback){ | 
|           return layui.onevent.call(this, MOD_NAME, events, callback); | 
|         } | 
|   | 
|         //主体CSS等待事件 | 
|         ,ready: function (fn) { | 
|           var cssPath = layui.cache.base + "/cron.css?v=" + cron.v; | 
|           layui.link(cssPath, fn, "cron"); //此处的“cron”要对应 cron.css 中的样式: html #layuicss-cron{} | 
|           return this; | 
|         } | 
|       } | 
|   | 
|       //操作当前实例 | 
|       ,thisIns = function(){ | 
|         var that = this | 
|             ,options = that.config | 
|             ,id = options.id || options.index; | 
|   | 
|         return { | 
|           //提示框 | 
|           hint: function(content){ | 
|             that.hint.call(that, content); | 
|           } | 
|           ,config: options | 
|         } | 
|       } | 
|   | 
|       //构造器,创建实例 | 
|       ,Class = function(options){ | 
|         var that = this; | 
|         that.index = ++cron.index; | 
|         that.config = $.extend({}, that.config, cron.config, options); | 
|         cron.ready(function () { | 
|           that.init(); | 
|         }); | 
|       }; | 
|   | 
|   //默认配置 | 
|   Class.prototype.config = { | 
|     value: null // 当前表达式值,每秒执行一次 | 
|     ,isInitValue: true //用于控制是否自动向元素填充初始值(需配合 value 参数使用) | 
|     ,lang: "cn" //语言,只支持cn/en,即中文和英文 | 
|     ,tabs:[{key:'seconds',range:'0-59'},{key:'minutes',range:'0-59'},{key:'hours',range:'0-23'},{key:'days',range:'1-31'},{key:'months',range:'1-12'},{key:'weeks',range:'1-7'},{key:'years'}] | 
|     ,defaultCron: {seconds:"*",minutes:"*",hours:"*",days:"*", months:"*", weeks:"?", years:""} | 
|     ,trigger: "click" //呼出控件的事件 | 
|     ,btns: ['run', 'confirm'] //右下角显示的按钮,会按照数组顺序排列 | 
|     ,position: null //控件定位方式定位, 默认absolute,支持:fixed/absolute/static | 
|     ,zIndex: null //控件层叠顺序 | 
|     ,show: false //是否直接显示,如果设置 true,则默认直接显示控件 | 
|     ,showBottom: true //是否显示底部栏 | 
|     ,done: null //控件选择完毕后的回调,点击运行/确定也均会触发 | 
|     ,run: null // 最近运行时间接口 | 
|   }; | 
|   | 
|   //多语言 | 
|   Class.prototype.lang = function(){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,text = { | 
|       cn: { | 
|         tabs: [{title: "秒"} | 
|           , {title: "分"} | 
|           , {title: "时"} | 
|           , {title: "日"} | 
|           , {title: "月"} | 
|           , {title: "周", rateBegin: "第", rateMid: "周的星期", rateEnd:""} | 
|           , {title: "年"}] | 
|         , every: "每" | 
|         , unspecified: "不指定" | 
|         , period: "周期" | 
|         , periodFrom: "从" | 
|         , rate: "按照" | 
|         , rateBegin: "从" | 
|         , rateMid: "开始,每" | 
|         , rateEnd: "执行一次" | 
|         , weekday: "工作日" | 
|         , weekdayPrefix: "每月" | 
|         , weekdaySuffix: "号最近的那个工作日" | 
|         , lastday: "本月最后一日" | 
|         , lastweek: "本月最后一个星期" | 
|         , custom: "指定" | 
|         ,tools: { | 
|           confirm: '确定' | 
|           ,run: '运行' | 
|         } | 
|         ,formatError: ['Cron格式不合法', '<br>已为你重置'] | 
|       } | 
|       ,en: { | 
|         tabs: [{title:"Seconds"} | 
|           , {title:"Minutes"} | 
|           , {title:"Hours"} | 
|           , {title:"Days"} | 
|           , {title:"Months"} | 
|           , {title:"Weeks"} | 
|           , {title:"Years"}] | 
|         , every:"Every " | 
|         , unspecified:"Unspecified" | 
|         , period:"Period" | 
|         , periodFrom: "From" | 
|         , rate: "According to" | 
|         , rateBegin: "begin at" | 
|         , rateMid: ", every" | 
|         , rateEnd: " execute once" | 
|         , weekday: "Weekday" | 
|         , weekdayPrefix: "Every month at " | 
|         , weekdaySuffix: "号最近的那个工作日" | 
|         , lastday: "Last day of the month" | 
|         , lastweek: "本月最后一个星期" | 
|         , custom: "Custom" | 
|         ,tools: { | 
|           confirm: 'Confirm' | 
|           ,run: 'Run' | 
|         } | 
|         ,formatError: ['The cron format error', '<br>It has been reset'] | 
|       } | 
|     }; | 
|     return text[options.lang] || text['cn']; | 
|   }; | 
|   | 
|   //初始准备 | 
|   Class.prototype.init = function(){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,isStatic = options.position === 'static'; | 
|   | 
|     options.elem = lay(options.elem); | 
|   | 
|     options.eventElem = lay(options.eventElem); | 
|   | 
|     if(!options.elem[0]) return; | 
|   | 
|     //如果不是input|textarea元素,则默认采用click事件 | 
|     if(!that.isInput(options.elem[0])){ | 
|       if(options.trigger === 'focus'){ | 
|         options.trigger = 'click'; | 
|       } | 
|     } | 
|   | 
|     // 设置渲染所绑定元素的唯一KEY | 
|     if(!options.elem.attr('lay-key')){ | 
|       options.elem.attr('lay-key', that.index); | 
|       options.eventElem.attr('lay-key', that.index); | 
|     } | 
|   | 
|     // 当前实例主面板ID | 
|     that.elemID = 'layui-icon'+ options.elem.attr('lay-key'); | 
|   | 
|     //默认赋值 | 
|     if(options.value && options.isInitValue){ | 
|       that.setValue(options.value); | 
|     } | 
|     if(!options.value){ | 
|       options.value = options.elem[0].value||''; | 
|     } | 
|     var cronArr = options.value.split(' '); | 
|     if(cronArr.length >= 6){ | 
|       options.cron = { | 
|         seconds:cronArr[0], | 
|         minutes:cronArr[1], | 
|         hours:cronArr[2], | 
|         days:cronArr[3], | 
|         months:cronArr[4], | 
|         weeks:cronArr[5], | 
|         years:"", | 
|       }; | 
|     }else{ | 
|       options.cron = lay.extend({},options.defaultCron); | 
|     } | 
|   | 
|   | 
|     if(options.show || isStatic) that.render(); | 
|     isStatic || that.events(); | 
|   | 
|   | 
|   }; | 
|   | 
|   | 
|   // 控件主体渲染 | 
|   Class.prototype.render = function(){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,lang = that.lang() | 
|         ,isStatic = options.position === 'static' | 
|         ,tabFilter = 'cron-tab' + options.elem.attr('lay-key') | 
|         //主面板 | 
|         ,elem = that.elem = lay.elem('div', { | 
|           id: that.elemID | 
|           ,'class': [ | 
|             'layui-cron' | 
|             ,isStatic ? (' '+ ELEM_STATIC) : '' | 
|           ].join('') | 
|         }) | 
|   | 
|         // tab 内容区域 | 
|         ,elemTab = that.elemTab = lay.elem('div', { | 
|           'class': 'layui-tab layui-tab-card', | 
|           'lay-filter':tabFilter | 
|         }) | 
|         ,tabHead = lay.elem('ul',{ | 
|           'class': 'layui-tab-title' | 
|         }) | 
|         ,tabContent = lay.elem('div',{ | 
|           'class': 'layui-tab-content' | 
|         }) | 
|   | 
|         //底部区域 | 
|         ,divFooter = that.footer = lay.elem('div', { | 
|           'class': ELEM_FOOTER | 
|         }); | 
|   | 
|     if(options.zIndex) elem.style.zIndex = options.zIndex; | 
|   | 
|     // 生成tab 内容区域 | 
|     elemTab.appendChild(tabHead); | 
|     elemTab.appendChild(tabContent); | 
|     lay.each(lang.tabs, function(i,item){ | 
|       // 表头 | 
|       var li = lay.elem('li',{ | 
|         'class':i===0?THIS:"", | 
|         'lay-id':i | 
|       }); | 
|       li.innerHTML = item.title; | 
|       tabHead.appendChild(li); | 
|   | 
|       // 表体 | 
|       tabContent.appendChild(that.getTabContentChildElem(i)); | 
|     }); | 
|   | 
|     // 主区域 | 
|     elemMain = that.elemMain = lay.elem('div', { | 
|       'class': 'layui-cron-main' | 
|     }); | 
|     elemMain.appendChild(elemTab); | 
|   | 
|     //生成底部栏 | 
|     lay(divFooter).html(function(){ | 
|       var html = [], btns = []; | 
|       lay.each(options.btns, function(i, item){ | 
|         var title = lang.tools[item] || 'btn'; | 
|         btns.push('<span lay-type="'+ item +'" class="cron-btns-'+ item +'">'+ title +'</span>'); | 
|       }); | 
|       html.push('<div class="cron-footer-btns">'+ btns.join('') +'</div>'); | 
|       return html.join(''); | 
|     }()); | 
|   | 
|     //插入到主区域 | 
|     elem.appendChild(elemMain); | 
|   | 
|     options.showBottom && elem.appendChild(divFooter); | 
|   | 
|   | 
|     //移除上一个控件 | 
|     that.remove(Class.thisElemCron); | 
|   | 
|     //如果是静态定位,则插入到指定的容器中,否则,插入到body | 
|     isStatic ? options.elem.append(elem) : ( | 
|         document.body.appendChild(elem) | 
|             ,that.position() | 
|     ); | 
|   | 
|   | 
|     that.checkCron(); | 
|   | 
|     that.elemEvent(); // 主面板事件 | 
|   | 
|     Class.thisElemCron = that.elemID; | 
|   | 
|     form.render(); | 
|   | 
|   } | 
|   | 
|   // 渲染 tab 子控件 | 
|   Class.prototype.getTabContentChildElem = function(index){ | 
|     var that = this, | 
|         options = that.config, | 
|         tabItem = options.tabs[index], | 
|         tabItemKey = tabItem.key, | 
|         lang = that.lang(), | 
|         tabItemLang = lang.tabs[index], | 
|         cron = options.cron, | 
|         formFilter = 'cronForm'+tabItemKey+options.elem.attr('lay-key') | 
|         ,data = function(){ | 
|           if(cron[tabItemKey].indexOf('-') != -1){ | 
|             // 周期数据 | 
|             var arr = cron[tabItemKey].split('-'); | 
|             return { | 
|               type:'range', | 
|               start:arr[0], | 
|               end:arr[1] | 
|             }; | 
|           } | 
|           if(cron[tabItemKey].indexOf('/') != -1){ | 
|             // 频率数据 | 
|             var arr = cron[tabItemKey].split('/'); | 
|             return { | 
|               type:'rate', | 
|               begin:arr[0], | 
|               rate:arr[1] | 
|             }; | 
|           } | 
|           if(cron[tabItemKey].indexOf(',') != -1 || /^\+?[0-9][0-9]*$/.test(cron[tabItemKey])){ | 
|             // 按照指定执行 | 
|             var arr = cron[tabItemKey].split(',').map(Number); | 
|             return { | 
|               type:'custom', | 
|               values:arr | 
|             }; | 
|           } | 
|           if(cron[tabItemKey].indexOf('W') != -1){ | 
|             // 最近的工作日 | 
|             var value = cron[tabItemKey].replace('W',''); | 
|             return { | 
|               type:'weekday', | 
|               value: value | 
|             }; | 
|           } | 
|           if(index===3 && cron[tabItemKey] === 'L'){ | 
|             // 本月最后一日 | 
|             return { | 
|               type:'lastday', | 
|               value: 'L' | 
|             }; | 
|           } | 
|           if(index===5 && cron[tabItemKey].indexOf('L') != -1){ | 
|             // 本月最后一个周 value | 
|             var value = cron[tabItemKey].replace('L',''); | 
|             return { | 
|               type:'lastweek', | 
|               value: value | 
|             }; | 
|           } | 
|           if(cron[tabItemKey] === '*'){ | 
|             // 每次 | 
|             return { | 
|               type:'every', | 
|               value:'*' | 
|             }; | 
|           } | 
|           if(cron[tabItemKey] === '?'||cron[tabItemKey]===undefined||cron[tabItemKey]===''){ | 
|             // 不指定 | 
|             return { | 
|               type:'unspecified', | 
|               value:cron[tabItemKey] | 
|             }; | 
|           } | 
|         }() | 
|         , rangeData = function(){ | 
|           if(tabItem.range){ | 
|             var arr = tabItem.range.split('-'); | 
|             return { | 
|               min:parseInt(arr[0]), | 
|               max:parseInt(arr[1]) | 
|             }; | 
|           } | 
|         }(); | 
|     var elem = lay.elem('div', { | 
|       'class': 'layui-tab-item layui-form '+(index===0?SHOW:"") | 
|       ,'lay-filter': formFilter | 
|     }); | 
|   | 
|     // 每次 | 
|     elem.appendChild(function(){ | 
|       var everyRadio = lay.elem('input',{ | 
|         'name': tabItemKey+'[type]' | 
|         ,'type': 'radio' | 
|         ,'value': 'every' | 
|         ,'title': lang.every+tabItemLang.title | 
|       }); | 
|       if(data.type === 'every'){ | 
|         lay(everyRadio).attr('checked', true); | 
|       } | 
|       var everyDiv = lay.elem('div',{ | 
|         'class':'cron-row' | 
|       }); | 
|       everyDiv.appendChild(everyRadio); | 
|       return everyDiv; | 
|     }()); | 
|   | 
|     // 不指定,从日开始 | 
|     if(index >= 3){ | 
|       elem.appendChild(function(){ | 
|         var unspecifiedRadio = lay.elem('input',{ | 
|           'name': tabItemKey+'[type]' | 
|           ,'type': 'radio' | 
|           ,'value': 'unspecified' | 
|           ,'title': lang.unspecified | 
|         }); | 
|         if(data.type==='unspecified'){ | 
|           lay(unspecifiedRadio).attr('checked', true); | 
|         } | 
|         var unspecifiedDiv = lay.elem('div',{ | 
|           'class':'cron-row' | 
|         }); | 
|         unspecifiedDiv.appendChild(unspecifiedRadio); | 
|         return unspecifiedDiv; | 
|       }()); | 
|     } | 
|   | 
|     // 周期 | 
|     var rangeChild = [function(){ | 
|       var rangeRadio = lay.elem('input',{ | 
|         'name': tabItemKey+'[type]' | 
|         ,'type': 'radio' | 
|         ,'value': 'range' | 
|         ,'title': lang.period | 
|       }); | 
|       if(data.type === 'range'){ | 
|         lay(rangeRadio).attr('checked', true); | 
|       } | 
|       return rangeRadio; | 
|     }(),function(){ | 
|       var elem = lay.elem('div',{ | 
|         'class':'cron-input-mid' | 
|       }); | 
|       elem.innerHTML = lang.periodFrom; | 
|       return elem; | 
|     }(),function(){ | 
|       var elem = lay.elem('input',{ | 
|         'class':'cron-input', | 
|         'type': 'number', | 
|         'name': 'rangeStart', | 
|         'value': data.start||'' | 
|       }); | 
|       return elem; | 
|     }(),function(){ | 
|       var elem = lay.elem('div',{ | 
|         'class':'cron-input-mid' | 
|       }); | 
|       elem.innerHTML = '-'; | 
|       return elem; | 
|     }(),function(){ | 
|       var elem = lay.elem('input',{ | 
|         'class':'cron-input', | 
|         'type': 'number', | 
|         'name': 'rangeEnd', | 
|         'value': data.end||'' | 
|       }); | 
|       return elem; | 
|     }(),function(){ | 
|       var elem = lay.elem('div',{ | 
|         'class':'cron-input-mid' | 
|       }); | 
|       elem.innerHTML = tabItemLang.title; | 
|       return elem; | 
|     }()] | 
|   | 
|         ,rangeDiv = lay.elem('div',{ | 
|       'class':'cron-row' | 
|     }); | 
|     lay.each(rangeChild,function(i,item){ | 
|       rangeDiv.appendChild(item); | 
|     }); | 
|     if(tabItem.range){ | 
|       var rangeTip = lay.elem('div',{ | 
|         'class':'cron-tips' | 
|       }); | 
|       rangeTip.innerHTML = ['(',tabItem.range,')'].join(''); | 
|       rangeDiv.appendChild(rangeTip); | 
|     } | 
|     elem.appendChild(rangeDiv); | 
|   | 
|     // 频率,年没有 | 
|     if(index<6){ | 
|       var rateChild = [function(){ | 
|         var rateRadio = lay.elem('input',{ | 
|           'name': tabItemKey+'[type]' | 
|           ,'type': 'radio' | 
|           ,'value': 'rate' | 
|           ,'title': lang.rate | 
|         }); | 
|         if(data.type === 'rate'){ | 
|           lay(rateRadio).attr('checked', true); | 
|         } | 
|         return rateRadio; | 
|       }(),function(){ | 
|         var elem = lay.elem('div',{ | 
|           'class':'cron-input-mid' | 
|         }); | 
|         elem.innerHTML = tabItemLang.rateBegin || lang.rateBegin; | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('input',{ | 
|           'class':'cron-input', | 
|           'type': 'number', | 
|           'name': 'begin', | 
|           'value': data.begin||'' | 
|         }); | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('div',{ | 
|           'class':'cron-input-mid' | 
|         }); | 
|         elem.innerHTML = tabItemLang.rateMid || (tabItemLang.title+lang.rateMid); | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('input',{ | 
|           'class':'cron-input', | 
|           'type': 'number', | 
|           'name': 'rate', | 
|           'value': data.rate||'' | 
|         }); | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('div',{ | 
|           'class':'cron-input-mid' | 
|         }); | 
|         elem.innerHTML = undefined!=tabItemLang.rateEnd ? tabItemLang.rateEnd:(tabItemLang.title+lang.rateEnd); | 
|         if(undefined!=tabItemLang.rateEnd&&tabItemLang.rateEnd===''){ | 
|           lay(elem).addClass(HIDE); | 
|         } | 
|         return elem; | 
|       }()] | 
|   | 
|           ,rateDiv = lay.elem('div',{ | 
|         'class':'cron-row' | 
|       }); | 
|       lay.each(rateChild,function(i,item){ | 
|         rateDiv.appendChild(item); | 
|       }); | 
|       if(tabItem.range){ | 
|         var rateTip = lay.elem('div',{ | 
|           'class':'cron-tips' | 
|         }); | 
|         if(index===5){ | 
|           // 周 | 
|           rateTip.innerHTML = '(1-4/1-7)'; | 
|         }else{ | 
|           rateTip.innerHTML = ['(',rangeData.min,'/',(rangeData.max+(index<=2?1:0)),')'].join(''); | 
|         } | 
|         rateDiv.appendChild(rateTip); | 
|       } | 
|       elem.appendChild(rateDiv); | 
|     } | 
|   | 
|     // 特殊:日(最近的工作日、最后一日),周(最后一周) | 
|     if(index===3){ | 
|       // 日 | 
|       // 最近的工作日 | 
|       var weekChild = [function(){ | 
|         var weekRadio = lay.elem('input',{ | 
|           'name': tabItemKey+'[type]' | 
|           ,'type': 'radio' | 
|           ,'value': 'weekday' | 
|           ,'title': lang.weekday | 
|         }); | 
|         if(data.type === 'weekday'){ | 
|           lay(weekRadio).attr('checked', true); | 
|         } | 
|         return weekRadio; | 
|       }(),function(){ | 
|         var elem = lay.elem('div',{ | 
|           'class':'cron-input-mid' | 
|         }); | 
|         elem.innerHTML = lang.weekdayPrefix; | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('input',{ | 
|           'class':'cron-input', | 
|           'type': 'number', | 
|           'name': 'weekday', | 
|           'value': data.value||'' | 
|         }); | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('div',{ | 
|           'class':'cron-input-mid' | 
|         }); | 
|         elem.innerHTML = lang.weekdaySuffix; | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('div',{ | 
|           'class':'cron-tips' | 
|         }); | 
|         elem.innerHTML = ['(',tabItem.range,')'].join(''); | 
|         return elem; | 
|       }()] | 
|   | 
|           ,weekDiv = lay.elem('div',{ | 
|         'class':'cron-row' | 
|       }); | 
|       lay.each(weekChild,function(i,item){ | 
|         weekDiv.appendChild(item); | 
|       }); | 
|       elem.appendChild(weekDiv); | 
|   | 
|       // 本月最后一日 | 
|       elem.appendChild(function(){ | 
|         var lastRadio = lay.elem('input',{ | 
|           'name': tabItemKey+'[type]' | 
|           ,'type': 'radio' | 
|           ,'value': 'lastday' | 
|           ,'title': lang.lastday | 
|         }); | 
|         if(data.type === 'lastday'){ | 
|           lay(lastRadio).attr('checked', true); | 
|         } | 
|         var lastDiv = lay.elem('div',{ | 
|           'class':'cron-row' | 
|         }); | 
|         lastDiv.appendChild(lastRadio); | 
|         return lastDiv; | 
|       }()); | 
|   | 
|     } | 
|   | 
|     if(index===5){ | 
|       // 本月最后一个周几 | 
|       var lastWeekChild = [function(){ | 
|         var lastWeekRadio = lay.elem('input',{ | 
|           'name': tabItemKey+'[type]' | 
|           ,'type': 'radio' | 
|           ,'value': 'lastweek' | 
|           ,'title': lang.lastweek | 
|         }); | 
|         if(data.type === 'lastweek'){ | 
|           lay(lastWeekRadio).attr('checked', true); | 
|         } | 
|         return lastWeekRadio; | 
|       }(),function(){ | 
|         var elem = lay.elem('input',{ | 
|           'class':'cron-input', | 
|           'type': 'number', | 
|           'name': 'lastweek', | 
|           'value': data.value||'' | 
|         }); | 
|         return elem; | 
|       }(),function(){ | 
|         var elem = lay.elem('div',{ | 
|           'class':'cron-tips' | 
|         }); | 
|         elem.innerHTML = ['(',tabItem.range,')'].join(''); | 
|         return elem; | 
|       }()] | 
|   | 
|           ,lastWeekDiv = lay.elem('div',{ | 
|         'class':'cron-row' | 
|       }); | 
|       lay.each(lastWeekChild,function(i,item){ | 
|         lastWeekDiv.appendChild(item); | 
|       }); | 
|       elem.appendChild(lastWeekDiv); | 
|   | 
|     } | 
|   | 
|     // 指定 | 
|     if(index <= 5){ | 
|       elem.appendChild(function(){ | 
|         var customRadio = lay.elem('input',{ | 
|           'name': tabItemKey+'[type]' | 
|           ,'type': 'radio' | 
|           ,'value': 'custom' | 
|           ,'title': lang.custom | 
|         }); | 
|         if(data.type === 'custom'){ | 
|           lay(customRadio).attr('checked', true); | 
|         } | 
|         var customDiv = lay.elem('div',{ | 
|           'class':'cron-row' | 
|         }); | 
|         customDiv.appendChild(customRadio); | 
|         return customDiv; | 
|       }()); | 
|   | 
|       // 指定数值,时分秒显示两位数,自动补零 | 
|       elem.appendChild(function(){ | 
|         var customGrid = lay.elem('div',{ | 
|           'class': 'cron-grid' | 
|         }); | 
|         var i = rangeData.min; | 
|         while(i<=rangeData.max){ | 
|           // 时分秒显示两位数,自动补零 | 
|           var gridItemValue = index<=2 ? lay.digit(i,2) : i; | 
|           var gridItem = lay.elem('input',{ | 
|             'type': 'checkbox', | 
|             'title': gridItemValue, | 
|             'lay-skin': 'primary', | 
|             'name':tabItemKey+'[custom]', | 
|             'value':i | 
|           }); | 
|           if(data.values && data.values.includes(i)){ | 
|             lay(gridItem).attr('checked',true); | 
|           } | 
|           customGrid.appendChild(gridItem); | 
|           i++; | 
|         } | 
|         return customGrid; | 
|       }()); | 
|     } | 
|   | 
|   | 
|     return elem; | 
|   } | 
|   | 
|   //是否输入框 | 
|   Class.prototype.isInput = function(elem){ | 
|     return /input|textarea/.test(elem.tagName.toLocaleLowerCase()); | 
|   }; | 
|   | 
|   // 绑定的元素事件处理 | 
|   Class.prototype.events = function(){ | 
|     var that = this | 
|         ,options = that.config | 
|   | 
|         //绑定呼出控件事件 | 
|         ,showEvent = function(elem, bind){ | 
|           elem.on(options.trigger, function(){ | 
|             bind && (that.bindElem = this); | 
|             that.render(); | 
|           }); | 
|         }; | 
|   | 
|     if(!options.elem[0] || options.elem[0].eventHandler) return; | 
|   | 
|     showEvent(options.elem, 'bind'); | 
|     showEvent(options.eventElem); | 
|   | 
|     //绑定关闭控件事件 | 
|     lay(document).on('click', function(e){ | 
|       if(e.target === options.elem[0] | 
|           || e.target === options.eventElem[0] | 
|           || e.target === lay(options.closeStop)[0]){ | 
|         return; | 
|       } | 
|       that.remove(); | 
|     }).on('keydown', function(e){ | 
|       if(e.keyCode === 13){ | 
|         if(lay('#'+ that.elemID)[0] && that.elemID === Class.thisElemDate){ | 
|           e.preventDefault(); | 
|           lay(that.footer).find(ELEM_CONFIRM)[0].click(); | 
|         } | 
|       } | 
|     }); | 
|   | 
|     //自适应定位 | 
|     lay(window).on('resize', function(){ | 
|       if(!that.elem || !lay(ELEM)[0]){ | 
|         return false; | 
|       } | 
|       that.position(); | 
|     }); | 
|   | 
|     options.elem[0].eventHandler = true; | 
|   }; | 
|   | 
|   // 主面板事件 | 
|   Class.prototype.elemEvent = function(){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,tabFilter = 'cron-tab' + options.elem.attr('lay-key'); | 
|   | 
|     // 阻止主面板点击冒泡,避免因触发文档事件而关闭主面 | 
|     lay(that.elem).on('click', function(e){ | 
|       lay.stope(e); | 
|     }); | 
|   | 
|     // tab选项卡切换 | 
|     var lis = lay(that.elemTab).find('li'); | 
|     lis.on('click',function(){ | 
|       var layid = lay(this).attr('lay-id'); | 
|       if(undefined === layid){ | 
|         return; | 
|       } | 
|       element.tabChange(tabFilter, layid); | 
|     }); | 
|   | 
|     // cron选项点击 | 
|     form.on('radio', function(data){ | 
|       var $parent = data.othis.parent(); | 
|       var formFilter = $parent.parent().attr('lay-filter'); | 
|       var formData = form.val(formFilter); | 
|       var radioType = data.value; | 
|       if('range'===radioType){ | 
|         // 范围 | 
|         form.val(formFilter,{ | 
|           rangeStart: formData.rangeStart||0, | 
|           rangeEnd: formData.rangeEnd||2 | 
|         }); | 
|       } | 
|       if('rate'===radioType){ | 
|         // 频率 | 
|         form.val(formFilter,{ | 
|           begin: formData.begin||0, | 
|           rate: formData.rate||2 | 
|         }); | 
|       } | 
|       if('custom'===radioType){ | 
|         // custom | 
|         var $grid = $parent.next(); | 
|         if($grid.find(':checkbox:checked').length<=0){ | 
|           $grid.children(':checkbox:first').next().click() | 
|         } | 
|       } | 
|       if('weekday'===radioType){ | 
|         // weekday | 
|         form.val(formFilter,{ | 
|           weekday: formData.weekday||1 | 
|         }); | 
|       } | 
|       if('lastweek'===radioType){ | 
|         // lastweek | 
|         form.val(formFilter,{ | 
|           lastweek: formData.lastweek||1 | 
|         }); | 
|       } | 
|   | 
|     }); | 
|   | 
|     //点击底部按钮 | 
|     lay(that.footer).find('span').on('click', function(){ | 
|       var type = lay(this).attr('lay-type'); | 
|       that.tool(this, type); | 
|     }); | 
|   }; | 
|   | 
|   //底部按钮点击事件 | 
|   Class.prototype.tool = function(btn, type){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,lang = that.lang() | 
|         ,isStatic = options.position === 'static' | 
|         ,active = { | 
|       //运行 | 
|       run: function(){ | 
|         var value = that.parse(); | 
|         var loading = layer.load(); | 
|         $.get(options.run,{cron:value},function(res){ | 
|           layer.close(loading); | 
|           if(res.code !== 0){ | 
|             return that.hint(res.msg); | 
|           } | 
|           that.runHint(res.data); | 
|         },'json').fail(function(){ | 
|           layer.close(loading); | 
|           that.hint('服务器异常!'); | 
|         }); | 
|       } | 
|   | 
|       //确定 | 
|       ,confirm: function(){ | 
|         var value = that.parse(); | 
|         that.done([value]); | 
|         that.setValue(value).remove() | 
|       } | 
|     }; | 
|     active[type] && active[type](); | 
|   }; | 
|   | 
|   //执行 done/change 回调 | 
|   Class.prototype.done = function(param, type){ | 
|     var that = this | 
|         ,options = that.config; | 
|   | 
|     param = param || [that.parse()]; | 
|     typeof options[type || 'done'] === 'function' && options[type || 'done'].apply(options, param); | 
|   | 
|     return that; | 
|   }; | 
|   | 
|   // 解析cron表达式 | 
|   Class.prototype.parse = function(){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,valueArr = []; | 
|   | 
|     lay.each(options.tabs, function(index, item){ | 
|       var key = item.key; | 
|       var formFilter = 'cronForm' + key + options.elem.attr('lay-key'); | 
|       var formData = form.val(formFilter); | 
|       var radioType = (key+'[type]'); | 
|       var current = ""; | 
|       if(formData[radioType] === 'every'){ | 
|         // 每次 | 
|         current = "*"; | 
|       } | 
|       if(formData[radioType] === 'range'){ | 
|         // 范围 | 
|         current = formData.rangeStart + "-" + formData.rangeEnd; | 
|       } | 
|       if(formData[radioType] === 'rate'){ | 
|         // 频率 | 
|         current = formData.begin + "/" + formData.rate; | 
|       } | 
|       if(formData[radioType] === 'custom'){ | 
|         // 指定 | 
|         var checkboxName = (item.key+'[custom]'); | 
|         var customArr = []; | 
|         $('input[name="' + checkboxName + '"]:checked').each(function() { | 
|           customArr.push($(this).val()); | 
|         }); | 
|         current = customArr.join(','); | 
|       } | 
|       if(formData[radioType] === 'weekday'){ | 
|         // 每月 formData.weekday 号最近的那个工作日 | 
|         current = formData.weekday + "W"; | 
|       } | 
|       if(formData[radioType] === 'lastday'){ | 
|         // 本月最后一日 | 
|         current = "L"; | 
|       } | 
|       if(formData[radioType] === 'lastweek'){ | 
|         // 本月最后星期 | 
|         current = formData.lastweek + "L"; | 
|       } | 
|   | 
|       if(formData[radioType] === 'unspecified' && index != 6){ | 
|         // 不指定 | 
|         current = "?"; | 
|       } | 
|       if(current !== ""){ | 
|         valueArr.push(current); | 
|         options.cron[key] = current; | 
|       } | 
|     }); | 
|     return valueArr.join(' '); | 
|   }; | 
|   | 
|   //控件移除 | 
|   Class.prototype.remove = function(prev){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,elem = lay('#'+ (prev || that.elemID)); | 
|     if(!elem[0]) return that; | 
|   | 
|     if(!elem.hasClass(ELEM_STATIC)){ | 
|       that.checkCron(function(){ | 
|         elem.remove(); | 
|       }); | 
|     } | 
|     return that; | 
|   }; | 
|   | 
|   //定位算法 | 
|   Class.prototype.position = function(){ | 
|     var that = this | 
|         ,options = that.config; | 
|     lay.position(that.bindElem || options.elem[0], that.elem, { | 
|       position: options.position | 
|     }); | 
|     return that; | 
|   }; | 
|   | 
|   //提示 | 
|   Class.prototype.hint = function(content){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,div = lay.elem('div', { | 
|       'class': ELEM_HINT | 
|     }); | 
|   | 
|     if(!that.elem) return; | 
|   | 
|     div.innerHTML = content || ''; | 
|     lay(that.elem).find('.'+ ELEM_HINT).remove(); | 
|     that.elem.appendChild(div); | 
|   | 
|     clearTimeout(that.hinTimer); | 
|     that.hinTimer = setTimeout(function(){ | 
|       lay(that.elem).find('.'+ ELEM_HINT).remove(); | 
|     }, 3000); | 
|   }; | 
|   | 
|   //运行提示 | 
|   Class.prototype.runHint = function(runList){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,div = lay.elem('div', { | 
|       'class': ELEM_RUN_HINT | 
|     }); | 
|     // debugger; | 
|     if(!that.elem||!runList||!runList.length) return; | 
|   | 
|   | 
|     lay(div).html(function(){ | 
|       var html = []; | 
|       lay.each(runList, function(i, item){ | 
|         html.push('<div class="cron-run-list">'+ item +'</div>'); | 
|       }); | 
|       return html.join(''); | 
|     }()); | 
|   | 
|     lay(that.elem).find('.'+ ELEM_RUN_HINT).remove(); | 
|     that.elem.appendChild(div); | 
|   }; | 
|   | 
|   //赋值 | 
|   Class.prototype.setValue = function(value=''){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,elem = that.bindElem || options.elem[0] | 
|         ,valType = that.isInput(elem) ? 'val' : 'html' | 
|   | 
|     options.position === 'static' || lay(elem)[valType](value || ''); | 
|     elem.textContent = '生成'; | 
|     return this; | 
|   }; | 
|   | 
|   //cron校验 | 
|   Class.prototype.checkCron = function(fn){ | 
|     var that = this | 
|         ,options = that.config | 
|         ,lang = that.lang() | 
|         ,elem = that.bindElem || options.elem[0] | 
|         ,value = that.isInput(elem) ? elem.value : (options.position === 'static' ? '' : elem.innerHTML) | 
|   | 
|         ,checkValid = function(value=""){ | 
|   | 
|     }; | 
|   | 
|     // cron 值,多个空格替换为一个空格,去掉首尾空格 | 
|     value = value || options.value; | 
|     if(typeof value === 'string'){ | 
|       value = value.replace(/\s+/g, ' ').replace(/^\s|\s$/g, ''); | 
|     } | 
|   | 
|     if(fn==='init') return checkValid(value),that; | 
|   | 
|     value = that.parse(); | 
|     if(value){ | 
|       that.setValue(value); | 
|     } | 
|     fn && fn(); | 
|     return that; | 
|   }; | 
|   | 
|   //核心入口 | 
|   cron.render = function(options){ | 
|     var ins = new Class(options); | 
|     return thisIns.call(ins); | 
|   }; | 
|   | 
|   exports('cron', cron); | 
| }); |