[easyui] datebox源码阅读. 批注

jquery.datebox.js

文件.

(function($){
	/**
	 * create date box
	 */
	function createBox(target){

		var state = $.data(target, 'datebox');
		var opts = state.options;
		
		//在'onShowPanel'触发时会执行一系列的函数.
		$(target).addClass('datebox-f').combo($.extend({}, opts, {
			onShowPanel:function(){
				bindEvents(this);
				setButtons(this);
				setCalendar(this);
				setValue(this, $(this).datebox('getText'), true);
				opts.onShowPanel.call(this);
			}
		}));
		
		/**
		 * if the calendar isn't created, create it.
		 * 创建日历
		 */
		if (!state.calendar){
			
			var panel = $(target).combo('panel').css('overflow','hidden');
			
			//什么时候destroy呢?
			panel.panel('options').onBeforeDestroy = function(){
				var c = $(this).find('.calendar-shared');
				if (c.length){
					// pholder -> ? -> calendar-pholder 是easyui在下文自己定义的.
					c.insertBefore(c[0].pholder);
				}
			};
			
			//承载日历的dom对象.
			var cc = $('<div class="datebox-calendar-inner"></div>').prependTo(panel);
			
			if (opts.sharedCalendar){
				var c = $(opts.sharedCalendar);
				if (!c[0].pholder){
					c[0].pholder = $('<div class="calendar-pholder" style="display:none"></div>').insertAfter(c);
				}
				c.addClass('calendar-shared').appendTo(cc);
				if (!c.hasClass('calendar')){
					c.calendar();
				}
				state.calendar = c;
			} else {
				state.calendar = $('<div></div>').appendTo(cc).calendar();
			}

			//点击日历后,隐藏日历面板.
			$.extend(state.calendar.calendar('options'), {
				fit:true,
				border:false,
				onSelect:function(date){
					var target = this.target;
					var opts = $(target).datebox('options');
					setValue(target, opts.formatter.call(target, date));
					$(target).combo('hidePanel');
					opts.onSelect.call(target, date);
				}
			});
		}

		$(target).combo('textbox').parent().addClass('datebox');
		$(target).datebox('initValue', opts.value);
		
		//为按钮绑定点击事件.
		function bindEvents(target){
			var opts = $(target).datebox('options');
			var panel = $(target).combo('panel');
			panel.unbind('.datebox').bind('click.datebox', function(e){
				//'datebox-button-a' -> 就是下面setButtons方法中的按钮的css样式.
				if ($(e.target).hasClass('datebox-button-a')){
					var index = parseInt($(e.target).attr('datebox-button-index'));
					opts.buttons[index].handler.call(e.target, target);
				}
			});
		}

		//设置'Today','Close'两个按钮. -> 新版本应该是允许用户增加按钮的.
		function setButtons(target){
			var panel = $(target).combo('panel');
			if (panel.children('div.datebox-button').length){return}
			var button = $('<div class="datebox-button">'
							+'<table cellspacing="0" cellpadding="0" style="width:100%">'
							+'<tr></tr></table></div>').appendTo(panel);
			var tr = button.find('tr');
			for(var i=0; i<opts.buttons.length; i++){
				var td = $('<td></td>').appendTo(tr);
				var btn = opts.buttons[i];
				var t = $('<a class="datebox-button-a" href="javascript:void(0)"></a>')
						.html($.isFunction(btn.text) ? btn.text(target) : btn.text).appendTo(td);
				t.attr('datebox-button-index', i);
			}
			//为按钮父元素td设置百分比.->想象"'Today','Close'"父td各占50%
			tr.find('td').css('width', (100/opts.buttons.length)+'%');
		}
		
		//
		function setCalendar(target){
			var panel = $(target).combo('panel');
			var cc = panel.children('div.datebox-calendar-inner');
			
			//_outerWidth 在jquery.parser.js中有定义.
			panel.children()._outerWidth(panel.width());
			state.calendar.appendTo(cc);
			state.calendar[0].target = target;
			if (opts.panelHeight != 'auto'){
				var height = panel.height();
				panel.children().not(cc).each(function(){
					height -= $(this).outerHeight();
				});
				cc._outerHeight(height);
			}
			state.calendar.calendar('resize');
		}
	}
	
	/**
	 * called when user inputs some value in text box
	 * 当给文本框赋值时->触发此动作->譬如:粘贴"2015-01-07"
	 */
	function doQuery(target, q){
		setValue(target, q, true);
	}
	
	/**
	 * called when user press enter key
	 */
	function doEnter(target){
		var state = $.data(target, 'datebox');
		var opts = state.options;
		var current = state.calendar.calendar('options').current;
		if (current){
			setValue(target, opts.formatter.call(target, current));
			$(target).combo('hidePanel');
		}
	}
	
	/**
	 * 给文本框赋值.并且切换日历的显示->calendar.calendar('moveTo',...)
	 * remainText=undefined时 -> setText 并且 setValue
	 */
	function setValue(target, value, remainText){
		var state = $.data(target, 'datebox');
		var opts = state.options;
		var calendar = state.calendar;
		calendar.calendar('moveTo', opts.parser.call(target, value));
		if (remainText){
			$(target).combo('setValue', value);
		} else {
			if (value){
				value = opts.formatter.call(target, calendar.calendar('options').current);
			}
			$(target).combo('setText', value).combo('setValue', value);
		}
	}
	
	/**
	 * 构造方法.
	 * 现象: 如果在下面的function第一行输出打印,然后到浏览器执行,会发现打印将输出多次.
	 * 例如:
	 * 第一次打印: options, param 都是undefined
	 * 第二次打印: options: initValue, param: 
	 * 第三次打印: options: options, param: undefined
	 */
	$.fn.datebox = function(options, param){
		
		if (typeof options == 'string'){
			var method = $.fn.datebox.methods[options];
			if (method){
				//当 method 是"datebox"定义的方法是,直接调用.
				return method(this, param);
			} else {
				//否则,调用combo对应的方法.
				return this.combo(options, param);
			}
		}
		
		options = options || {};
		
		return this.each(function(){
			
			var state = $.data(this, 'datebox');
			
			if (state){
				$.extend(state.options, options);
			} else {
				//在元素上存放(set)数据. 除了'cloneFrom'方法外,其他地方都是获取(get).
				$.data(this, 'datebox', {
					// 拷贝 $.fn.datebox.defaults 数据.
					options: $.extend({}, $.fn.datebox.defaults, $.fn.datebox.parseOptions(this), options)
				});
			}
			//
			createBox(this);
		});
	};
	
	$.fn.datebox.methods = {
		//测试发现,'options'方法在内部调用非常频繁.
		options: function(jq){
			var copts = jq.combo('options');
			return $.extend($.data(jq[0], 'datebox').options, {
				width: copts.width,
				height: copts.height,
				originalValue: copts.originalValue,
				disabled: copts.disabled,
				readonly: copts.readonly
			});
		},
		//cloneFrom 是combo中定义的方法.测试发现,内部几乎没有被使用.这个方法应该是暴露给用户使用的.
		cloneFrom: function(jq, from){
			return jq.each(function(){
				$(this).combo('cloneFrom', from);
				$.data(this, 'datebox', {
					options: $.extend(true, {}, $(from).datebox('options')),
					calendar: $(from).datebox('calendar')
				});
				$(this).addClass('datebox-f');
			});
		},
		//暴露给用户使用的API.获得calendar对象.
		calendar: function(jq){	// get the calendar object
			return $.data(jq[0], 'datebox').calendar;
		},
		initValue: function(jq, value){
			return jq.each(function(){
				var opts = $(this).datebox('options');
				var value = opts.value;
				if (value){
					//下文有定义'formatter','parser'方法.
					value = opts.formatter.call(this, opts.parser.call(this, value));
				}
				//最终还是会调用'combo'的方法, 并且还调用'setText'方法
				$(this).combo('initValue', value).combo('setText', value);
			});
		},
		setValue: function(jq, value){
			return jq.each(function(){
				//调用本模块定义的'setValue'函数.
				setValue(this, value);
			});
		},
		reset: function(jq){
			return jq.each(function(){
				var opts = $(this).datebox('options');
				// opts.originalValue -> 来自combo -> 为空字符串.
				$(this).datebox('setValue', opts.originalValue);
			});
		}
	};
	
	$.fn.datebox.parseOptions = function(target){
		return $.extend({}, $.fn.combo.parseOptions(target), $.parser.parseOptions(target, ['sharedCalendar']));
	};
	
	$.fn.datebox.defaults = $.extend({}, $.fn.combo.defaults, {
		panelWidth:180,
		panelHeight:'auto',
		sharedCalendar:null,
		
		keyHandler: {
			up:function(e){},
			down:function(e){},
			left: function(e){},
			right: function(e){},
			enter:function(e){doEnter(this)},
			query:function(q,e){doQuery(this, q)}
		},
		
		currentText:'Today',
		closeText:'Close',
		okText:'Ok',
		
		buttons:[{
			text: function(target){return $(target).datebox('options').currentText;},
			handler: function(target){
				var now = new Date();
				$(target).datebox('calendar').calendar({
					year:now.getFullYear(),
					month:now.getMonth()+1,
					current:new Date(now.getFullYear(), now.getMonth(), now.getDate())
				});
				doEnter(target);
			}
		},{
			text: function(target){return $(target).datebox('options').closeText;},
			handler: function(target){
				$(this).closest('div.combo-panel').panel('close');
			}
		}],
		
		formatter:function(date){
			var y = date.getFullYear();
			var m = date.getMonth()+1;
			var d = date.getDate();
			return (m<10?('0'+m):m)+'/'+(d<10?('0'+d):d)+'/'+y;
		},
		parser:function(s){
			if (!s) return new Date();
			var ss = s.split('/');
			var m = parseInt(ss[0],10);
			var d = parseInt(ss[1],10);
			var y = parseInt(ss[2],10);
			if (!isNaN(y) && !isNaN(m) && !isNaN(d)){
				return new Date(y,m-1,d);
			} else {
				return new Date();
			}
		},
		
		onSelect:function(date){}
	});
})(jQuery);

  

 

