My97DatePicker控件的大名很多人都听过了,作为一款国产的日期时间控件,它的功能和性能各方面都是数一数二的。相对而言,jQuery Easyui的datebox和datetimebox的功能就有点捉襟见肘了。也因为如此,很多使用了Easyui框架的童鞋依旧会选择my97作为日期控件使用。
通常情况下,我们只要导入My97DatePicker的核心javascript文件就能在Easyui框架中使用my97了,而且用法也比较简单,比如以下代码就能轻松使用my97以及Easyui的validatebox组件:
- <input id="d411" class="Wdate easyui-validatebox" type="text" onfocus="WdatePicker({skin:'whyGreen',minDate:'2006-09-10',maxDate:'2008-12-20'})"/>
既然直接使用也很简单,为何还要集成?本文就针对直接使用my97的弊端以及如何集成my97到Easyui框架中做较为全面的描述。
直接使用my97的缺点:
my97编码方式与Easyui存在点差异
在Easyui的世界中,我们习惯了使用class来注册组件,或者是用jQuery来注册组件,而my97无法通过class注册。这一点很多人可能觉得吹毛求疵,不过对于我个人而已,同一项目中存在不同的组件编码风格总归让人觉得不舒服。
my97的DOM结构样式跟Easyui存在差异
这一点是毋庸置疑的了,my97的结构简单,只有一个文本框,其日期图标实际上只是文本框的背景图片。而easyui的对应组件却是一个文本框和一个span元素组成的。当然了,要解决这个问题也很简单,my97自身也是可以灵活设置触发点的,DOM结构可以模拟得跟easyui对应组件一样,然后再加以CSS就可基本解决问题。
my97样式与validatabox组件样式冲突
my97与validatebox样式的冲突的根本原因依然是DOM结构的差异,也可以通过问题二的同样方式去解决,而这样做的代价除了写css文件外,还要每个组件都要自己手动写较复杂的DOM,比如my97用以下DOM模拟datebox:
- <span class="my97-wrap">
- <input id="my97_2" type="text" class="easyui-validatebox my97-text" data-options="required:true" onclick="WdatePicker();">
- <span>
- <span class="my97-arrow" onclick="WdatePicker({el:'my97_2'});"></span>
- </span>
- </span>
我们来看一下我最终模拟的效果:
http://www.easyui.info/easyui/demo/my97/062.html
实现my97与EasyUI的集成:
集成二者其实也就是为了解决直接使用my97的不足之处,而我们做集成的思路也就是前面用my97模拟databox的思路,只不过我们把这种零碎的操场封装成为EasyUI的插件更为方便罢了,直接上代码:
jquery.my97.js文件:
- /**
- * my97 - jQuery EasyUI
- * Licensed under the GPL:
- * http://www.gnu.org/licenses/gpl.txt
- * Copyright 2013 小雪转中雪 [ caoguanghuicgh@163.com ] [http://www.easyui.info]
- */
- (function ($) {
- //如果没有my97控件,则添加之。
- (function () {
- var hasmy97 = false;
- var plugins = $.parser.plugins;
- for (var i = plugins.length - 1; i > -1; i--) {
- if (plugins[i] === "my97") {
- hasmy97 = true;
- break;
- }
- }
- if (hasmy97 == false) {
- $.parser.plugins[$.parser.plugins.length] = "my97";
- }
- })();
- function init(target) {
- $(target).addClass("my97-text")
- var wrap = $("<span class=\"my97-wrap\"></span>").insertBefore(target);
- wrap[0].appendChild(target);
- var arrow = $("<span class=\"my97-arrow\"></span>").insertAfter(target);
- return wrap;
- };
- /**
- * 绑定事件用以触发原生的my97控件
- * @param {[type]} target [description]
- * @return {[type]} [description]
- */
- function bindEvents(target) {
- var data = $.data(target, "my97");
- var opts = data.options;
- var wrap = $.data(target, "my97").my97;
- var input = wrap.find(".my97-text");
- var arrow = wrap.find(".my97-arrow");
- input.unbind(".my97");
- arrow.unbind(".my97");
- if (!opts.disabled) {
- input.bind("click.my97", function (e) {
- //TODO 触发my97
- WdatePicker(opts);
- });
- arrow.bind("click.my97",function () {
- //TODO 触发my97
- WdatePicker($.extend({}, opts, {el:opts.id}));
- }).bind('mouseenter.my97',
- function (e) {
- $(this).addClass('my97-arrow-hover');
- }).bind('mouseout.my97',
- function (e) {
- $(this).removeClass('my97-arrow-hover');
- }
- );
- }
- };
- /**
- * 销毁组件
- * @param {document object} target 承载组件的输入框
- * @return {[type]} [description]
- */
- function destroy(target) {
- var input = $.data(target, "my97").my97.find("input.my97-text");
- input.validatebox("destroy");
- $.data(target, "my97").my97.remove();
- $(target).remove();
- };
- function validate(target, doit) {
- var opts = $.data(target, "my97").options;
- var input = $.data(target, "my97").my97.find("input.my97-text");
- input.validatebox(opts);
- if (doit) {
- input.validatebox("validate");
- }
- };
- function initValue(target) {
- var opts = $.data(target, "my97").options;
- var input = $.data(target, "my97").my97.find("input.my97-text");
- input.val(opts.value);
- }
- function setDisabled(target, disabled) {
- var ops = $.data(target, "my97").options;
- var my97 = $.data(target, "my97").my97;
- var arrow = my97.find('.my97-arrow');
- if (disabled) {
- ops.disabled = true;
- $(target).attr("disabled", true);
- arrow.unbind('click.my97');
- arrow.unbind('hover.my97');
- } else {
- ops.disabled = false;
- $(target).removeAttr("disabled");
- arrow.unbind('click.my97').bind('click.my97', function () {
- WdatePicker(opts);
- });
- arrow.unbind('mouseenter.my97').unbind('mouseout').bind('mouseenter.my97',
- function (e) {
- this.addClass('my97-arrow-hover');
- }).bind('mouseenter.my97',
- function (e) {
- this.removeClass('my97-arrow-hover');
- }
- );
- }
- };
- /**
- * 设置输入框宽度,主要这里是指box模型的width
- * @param {document object} target 承载控件的输入框
- * @param {number} width 宽度
- */
- function setWidth(target, width) {
- var opts = $.data(target, "my97").options;
- opts.width = width;
- $(target).width(width);
- }
- function setValue(target, value) {
- $(target).val(value);
- }
- function getValue(target) {
- return $(target).val();
- }
- /**
- * 因为my97图片触发方式,必要id,所以在没有设置id的情况下,设置一个唯一ID
- * @param {[type]} target [description]
- */
- function setId(target) {
- var pre = "_easyui_my97_id_";
- var opts = $.data(target, "my97").options;
- opts.id = pre + $.fn.my97.defaults.count;
- $(target).attr("id", opts.id);
- $.fn.my97.defaults.count++;
- }
- $.fn.my97 = function (options, param) {
- if (typeof options == 'string') {
- return $.fn.my97.methods[options](this, param);
- }
- options = options || {};
- return this.each(function () {
- var state = $.data(this, 'my97');
- var opts;
- if (state) {
- opts = $.extend(state.options, options);
- } else {
- opts = $.extend({}, $.fn.my97.defaults, $.fn.my97.parseOptions(this), options);
- var wrap = init(this);
- state = $.data(this, 'my97', {
- options:opts,
- my97:wrap
- });
- }
- if (opts.id == undefined) {
- setId(this);
- }
- setWidth(this, state.options.width);
- setDisabled(this, state.options.disabled);
- bindEvents(this);
- validate(this);
- initValue(this);
- });
- };
- $.fn.my97.methods = {
- options:function (jq) {
- return $.data(jq[0], 'my97').options;
- },
- destroy:function (jq, param) {
- return jq.each(function () {
- destroy(this, param);
- });
- },
- setWidth:function (jq, param) {
- return jq.each(function () {
- setWidth(this, param);
- });
- },
- setValue:function (jq, param) {
- setValue(jq[0], param);
- },
- getValue:function (jq, param) {
- return getValue(jq[0]);
- }
- };
- /**
- * 属性转换器,继承validatebox组件属性
- * @param {document object} target 承载my97的输入框
- * @return {object} 属性列表
- */
- $.fn.my97.parseOptions = function (target) {
- var t = $(target);
- return $.extend({}, $.fn.validatebox.parseOptions(target), $.parser.parseOptions(target, ["width", "height", "weekMethod", "lang", "skin", "dateFmt", "realDateFmt", 'realTimeFmt', 'realFullFmt', 'minDate', 'maxDate', 'startDate',
- {
- doubleCalendar:"boolean",
- enableKeyboard:"boolean",
- enableInputMask:"boolean",
- isShowWeek:"boolean",
- highLineWeekDay:"boolean",
- isShowClear:"boolean",
- isShowOthers:"boolean",
- readOnly:"boolean",
- qsEnabled:"boolean",
- autoShowQS:"boolean",
- opposite:"boolean"
- }, {
- firstDayOfWeek:"number",
- errDealMode:"number"
- }]),
- {
- value:(t.val() || undefined),
- disabled:(t.attr("disabled") ? true : undefined),
- id:(t.attr("id") || undefined)
- });
- };
- $.fn.my97.defaults = {
- id:null,
- count:0,
- value:'',
- width:109,
- height:22,
- disabled:false,
- doubleCalendar:false,
- enableKeyboard:true,
- enableInputMask:true,
- weekMethod:'ISO8601',
- position:{},
- lang:'auto',
- skin:'default',
- dateFmt:'yyyy-MM-dd',
- realDateFmt:'yyyy-MM-dd',
- realTimeFmt:'HH:mm:ss',
- realFullFmt:'%Date %Time',
- minDate:'1900-01-01 00:00:00',
- maxDate:'2099-12-31 23:59:59',
- startDate:'',
- firstDayOfWeek:0,
- isShowWeek:false,
- highLineWeekDay:true,
- isShowClear:true,
- isShowOthers:true,
- readOnly:false,
- errDealMode:0,
- qsEnabled:true,
- autoShowQS:false,
- opposite:false,
- quickSel:[],
- disabledDays:null,
- disabledDates:null,
- specialDates:null,
- specialDays:null,
- onpicking:function () {
- },
- onpicked:function () {
- },
- onclearing:function () {
- },
- oncleared:function () {
- }
- };
- })(jQuery);
注意:该文件放在themes下你要用到的皮肤下即可。
如何使用?
先引入javascript和css文件
javascript文件之间是有依赖关系的,先要引入EasyUi和my97的核心文件,然后再引入我扩展的名为"my97"的EasyUI组件的javascript文件,至于css文件,先后顺序则无影响,比如:
- <link rel="stylesheet" type="text/css" href="../../themes/default/easyui.css">
- <link rel="stylesheet" type="text/css" href="../../themes/default/my97.css">
- <link rel="stylesheet" type="text/css" href="../../themes/icon.css">
- <script type="text/javascript" src="../../jquery-1.8.0.min.js"></script>
- <script type="text/javascript" src="../../../third/My97DatePicker/WdatePicker.js"></script>
- <script type="text/javascript" src="../../jquery.easyui.min.js"></script>
- <script type="text/javascript" src="../../plugins/jquery.my97.js"></script>
像EasyUI的其它组件一样使用
到这里,你就可以跟使用EasyUI的datebox组件一样,用class或者jQuery注册my97组件了,例如使用class注册:
- <input type="text" class="easyui-my97" data-options="required:true,disabled:false,value:'2012-12-13',minDate:'2012-12-12',maxDate:'2012-12-25'">
又或者是使用jQuery注册:
- $('#dd').my97({});
使用场景:
暂未整理
效果演示:
http://www.easyui.info/easyui/demo/my97/061.html
接口文档:
暂未整理,属性基本与原生的my97属性一致,请查看my97官方的API文档
更新说明:
本篇文章写的扩展不适合1.4版本,适合1.4版本的扩展抽空会在此处补上!
管理员 世纪之光 : 2013年06月26日09:16:45 地下1层
管理员 世纪之光 : 2013年08月06日18:20:13 地下1层
管理员 世纪之光 : 2015年06月26日17:02:20 地下3层
管理员 世纪之光 : 2014年10月13日20:08:45 地下1层
管理员 世纪之光 : 2015年01月08日12:33:47 地下1层
管理员 世纪之光 : 2015年02月05日21:00:24 地下1层