• Ext4 中 日期和时间的控件


    一。一些废话

    近日来,有几个项目用到了EXTJS作为Web前端。也看到了一些童鞋苦苦在网上寻觅可以选择时间的控件,由于EXTJS版本差异较大,利用官方3.2的Demo制作了一个可以选择到秒的时间控件,该控件只能够用于ExtJs2.2以上的版本。经过测试ExtJs2.02版本不适用该控件,如果你还在使用2.02这个版本或者更老,请绕道。废话不说了,看代码:

    二。文件明细:

    Spinner.js

    SpinnerField.js

    DateTimeField.js

    三。各文件详解

    1.Spinner.js

    EXTJS个版本略有不同,最后的文件解压后请覆盖源文件。这里不做详细介绍。

    2.SpinnerField.js

    EXTJS个版本略有不同,最后的文件解压后请覆盖源文件。这里不做详细介绍。

    3.DateTimeField.js

    Js代码  收藏代码
    1. // 命名空间归属  
    2. Ext.ns('Ext.ux.form');  
    3. // 在该命名空间内,开辟一个名为TimePickerField的区域,我们可以当他是一个时间选择器  
    4. Ext.ux.form.TimePickerField = function(config){  
    5.     // 调用构造方法,也就是说定义了他的所属--this  
    6.     // this指的是什么呢?这里需要注意,首先这个东东属于这个类(对象),其次这个类(对象)在没有被调用之前或者实例之前是不会被构造的  
    7.     // 那么这个this实际上是指我们实例化后的datetimefield  
    8.     Ext.ux.form.TimePickerField.superclass.constructor.call(this, config);  
    9. }  
    10. // 给刚刚定义的TimePickerField加点菜吧。  
    11. // 首先它继承与Ext.form.Field,是一个扩展  
    12. Ext.extend(Ext.ux.form.TimePickerField, Ext.form.Field, {  
    13.     defaultAutoCreate: {  
    14.         tag: 'div'// 定义了一个DIV标签  
    15.     },  
    16.     cls: 'x-form-timepickerfield',// 它的样式  
    17.     hoursSpinner: null,// 属性:小时选择器  
    18.     minutesSpinner: null,// 属性:分钟选择器  
    19.     secondsSpinner: null,// 属性:秒选择器  
    20.     spinnerCfg: {  
    21.          40// 选择器的宽度定位40px  
    22.     },  
    23.       
    24.     // 约束:选择数值约束,如果小于最小值该如何,如果大于最大值该如何,这里的处理方式我详细说明一下(这个约束是触发的,我们输入的值或者我们点击上下箭头选择的值后都会进入该约束检查。)  
    25.     spinnerFixBoundries: function(value){  
    26.         // 这里有可能会造成不解,我解释一下。  
    27.         // 如果我们选择秒的时候,有一个向上的箭头和向下的箭头,如果我点击向上的箭头则秒数加1,点击向下的箭头则秒数减1。  
    28.         // 如果我选择了59秒后,点击向上的箭头,由于时间秒数约束,不可能出现60,那我们要怎么办?会如何?当然是,58,59,0,1这样的序列  
    29.         // 所以最大值定义为59,如果超过59那么秒数归零,就是这个逻辑。  
    30.         if (value < this.field.minValue) {  
    31.             value = this.field.maxValue;  
    32.         }  
    33.         if (value > this.field.maxValue) {  
    34.             value = this.field.minValue;  
    35.         }  
    36.         // 这里返回了一个带有精度的值  
    37.         return this.fixPrecision(value);  
    38.     },  
    39.     // 渲染,这个没什么可说的了所有的渲染都差不多是位置和范围之类的  
    40.     onRender: function(ct, position){  
    41.         Ext.ux.form.TimePickerField.superclass.onRender.call(this, ct, position);  
    42.         this.rendered = false;  
    43.         this.date = new Date();  
    44.         // 定义一个对象,他即将有三个属性,时分秒数值,往下看。  
    45.         var values = {};  
    46.         // 如果实例时已经被设定了初始值,那么将这些值赋予values这个对象中。  
    47.         // 再将这些值表示在时分秒选择器中  
    48.         if (this.value) {  
    49.             values = this._valueSplit(this.value);  
    50.             this.date.setHours(values.h);  
    51.             this.date.setMinutes(values.m);  
    52.             this.date.setSeconds(values.s);  
    53.             delete this.value;  
    54.         }  
    55.         // 如果实例时没被设定了初始值,简单了,时分秒选择器的初始值就不用改变了,只要values得到这些值备用即可  
    56.         else {  
    57.             values = {  
    58.                 h: this.date.getHours(),  
    59.                 m: this.date.getMinutes(),  
    60.                 s: this.date.getSeconds()  
    61.             };  
    62.         }  
    63.         // 定义一个外围包裹,就是想把时分秒这三个选择器给包起来成为一组,下面会实例这三个选择器的,往下看。  
    64.         var spinnerWrap = Ext.DomHelper.append(this.el, {  
    65.             tag: 'div'  
    66.         });  
    67.         var cfg = Ext.apply({}, this.spinnerCfg, {  
    68.             renderTo: spinnerWrap,  
    69.             readOnly: this.readOnly,  
    70.             disabled: this.disabled,  
    71.             listeners: {  
    72.                 spin: {  
    73.                     fn: this.onSpinnerChange,  
    74.                     scope: this  
    75.                 },  
    76.                 valid: {  
    77.                     fn: this.onSpinnerChange,  
    78.                     scope: this  
    79.                 },  
    80.                 afterrender: {  
    81.                     fn: function(spinner){  
    82.                         spinner.wrap.applyStyles('float: left');  
    83.                     },  
    84.                     single: true  
    85.                 }  
    86.             }  
    87.         });  
    88.         // 接下来实例(Ext.ux.form.SpinnerField)了几个选择器,时分秒。  
    89.         this.hoursSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, {  
    90.             minValue: 0,  
    91.             maxValue: 23,  
    92.             cls: 'first',  
    93.             value: values.h  
    94.         }));  
    95.         this.minutesSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, {  
    96.             minValue: 0,  
    97.             maxValue: 59,  
    98.             value: values.m  
    99.         }));  
    100.         this.secondsSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, {  
    101.             minValue: 0,  
    102.             maxValue: 59,  
    103.             value: values.s  
    104.         }));  
    105.         Ext.DomHelper.append(spinnerWrap, {  
    106.             tag: 'div',  
    107.             cls: 'x-form-clear-left'  
    108.         });  
    109.         // 渲染完毕释放出去  
    110.         this.rendered = true;  
    111.     },  
    112.     // 如果实例时已经被设定了初始值,那么调用这个方法,将这些值赋予values这个对象中。  
    113.     _valueSplit: function(v){  
    114.         var split = v.split(':');  
    115.         return {  
    116.             h: split.length > 0 ? split[0] : 0,  
    117.             m: split.length > 1 ? split[1] : 0,  
    118.             s: split.length > 2 ? split[2] : 0  
    119.         };  
    120.     },  
    121.     // 注意了,这里加了一个动作的监听,也可以说是自己弄了一个自定义监听  
    122.     onSpinnerChange: function(){  
    123.         if (!this.rendered) {  
    124.             return;  
    125.         }  
    126.         // 这里注册了这个监听类别,指明了监听的对象  
    127.         this.fireEvent('change', this, this.getRawValue());  
    128.     },  
    129.     // 禁用  
    130.     disable: function(){  
    131.         Ext.ux.form.TimePickerField.superclass.disable.call(this);  
    132.         this.hoursSpinner.disable();  
    133.         this.minutesSpinner.disable();  
    134.         this.secondsSpinner.disable();  
    135.     },  
    136.     // 解用  
    137.     enable: function(){  
    138.         Ext.ux.form.TimePickerField.superclass.enable.call(this);  
    139.         this.hoursSpinner.enable();  
    140.         this.minutesSpinner.enable();  
    141.         this.secondsSpinner.enable();  
    142.     },  
    143.     // 只读  
    144.     setReadOnly: function(r){  
    145.         Ext.ux.form.TimePickerField.superclass.setReadOnly.call(this, r);  
    146.         this.hoursSpinner.setReadOnly(r);  
    147.         this.minutesSpinner.setReadOnly(r);  
    148.         this.secondsSpinner.setReadOnly(r);  
    149.     },  
    150.     // 清除所有的无效验证  
    151.     clearInvalid: function(){  
    152.         Ext.ux.form.TimePickerField.superclass.clearInvalid.call(this);  
    153.         this.hoursSpinner.clearInvalid();  
    154.         this.minutesSpinner.clearInvalid();  
    155.         this.secondsSpinner.clearInvalid();  
    156.     },  
    157.     // 拿到那个值,可以认为是vlaues对象  
    158.     getRawValue: function(){  
    159.         if (!this.hoursSpinner) {  
    160.             this.date = new Date();  
    161.             return {  
    162.                 h: this.date.getHours(),  
    163.                 m: this.date.getMinutes(),  
    164.                 s: this.date.getSeconds()  
    165.             };  
    166.         }  
    167.         else {  
    168.             return {  
    169.                 h: this.hoursSpinner.getValue(),  
    170.                 m: this.minutesSpinner.getValue(),  
    171.                 s: this.secondsSpinner.getValue()  
    172.             };  
    173.         }  
    174.     },  
    175.     // 赋值  
    176.     setRawValue: function(v){  
    177.         this.hoursSpinner.setValue(v.h);  
    178.         this.minutesSpinner.setValue(v.m);  
    179.         this.secondsSpinner.setValue(v.s);  
    180.     },  
    181.     // 有效验证  
    182.     isValid: function(preventMark){  
    183.         return this.hoursSpinner.isValid(preventMark) &&  
    184.         this.minutesSpinner.isValid(preventMark) &&  
    185.         this.secondsSpinner.isValid(preventMark);  
    186.     },  
    187.     // 验证  
    188.     validate: function(){  
    189.         return this.hoursSpinner.validate() &&  
    190.         this.minutesSpinner.validate() &&  
    191.         this.secondsSpinner.validate();  
    192.     },  
    193.     // 这里可以自己修改想要的格式,这个值将作为返回值到调用该类的元控件中也就是DateTimeField的实例  
    194.     getValue: function(){  
    195.         var v = this.getRawValue();  
    196.         return String.leftPad(v.h, 2, '0') + ':' +  
    197.         String.leftPad(v.m, 2, '0') +  
    198.         ':' +  
    199.         String.leftPad(v.s, 2, '0');  
    200.     },  
    201.     setValue: function(value){  
    202.         if (!this.rendered) {  
    203.             this.value = value;  
    204.             return;  
    205.         }  
    206.         value = this._valueSplit(value);  
    207.         this.setRawValue(value);  
    208.         this.validate();  
    209.     }  
    210. });  
    211.   
    212. // 下面就没什么好说的了,就是将上面自定义的类(对象),成为一个总选择器一部分。  
    213. Ext.form.TimePickerField = Ext.ux.form.TimePickerField;  
    214. Ext.reg('timepickerfield', Ext.form.TimePickerField);  
    215. Ext.ns('Ext.ux.form');  
    216. Ext.DateTimePicker = Ext.extend(Ext.DatePicker, {  
    217.     timeFormat: 'g:i:s A',  
    218.     timeLabel: '时间',  
    219.     timeWidth: 100,  
    220.     initComponent: function(){  
    221.         Ext.DateTimePicker.superclass.initComponent.call(this);  
    222.         this.id = Ext.id();  
    223.     },  
    224.     onRender: function(container, position){  
    225.         Ext.DateTimePicker.superclass.onRender.apply(this, arguments);  
    226.         var table = Ext.get(Ext.DomQuery.selectNode('table tbody', container.dom));  
    227.         var tfEl = Ext.DomHelper.insertBefore(table.last(), {  
    228.             tag: 'tr',  
    229.             children: [{  
    230.                 tag: 'td',  
    231.                 cls: 'x-date-bottom',  
    232.                 html: this.timeLabel,  
    233.                 style: '30;'  
    234.             }, {  
    235.                 tag: 'td',  
    236.                 cls: 'x-date-bottom ux-timefield',  
    237.                 colspan: '2'  
    238.             }]  
    239.         }, true);  
    240.         this.tf.render(table.child('td.ux-timefield'));  
    241.         var p = this.getEl().parent('div.x-layer');  
    242.         if (p) {  
    243.             p.setStyle("height", p.getHeight() + 31);  
    244.         }  
    245.     },  
    246.     setValue: function(value){  
    247.         var old = this.value;  
    248.         if (!this.tf) {  
    249.             this.tf = new Ext.ux.form.TimePickerField();  
    250.             this.tf.ownerCt = this;  
    251.         }  
    252.         this.value = this.getDateTime(value);  
    253.     },  
    254.     getDateTime: function(value){  
    255.         if (this.tf) {  
    256.             var dt = new Date();  
    257.             var timeval = this.tf.getValue();  
    258.             value = Date.parseDate(value.format(this.dateFormat) + ' ' + this.tf.getValue(), this.format);  
    259.         }  
    260.         return value;  
    261.     },  
    262.     selectToday: function(){  
    263.         if (this.todayBtn && !this.todayBtn.disabled) {  
    264.             this.value = this.getDateTime(new Date());  
    265.             this.fireEvent("select", this, this.value);  
    266.         }  
    267.     }  
    268. });  
    269. Ext.reg('datetimepickerfield', Ext.DateTimePicker);  
    270. if (parseInt(Ext.version.substr(0, 1), 10) > 2) {  
    271.     Ext.menu.DateTimeItem = Ext.DateTimePicker;  
    272.     Ext.override(Ext.menu.DateMenu, {  
    273.         initComponent: function(){  
    274.             this.on('beforeshow', this.onBeforeShow, this);  
    275.             if (this.strict = (Ext.isIE7 && Ext.isStrict)) {  
    276.                 this.on('show', this.onShow, this, {  
    277.                     single: true,  
    278.                     delay: 20  
    279.                 });  
    280.             }  
    281.             Ext.apply(this, {  
    282.                 plain: true,  
    283.                 showSeparator: false,  
    284.                 items: this.picker = new Ext.DatePicker(Ext.apply({  
    285.                     internalRender: this.strict || !Ext.isIE,  
    286.                     ctCls: 'x-menu-date-item'  
    287.                 }, this.initialConfig))  
    288.             });  
    289.             Ext.menu.DateMenu.superclass.initComponent.call(this);  
    290.             this.relayEvents(this.picker, ["select"]);  
    291.             this.on('select', this.menuHide, this);  
    292.             if (this.handler) {  
    293.                 this.on('select', this.handler, this.scope || this);  
    294.             }  
    295.         }  
    296.     });  
    297. }  
    298. else {  
    299.     Ext.menu.DateTimeItem = function(config){  
    300.         Ext.menu.DateTimeItem.superclass.constructor.call(this, new Ext.DateTimePicker(config), config);  
    301.         this.picker = this.component;  
    302.         this.addEvents('select');  
    303.           
    304.         this.picker.on("render", function(picker){  
    305.             picker.getEl().swallowEvent("click");  
    306.             picker.container.addClass("x-menu-date-item");  
    307.         });  
    308.           
    309.         this.picker.on("select", this.onSelect, this);  
    310.     };  
    311.       
    312.     Ext.extend(Ext.menu.DateTimeItem, Ext.menu.DateMenu, {  
    313.         onSelect: function(picker, date){  
    314.             this.fireEvent("select", this, date, picker);  
    315.             Ext.menu.DateTimeItem.superclass.handleClick.call(this);  
    316.         }  
    317.     });  
    318. }  
    319.   
    320. Ext.menu.DateTimeMenu = function(config){  
    321.     Ext.menu.DateTimeMenu.superclass.constructor.call(this, config);  
    322.     this.plain = true;  
    323.     var di = new Ext.menu.DateTimeItem(config);  
    324.     this.add(di);  
    325.     this.picker = di;  
    326.     this.relayEvents(di, ["select"]);  
    327.       
    328.     this.on('beforeshow', function(){  
    329.         if (this.picker) {  
    330.             this.picker.hideMonthPicker(true);  
    331.         }  
    332.     }, this);  
    333. };  
    334. Ext.extend(Ext.menu.DateTimeMenu, Ext.menu.Menu, {  
    335.     cls: 'x-date-menu',  
    336.     beforeDestroy: function(){  
    337.         this.picker.destroy();  
    338.     },  
    339.     hide: function(deep){  
    340.         if (this.picker.tf.innerList) {  
    341.             if ((Ext.EventObject.within(this.picker.tf.innerList)) || (Ext.get(Ext.EventObject.getTarget()) == this.picker.tf.innerList))   
    342.                 return false;  
    343.         }  
    344.         if (this.el && this.isVisible()) {  
    345.             this.fireEvent("beforehide", this);  
    346.             if (this.activeItem) {  
    347.                 this.activeItem.deactivate();  
    348.                 this.activeItem = null;  
    349.             }  
    350.             this.el.hide();  
    351.             this.hidden = true;  
    352.             this.fireEvent("hide", this);  
    353.         }  
    354.         if (deep === true && this.parentMenu) {  
    355.             this.parentMenu.hide(true);  
    356.         }  
    357.     }  
    358. });  
    359.   
    360. Ext.ux.form.DateTimeField = Ext.extend(Ext.form.DateField, {  
    361.     dateFormat: 'Y-m-d',  
    362.     timeFormat: 'H:i:s',  
    363.     defaultAutoCreate: {  
    364.         tag: "input",  
    365.         type: "text",  
    366.         size: "20",  
    367.         autocomplete: "off"  
    368.     },  
    369.     initComponent: function(){  
    370.         Ext.ux.form.DateTimeField.superclass.initComponent.call(this);  
    371.         this.format = this.dateFormat + ' ' + this.timeFormat;  
    372.         this.afterMethod('afterRender', function(){  
    373.             this.getEl().applyStyles('top:0');  
    374.         });  
    375.     },  
    376.     getValue: function(){  
    377.         return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || '';  
    378.     },  
    379.     onTriggerClick: function(){  
    380.         if (this.disabled) {  
    381.             return;  
    382.         }  
    383.         if (this.menu == null) {  
    384.             this.menu = new Ext.menu.DateTimeMenu();  
    385.         }  
    386.         Ext.apply(this.menu.picker, {  
    387.             minDate: this.minValue,  
    388.             maxDate: this.maxValue,  
    389.             disabledDatesRE: this.ddMatch,  
    390.             disabledDatesText: this.disabledDatesText,  
    391.             disabledDays: this.disabledDays,  
    392.             disabledDaysText: this.disabledDaysText,  
    393.             format: this.format,  
    394.             timeFormat: this.timeFormat,  
    395.             dateFormat: this.dateFormat,  
    396.             showToday: this.showToday,  
    397.             minText: String.format(this.minText, this.formatDate(this.minValue)),  
    398.             maxText: String.format(this.maxText, this.formatDate(this.maxValue))  
    399.         });  
    400.         if (this.menuEvents) {  
    401.             this.menuEvents('on');  
    402.         }  
    403.         else {  
    404.             this.menu.on(Ext.apply({}, this.menuListeners, {  
    405.                 scope: this  
    406.             }));  
    407.         }  
    408.         this.menu.picker.setValue(this.getValue() || new Date());  
    409.         this.menu.show(this.el, "tl-bl?");  
    410.     }  
    411. });  
    412. Ext.reg('datetimefield', Ext.ux.form.DateTimeField);  

     四。示例截图:

    不积跬步,无以至千里,不积小流,无以成江河
  • 相关阅读:
    使用canvas实现擦玻璃效果
    安装jdk For Windows
    墙裂推荐4款js网页烟花特效
    再次推荐一款逼真的HTML5下雪效果
    HTML5播放暂停音乐
    周末web前端练习
    Javascript贪食蛇小游戏
    jquery实现更多内容效果
    jQuery省市区三级联动插件
    Web前端测试题
  • 原文地址:https://www.cnblogs.com/sunteng-change-control/p/4520915.html
Copyright © 2020-2023  润新知