转载于:https://www.cnblogs.com/juedui0769/p/5114431.html

jQuery EasyUI 1 4版本更新内容: Bug(修复) menu:修复在删除一个菜单项的时候该菜单无法正确自适应高度的问题; datagrid:修复在datagrid宽度太小的时候“fitColumns”方法无法正常工作的问题 Improvement(改进) EasyUI的所有组件已经支持非固定 百分比大小的尺寸设置; menu:添加“showItem” “hideItem”和“resize”方法; menu:基于窗体大小自动调整高度; menu:添加“duration”属性 该属性允许用户自定义隐藏菜单动画的持续时间 以毫秒为单位; validatebox:添加“onBeforeValidate”和“onValidate”事件; combo:从该版本开始combo组件扩展自textbox组件(textbox是1 4中新增的组件); combo:添加“panelMinWidth” “panelMaxWidth” “panelMinHeight”和“panelMaxHeight”属性; searchbox:从该版本开始searchbox组件扩展自textbox组件(textbox是1 4中新增的组件); tree:添加“getRoot”方法 用于返回通过“nodeEl”参数指定的节点的顶部父节点元素 注意:官网的英文API中该函数的说明有误 其说明是none 无参数 实际这里是需要参数的 ; tree:添加“queryParams”属性; datetimebox:添加“spinnerWidth”属性; panel:添加“doLayout”方法 用于控制面板内组件的大小; panel:添加“clear”方法 用于清除面板内的内容; datagrid:允许用户设置百分比宽度的列(该功能真是千呼万唤始出来啊 ); form:添加“ajax” “novalidate”和“queryParams”属性; linkbutton:添加“resize”方法 New Plugin(新组件) textbox:该组件是一个增强的输入字段 它可以让用户非常简单的构建一个表单; datetimespinner:该组件是一个日期和时间的微调组件 它允许我们选择一个特定的日期或时间; filebox:filebox 该组件表单元素中用于上传文件的文件框工具组件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值