| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 | angular.module('wui.date',[]).directive('wuiDate', function() {	return {		// Restrict to elements and attributes		restrict: 'EA',		// Assign the angular link function		compile: fieldCompile,		// Assign the angular directive template HTML		template: fieldTemplate,		// templateUrl: "pageTemplate.html",		// Assign the angular scope attribute formatting		scope: {			id: '@?', // 时间插件主键 默认scope.$id			name: '@?', // 绑定表单验证input的name属性			format: '@?', // 定义时间格式 默认yyyy-mm-dd			interval: '@?', // 定义time时间间隔 默认30minutes			placeholder: '@?', // 选择框提示语 默认 '选择时间'			position: '@?', // 定义选择框浮动位置 默认left			ngModel: '=', // 父scope绑定的时间的属性			btns: '@', // 按钮信息 空则不显示任何按钮			dateClass: '@?', // 自定义样式			width: '@?', // 输入框宽度 支持px及百分比			size: '@?' // 插件大小 默认为迷你型  large、L、l表示大型窗		}	};	function fieldCompile(scope, element, attr) {		return {			pre: function(scope, element, attr) {				scope.id = scope.id || 'date' + scope.$id; // 生成插件唯一id				var position = scope.position || 'left', // 面板浮动					iptWidth = parseInt(scope.width); // 输入框宽度					iptWidthU = scope.width?scope.width.search('%') == -1 ? 'px' : '%':null,					size = scope.size != 'large' && scope.size != 'l' && scope.size != 'L' ? 'small' : null;				angular.element(element).find('.wui-date').addClass('wui-date-' + scope.id);				if(scope.name != '' && typeof scope.name != 'undefined') {					angular.element(element).find('.wui-date input').attr('name', scope.name);				}				if(size) {					angular.element(element).find('.wui-date').addClass(size); // 大小				}				angular.element(element).find('.wui-date .wui-date-picker').addClass(position); // 面板添加浮动				scope.dateClass ? angular.element(element).find('.wui-date').addClass(scope.dateClass) : null; // 插件外部样式				iptWidth ? angular.element(element).find('.wui-date').css('width', iptWidth + iptWidthU) : null; // 输入框宽度			},			post: function(scope, element, attr) {				fieldLink(scope, element, attr);			}		}	}	function fieldLink(scope, element, attr) {		// 初始化		var GMTDate, // GMT格式时间			format = (scope.format || 'yyyy-mm-dd').toLowerCase(), // 时间格式			interval = parseInt(scope.interval) || 30, // time间隔			interval = (60 % interval === 0 || interval % 60 === 0) && interval <= 12 * 60 ? interval : 30,			placeholder = scope.placeholder || "选择时间",			maxYear = parseInt(new Date().getFullYear()) + 100, // 插件最大year			minYear = 1900, // 插件最小year			SPECIAL_DATE_RULES = ['至今'], // 特殊字符串规则			DATE_RULES = ['yyyy-mm-dd hh:mm:ss', 'yyyy-mm-dd hh:mm', 'yyyy-mm-dd', 'yyyy-mm']; // 内置的日期格式		// angular对象初始化		scope.date = {			year: '0000',			month: '00',			date: '00',			hours: '00',			minutes: '00',			seconds: '00',			dateList: [],			timeList: [],			yearList: {},			showPicker: false,			showTimePicker: false,			showTimeList: true,			showClearIcon: false,			selector: 1,			btns: scope.btns ? JSON.parse(scope.btns.replace(/'/g, '"')) : {}, // btns字符串转对象			showBtn: false,		};		// 初始化GMT时间		function GMTDateInit(date) {			date = dateFormat(date);			if(date) {				if(!SPECIAL_DATE_RULES.includes(date)) {					GMTDate = StrDateToGMT(date);				} else {					GMTDate = new Date();				}			} else {				GMTDate = new Date();			}		}		// 加载dom		function domBootstrap(format) {			if(Object.keys(scope.date.btns).length) {				scope.date.showBtn = true;			}			switch(format) {				case 'yyyy-mm-dd hh:mm:ss':				case 'yyyy-mm-dd hh:mm':					scope.date.showTimePicker = true; // 					scope.date.selector = 1;					angular.element(element).find('.wui-date .wui-date-picker').removeClass('no_timer');					break;				case 'yyyy-mm-dd':					scope.date.showTimePicker = false;					angular.element(element).find('.wui-date .wui-date-picker').addClass('no_timer');					scope.date.selector = 1;					break;				case 'yyyy-mm':					scope.date.showTimePicker = false;					scope.date.selector = 2;					angular.element(element).find('.wui-date .wui-date-picker').addClass('no_timer');					break;				default:					break;			}		}		// 时间格式化		function dateFormat(date) {			if(!date) {				return null;			}			if(SPECIAL_DATE_RULES.includes(date)) { // 特殊字符串				return date;			}			date = date.toString().replace(/[\D]/g, ""); // 清除时间除数字外字符			var len = format.replace(/\W/g, "").length; // 默认格式长度			var str = date.length >= len ? date.slice(0, len) : '';			if(date && str) {				switch(format) {					case 'yyyy-mm-dd hh:mm:ss':						date = str.replace(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/, "$1-$2-$3 $4:$5:$6");						break;					case 'yyyy-mm-dd hh:mm':						date = str.replace(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/, "$1-$2-$3 $4:$5");						break;					case 'yyyy-mm-dd':						date = str.replace(/(\d{4})(\d{2})(\d{2})/, "$1-$2-$3");						break;					case 'yyyy-mm':						date = str.replace(/(\d{4})(\d{2})/, "$1-$2");						break;					default:						break;				}				return str !== date ? date : null; // 正则替换失败后返回原字符串  替换成功则 str != date 			}			return null;		}		// 字符串时间格式化为标准时间		function StrDateToGMT(date) {			if(date && new Date(date) != 'Invalid Date') {				return new Date(date);			}			return null;		}		// 标准时间格式化为字符串时间		function GMTToStrDate(date) {			date = new Date(date);			if(date && toString.call(date) == '[object Date]') {				return date.getFullYear() + '/' + getDoubleDigit(date.getMonth() + 1) + '/' + getDoubleDigit(date.getDate()) + ' ' + getDoubleDigit(date.getHours()) + ':' + getDoubleDigit(date.getMinutes()) + ':' + getDoubleDigit(date.getSeconds());			}			return null;		}		// 生成两位月、日		function getDoubleDigit(num) {			num = '0' + num;			return num.slice(-2);		}		// 显示的年月日时分秒数据 		function getAllDate() {			scope.date.year = GMTDate.getFullYear(); // 初始化年份			scope.date.month = getDoubleDigit(GMTDate.getMonth() + 1); // 两位月份			scope.date.day = getDoubleDigit(GMTDate.getDate()); // 两位日期			scope.date.hours = getDoubleDigit(GMTDate.getHours()); // 两位时			scope.date.minutes = getDoubleDigit(GMTDate.getMinutes()); // 两位分			scope.date.seconds = getDoubleDigit(GMTDate.getSeconds()); // 两位秒		}		// 生成日期数据		function getDateList(date) {			date = date || new Date();			if(date.getFullYear() <= maxYear && date.getFullYear() >= minYear) { // 判断年份上下限				// 初始化数据				var dateList = [], // 属性type:1 表示上月的日期 2表示当月日期 3表示下月日期, 属性date:当天是几号					weekOfFirstDay, // 当月第一天是周几					endDayOfMonth, // 当前月份最后一天					endDayOfLastMonth, // 上月最后一天					modelDate = StrDateToGMT(scope.ngModel);				getAllDate();				weekOfFirstDay = new Date(scope.date.year, scope.date.month - 1, 1).getDay();				endDayOfMonth = new Date(scope.date.year, scope.date.month, 0).getDate();				endDayOfLastMonth = new Date(scope.date.year, scope.date.month - 1, 0).getDate();				// 当月日期列表				for(var i = 1; i <= endDayOfMonth; i++) {					// 面板显示日期与输入框日期相同返回 true					if(modelDate) {						var condition1 = modelDate.getFullYear() == scope.date.year && (modelDate.getMonth() + 1) == scope.date.month && modelDate.getDate() == i;					}					// 面板日期为系统当天日期返回 true					var condition2 = new Date().getFullYear() == GMTDate.getFullYear() && new Date().getMonth() == GMTDate.getMonth() && new Date().getDate() == i;					var dateObj = {						'type': 2,						'date': i					};					if(condition1) {						dateObj.current = true; // currently picked					}					if(condition2) {						dateObj.today = true; // today					}					dateList.push(dateObj);				}				// 根据week生成填充上月日期				var prevLen = 0; // the length of prev month day				prevLen = weekOfFirstDay || 7;				for(var j = 0; j < prevLen; j++) {					dateList.unshift({						'type': 1,						'date': endDayOfLastMonth--					});				}				// 每个面板最多显示42天  计算剩余下月显示的天数				var nextLen = 42 - prevLen - endDayOfMonth;				for(var k = 1; k <= nextLen; k++) {					dateList.push({						'type': 3,						'date': k					});				}				// 按每行显示7天分割数组				var count = 0,					arr = [],					resList = [];				for(var l = 0; l < dateList.length; l++) {					count++;					arr.push(dateList[l]);					if(count >= 7) {						resList.push(arr);						count = 0;						arr = [];					}				}				return resList;			}		}		// 生成时间选择列表数据		function createTimeList() {			var h = 8,				m = 0,				resList = [{					'time': '08:00'				}];			// fill time list			for(var i = 1; i < 24 * 60 / interval; i++) {				m = m + interval;				if(m >= 60) {					h = h + (m / 60);					m = 0;				}				if(h >= 24) {					h = h - 24;				}				var timeObj = {					'time': getDoubleDigit(h) + ":" + getDoubleDigit(m)				};				resList.push(timeObj);			}			return resList;		}		// 生成年份选择列表数据		function createYearList(year) {			year = parseInt(year) || GMTDate.getFullYear();			if(year) {				var yearList = {};				yearList.startYear = year;				yearList.endYear = yearList.startYear + 10;				yearList.y1 = [];				yearList.y2 = [];				yearList.y3 = [];				for(var i = 0; i < 4; i++) {					yearList.y1.push(year + i);					yearList.y2.push(year + i + 4);					if(yearList.y3.length <= 2) {						yearList.y3.push(year + i + 8);					}				}				return yearList;			}			return null;		}		// 输出时间		function outputDate() {			scope.ngModel = dateFormat(GMTToStrDate(GMTDate));		}		// 点击某天关闭弹窗的规则		var DATE_PICK_CLOSE = (format == DATE_RULES[2]);		// Pick Date		scope.pickDate = function(item, e) {			if(item.type == 2) {				GMTDate.setDate(item.date);				if(DATE_PICK_CLOSE) {					scope.date.showPicker = false;				}			} else if(item.type == 1) {				GMTDate.setDate(item.date);				GMTDate.setMonth(scope.date.month - 2);			} else if(item.type == 3) {				GMTDate.setDate(item.date);				GMTDate.setMonth(scope.date.month);			}			outputDate();			scope.date.dateList = getDateList(GMTDate); // 生成年月日数据		}		// Pick Time		scope.pickTime = function(time) {			GMTDate.setHours(time.slice(0, 2));			GMTDate.setMinutes(time.slice(3, 5));			outputDate();			getAllDate();		}		// Prev Year		scope.prevYear = function() {			var y = scope.date.year - 1;			if(y >= minYear) {				GMTDate.setFullYear(y);				scope.date.dateList = getDateList(GMTDate); // 生成年月日数据			}		}		// Next Year		scope.nextYear = function() {			var y = scope.date.year + 1;			if(y <= maxYear) {				GMTDate.setFullYear(y);				scope.date.dateList = getDateList(GMTDate); // 生成年月日数据			}		}		// Prev Year		scope.prevYearByMonth = function() {			var y = scope.date.year - 1;			if(y >= minYear) {				GMTDate.setFullYear(y);				getAllDate();			}		}		// Next Year		scope.nextYearByMonth = function() {			var y = scope.date.year + 1;			if(y <= maxYear) {				GMTDate.setFullYear(y);				getAllDate();			}		}		// Prev Month		scope.prevMonth = function() {			var m = scope.date.month - 2;			GMTDate.setMonth(m);			scope.date.dateList = getDateList(GMTDate); // 生成年月日数据		}		// Next Month		scope.nextMonth = function() {			var m = scope.date.month;			GMTDate.setMonth(m);			scope.date.dateList = getDateList(GMTDate); // 生成年月日数据		}		// 打开年份选择列表		scope.openYearPicker = function(year) {			scope.date.selector = 3;			scope.date.yearList = createYearList(year);		}		// Pick Year		scope.selectYear = function(year) {			GMTDate.setFullYear(year);			scope.date.selector = 2;			getAllDate();			outputDate();		}		scope.pickPrevYear = function() {			var year = scope.date.yearList.startYear - 11;			if(year >= minYear) {				scope.openYearPicker(year);			}		}		scope.pickNextYear = function() {			var year = scope.date.yearList.startYear + 11;			if(year <= maxYear) {				scope.openYearPicker(year);			}		}		// 打开月份选择列表		scope.openMonthPicker = function() {			scope.date.selector = 2;		}		// 点击某月关闭弹窗的规则		var MONTH_PICK_CLOSE = (format == DATE_RULES[3]);		// Select Month		scope.selectMonth = function(m) {			GMTDate.setMonth(m - 1);			scope.date.dateList = getDateList(GMTDate); // 生成年月日数据			scope.date.selector = 1;			outputDate();			if(MONTH_PICK_CLOSE) {				scope.date.showPicker = false;			}		}		// 选择至今		scope.hitherto = function() {			scope.ngModel = '至今';			scope.date.showPicker = false;		}		// Picker open		scope.openPicker = function() {			domBootstrap(format); // 打开日期面板更新样式			angular.element(".wui-date .wui-date-picker").hide();			angular.element(".wui-date-" + scope.id + " .wui-date-picker").show();			GMTDateInit(scope.ngModel);			scope.date.dateList = getDateList(GMTDate); // 生成年月日数据			scope.date.showPicker = true;		}		// 确定按钮		scope.confirm = function() {			outputDate();			scope.date.showPicker = false;		}		// 此刻按钮		scope.moment = function() {			GMTDate = new Date();			outputDate();			scope.date.showPicker = false;		}		// 格式化input的date		scope.checkDateFormat = function() {			scope.ngModel = dateFormat(scope.ngModel);		}		// date init		scope.dateInit = function() {			domBootstrap(format);			GMTDateInit(scope.ngModel);			scope.date.dateList = getDateList(GMTDate); // 生成年月日数据			scope.date.timeList = createTimeList();		}		scope.$watch('date.showPicker', function() {			if(scope.date.showPicker) {				scope.dateInit();			}		});		// Close by click blank		element.on('click', function(e) {			//阻止底层冒泡			e.stopPropagation();		});		angular.element('body').on('click', ':not(.wui-date)', function() {			angular.element(element).find('.wui-date-picker').hide();		});	}	function fieldTemplate(scope, element, attr) {		return(			'<div class="wui-date wui-date" ng-app="wui.date">' +			'<div class="wui-date-editor" ng-click="openPicker()">' +			'<input class="wui-input wui-input-block wui-date-input" type="text" placeholder="{{placeholder}}" ng-model="ngModel" autocomplete="off" ng-blur=checkDateFormat()>' +			'<i class="iconfont icon1"></i>' +			'</div>' +			'<br/>' +			'<div class="wui-date-picker" ng-show="date.showPicker">' +			'<div class="wui-date-picker_body">' +			'<div class="wui-date-picker_panel" ng-show="date.selector == 1">' +			'<div class="wui-date-panel_header">' +			'<i class="iconfont" ng-click="prevYear()"></i>' +			'<i class="iconfont" ng-click="prevMonth()"></i>' +			'<span class="title">' +			'<span class="txt" ng-click="openYearPicker()"><span>{{date.year}}</span> 年 </span>' +			'<span class="txt" ng-click="openMonthPicker()"><span>{{date.month}}</span> 月</span>' +			'</span>' +			'<i class="iconfont" ng-click="nextMonth()"></i>' +			'<i class="iconfont" ng-click="nextYear()"></i>' +			'</div>' +			'<div class="wui-date-picker_content">' +			'<table class="wui-data-table">' +			'<tr>' +			'<th>日</th>' +			'<th>一</th>' +			'<th>二</th>' +			'<th>三</th>' +			'<th>四</th>' +			'<th>五</th>' +			'<th>六</th>' +			'</tr>' +			'<tr ng-repeat="item in date.dateList track by $index">' +			'<td ng-repeat="subItem in date.dateList[$index]"><div ng-class="{'prev-date':subItem.type==1,'date':subItem.type==2,'next-date':subItem.type==3}"><span ng-click="pickDate(subItem,$event)" ng-class="{'today':subItem.today,'current':subItem.current}">{{subItem.date}}</span></div></td>' +			'</tr>' +			'</table>' +			'</div>' +			'</div>' +			'<div class="wui-date-picker_panel month_panel" ng-show="date.selector == 2">' +			'<div class="wui-date-panel_header">' +			'<i class="iconfont" ng-click="prevYearByMonth()"></i>' +			'<span class="title">' +			'<span class="txt" ng-click="openYearPicker()"><span>{{date.year}}</span> 年</span>' +			'</span>' +			'<i class="iconfont" ng-click="nextYearByMonth()"></i>' +			'</div>	' +			'<div class="wui-date-picker_content">' +			'<table class="wui-data-table">' +			'<tr>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(1)">一月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(2)">二月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(3)">三月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(4)">四月</a>' +			'</td>' +			'</tr>' +			'<tr>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(5)">五月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(6)">六月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(7)">七月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(8)">八月</a>' +			'</td>' +			'</tr>' +			'<tr>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(9)">九月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(10)">十月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(11)">十一月</a>' +			'</td>' +			'<td>' +			'<a class="cell" ng-click="selectMonth(12)">十二月</a>' +			'</td>' +			'</tr>' +			'</table>' +			'</div>	' +			'</div>' +			'<div class="wui-date-picker_panel year_panel" ng-show="date.selector == 3 ">' +			'<div class="wui-date-panel_header">' +			'<i class="iconfont" ng-click="pickPrevYear()"></i>' +			'<span class="title">' +			'<span class="txt"><span>{{date.yearList.startYear}}</span> 年 - <span>{{date.yearList.endYear}}</span> 年</span>' +			'</span>' +			'<i class="iconfont" ng-click="pickNextYear()"></i>' +			'</div>' +			'<div class="wui-date-picker_content">' +			'<table class="wui-data-table">' +			'<tr>' +			'<td ng-repeat="item in date.yearList.y1 track by $index">' +			'<a class="cell" ng-click="selectYear(item)">{{item}}</a>' +			'</td>' +			'</tr>' +			'<tr>' +			'<td ng-repeat="item in date.yearList.y2 track by $index">' +			'<a class="cell" ng-click="selectYear(item)">{{item}}</a>' +			'</td>' +			'</tr>' +			'<tr>' +			'<td ng-repeat="item in date.yearList.y3 track by $index">' +			'<a class="cell" ng-click="selectYear(item)">{{item}}</a>' +			'</td>' +			'</tr>' +			'</table>' +			'</div>' +			'</div>' +			'<div class="wui-date-picker_aside" ng-show="date.showTimePicker">' +			'<div class="wui-date-aside_header">' +			'<div class="wui-select wui-select-block time-select" id="time">' +			'<div class="wui-select-selection time-selection">' +			'<input type="hidden" name="" value="" >' +			'<span class="wui-select-icon iconfont time-icon"></span>' +			'<span class="wui-select-placeholder placeholder">{{date.hours}}:{{date.minutes}}</span>' +			'<span class="wui-select-selected-value value"></span>' +			'</div>' +			'<div class="wui-select-menu time-menu" ng-show="date.showTimeList">' +			'<ul>' +			'<li class="wui-select-item time-menu-item" ng-repeat="item in date.timeList" ng-click="pickTime(item.time)">{{item.time}}</li>' +			'</ul>' +			'</div>' +			'</div>' +			'</div>' +			'</div>' +			'</div>' +			'<div class="wui-date-picker_footer" ng-show="date.showBtn">' +			'<button type="button" class="wui-btn wui-btn-white wui-btn-xsmall" ng-click="moment()" ng-if="date.btns.now">{{date.btns.now}}</button>' +			'<button type="button" class="wui-btn wui-btn-primary wui-btn-xsmall" ng-click="confirm()" ng-if="date.btns.ok">{{date.btns.ok}}</button>' +			'<button type="button" class="wui-btn wui-btn-white wui-btn-xsmall" ng-click="hitherto()" ng-if="date.btns.hitherto">至今</button>' +			'</div>' +			'</div>' +			'</div>'		);	}});
 |