| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701 |
- /* Fix ExtJS 3.4 issue with new timezones */
- Ext.override(Ext.form.TimeField, {
- initDate: '2/1/2008'
- });
- Ext.ns('Ext.ux.form');
- /**
- * Creates new DateTime
- * @constructor
- * @param {Object} config A config object
- */
- Ext.ux.form.DateTime = Ext.extend(Ext.form.Field, {
- /**
- * @cfg {Function} dateValidator A custom validation function to be called during date field
- * validation (defaults to null)
- */
- dateValidator:null
- /**
- * @cfg {String/Object} defaultAutoCreate DomHelper element spec
- * Let superclass to create hidden field instead of textbox. Hidden will be submittend to server
- */
- ,defaultAutoCreate:{tag:'input', type:'hidden'}
- /**
- * @cfg {String} dtSeparator Date - Time separator. Used to split date and time (defaults to ' ' (space))
- */
- ,dtSeparator:' '
- /**
- * @cfg {String} hiddenFormat Format of datetime used to store value in hidden field
- * and submitted to server (defaults to 'Y-m-d H:i:s' that is mysql format)
- */
- ,hiddenFormat:'Y-m-d H:i:s'
- /**
- * @cfg {Boolean} otherToNow Set other field to now() if not explicly filled in (defaults to true)
- */
- ,otherToNow:true
- /**
- * @cfg {Boolean} emptyToNow Set field value to now on attempt to set empty value.
- * If it is true then setValue() sets value of field to current date and time (defaults to false)
- */
- /**
- * @cfg {String} timePosition Where the time field should be rendered. 'right' is suitable for forms
- * and 'below' is suitable if the field is used as the grid editor (defaults to 'right')
- */
- ,timePosition:'right' // valid values:'below', 'right'
- /**
- * @cfg {Function} timeValidator A custom validation function to be called during time field
- * validation (defaults to null)
- */
- ,timeValidator:null
- /**
- * @cfg {Number} timeWidth Width of time field in pixels (defaults to 100)
- */
- ,timeWidth:100
- /**
- * @cfg {String} dateFormat Format of DateField. Can be localized. (defaults to 'm/y/d')
- */
- ,dateFormat:'m/d/y'
- /**
- * @cfg {String} timeFormat Format of TimeField. Can be localized. (defaults to 'g:i A')
- */
- ,timeFormat:'g:i A'
- /**
- * @cfg {Object} dateConfig Config for DateField constructor.
- */
- /**
- * @cfg {Object} timeConfig Config for TimeField constructor.
- */
- ,maxDateValue: ''
- ,minDateValue: ''
- ,timeIncrement: 15
- ,maxTimeValue: null
- ,minTimeValue: null
- ,disabledDates: null
- ,hideTime: false
- // {{{
- /**
- * @private
- * creates DateField and TimeField and installs the necessary event handlers
- */
- ,initComponent:function() {
- // call parent initComponent
- Ext.ux.form.DateTime.superclass.initComponent.call(this);
- // offset time
- if (!this.hasOwnProperty('offset_time') || isNaN(this.offset_time)) {
- this.offset_time = 0;
- }
- // create DateField
- var dateConfig = Ext.apply({}, {
- id:this.id + '-date'
- ,format:this.dateFormat || Ext.form.DateField.prototype.format
- ,width:this.timeWidth
- ,selectOnFocus:this.selectOnFocus
- ,validator:this.dateValidator
- ,disabledDates: this.disabledDates || null
- ,disabledDays: this.disabledDays || []
- ,showToday: this.showToday || true
- ,maxValue: this.maxDateValue || ''
- ,minValue: this.minDateValue || ''
- ,startDay: this.startDay || 0
- ,allowBlank: this.allowBlank
- ,listeners:{
- blur:{scope:this, fn:this.onBlur}
- ,focus:{scope:this, fn:this.onFocus}
- }
- }, this.dateConfig);
- this.df = new Ext.form.DateField(dateConfig);
- this.df.ownerCt = this;
- delete(this.dateFormat);
- delete(this.disabledDates);
- delete(this.disabledDays);
- delete(this.maxDateValue);
- delete(this.minDateValue);
- delete(this.startDay);
- // create TimeField
- var timeConfig = Ext.apply({}, {
- id:this.id + '-time'
- ,format:this.timeFormat || Ext.form.TimeField.prototype.format
- ,width:this.timeWidth
- ,selectOnFocus:this.selectOnFocus
- ,validator:this.timeValidator
- ,increment: this.timeIncrement || 15
- ,maxValue: this.maxTimeValue || null
- ,minValue: this.minTimeValue || null
- ,hidden: this.hideTime
- ,allowBlank: this.allowBlank
- ,listeners:{
- blur:{scope:this, fn:this.onBlur}
- ,focus:{scope:this, fn:this.onFocus}
- }
- }, this.timeConfig);
- this.tf = new Ext.form.TimeField(timeConfig);
- this.tf.ownerCt = this;
- delete(this.timeFormat);
- delete(this.maxTimeValue);
- delete(this.minTimeValue);
- delete(this.timeIncrement);
- // relay events
- this.relayEvents(this.df, ['focus', 'specialkey', 'invalid', 'valid']);
- this.relayEvents(this.tf, ['focus', 'specialkey', 'invalid', 'valid']);
- this.on('specialkey', this.onSpecialKey, this);
- } // eo function initComponent
- // }}}
- // {{{
- /**
- * @private
- * Renders underlying DateField and TimeField and provides a workaround for side error icon bug
- */
- ,onRender:function(ct, position) {
- // don't run more than once
- if(this.isRendered) {
- return;
- }
- // render underlying hidden field
- Ext.ux.form.DateTime.superclass.onRender.call(this, ct, position);
- // render DateField and TimeField
- // create bounding table
- var t;
- if('below' === this.timePosition || 'bellow' === this.timePosition) {
- t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
- {tag:'tr',children:[{tag:'td', style:'padding-bottom:1px', cls:'ux-datetime-date'}]}
- ,{tag:'tr',children:[{tag:'td', cls:'ux-datetime-time'}]}
- ]}, true);
- }
- else {
- t = Ext.DomHelper.append(ct, {tag:'table',style:'border-collapse:collapse',children:[
- {tag:'tr',children:[
- {tag:'td',style:'padding-right:4px', cls:'ux-datetime-date'},{tag:'td', cls:'ux-datetime-time'}
- ]}
- ]}, true);
- }
- this.tableEl = t;
- this.wrap = t.wrap({cls:'x-form-field-wrap x-datetime-wrap'});
- // this.wrap = t.wrap();
- this.wrap.on("mousedown", this.onMouseDown, this, {delay:10});
- // render DateField & TimeField
- this.df.render(t.child('td.ux-datetime-date'));
- this.tf.render(t.child('td.ux-datetime-time'));
- // workaround for IE trigger misalignment bug
- // see http://extjs.com/forum/showthread.php?p=341075#post341075
- // if(Ext.isIE && Ext.isStrict) {
- // t.select('input').applyStyles({top:0});
- // }
- this.df.el.swallowEvent(['keydown', 'keypress']);
- this.tf.el.swallowEvent(['keydown', 'keypress']);
- // create icon for side invalid errorIcon
- if('side' === this.msgTarget) {
- var elp = this.el.findParent('.x-form-element', 10, true);
- if(elp) {
- this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
- }
- var o = {
- errorIcon:this.errorIcon
- ,msgTarget:'side'
- ,alignErrorIcon:this.alignErrorIcon.createDelegate(this)
- };
- Ext.apply(this.df, o);
- Ext.apply(this.tf, o);
- // this.df.errorIcon = this.errorIcon;
- // this.tf.errorIcon = this.errorIcon;
- }
- // setup name for submit
- this.el.dom.name = this.hiddenName || this.name || this.id;
- // prevent helper fields from being submitted
- this.df.el.dom.removeAttribute("name");
- this.tf.el.dom.removeAttribute("name");
- // we're rendered flag
- this.isRendered = true;
- // update hidden field
- this.updateHidden();
- } // eo function onRender
- // }}}
- // {{{
- /**
- * @private
- */
- ,adjustSize:Ext.BoxComponent.prototype.adjustSize
- // }}}
- // {{{
- /**
- * @private
- */
- ,alignErrorIcon:function() {
- this.errorIcon.alignTo(this.tableEl, 'tl-tr', [2, 0]);
- }
- // }}}
- // {{{
- /**
- * @private initializes internal dateValue
- */
- ,initDateValue:function() {
- this.dateValue = this.otherToNow ? new Date() : new Date(1970, 0, 1, 0, 0, 0);
- }
- // }}}
- // {{{
- /**
- * Calls clearInvalid on the DateField and TimeField
- */
- ,clearInvalid:function(){
- this.df.clearInvalid();
- this.tf.clearInvalid();
- } // eo function clearInvalid
- // }}}
- // {{{
- /**
- * Calls markInvalid on both DateField and TimeField
- * @param {String} msg Invalid message to display
- */
- ,markInvalid:function(msg){
- this.df.markInvalid(msg);
- this.tf.markInvalid(msg);
- } // eo function markInvalid
- // }}}
- // {{{
- /**
- * @private
- * called from Component::destroy.
- * Destroys all elements and removes all listeners we've created.
- */
- ,beforeDestroy:function() {
- if(this.isRendered) {
- // this.removeAllListeners();
- this.wrap.removeAllListeners();
- this.wrap.remove();
- this.tableEl.remove();
- this.df.destroy();
- this.tf.destroy();
- }
- } // eo function beforeDestroy
- // }}}
- // {{{
- /**
- * Disable this component.
- * @return {Ext.Component} this
- */
- ,disable:function() {
- if(this.isRendered) {
- this.df.disabled = this.disabled;
- this.df.onDisable();
- this.tf.onDisable();
- }
- this.disabled = true;
- this.df.disabled = true;
- this.tf.disabled = true;
- this.fireEvent("disable", this);
- return this;
- } // eo function disable
- // }}}
- // {{{
- /**
- * Enable this component.
- * @return {Ext.Component} this
- */
- ,enable:function() {
- if(this.rendered){
- this.df.onEnable();
- this.tf.onEnable();
- }
- this.disabled = false;
- this.df.disabled = false;
- this.tf.disabled = false;
- this.fireEvent("enable", this);
- return this;
- } // eo function enable
- // }}}
- // {{{
- /**
- * @private Focus date filed
- */
- ,focus:function() {
- this.df.focus();
- } // eo function focus
- // }}}
- // {{{
- /**
- * @private
- */
- ,getPositionEl:function() {
- return this.wrap;
- }
- // }}}
- // {{{
- /**
- * @private
- */
- ,getResizeEl:function() {
- return this.wrap;
- }
- // }}}
- // {{{
- /**
- * @return {Date/String} Returns value of this field
- */
- ,getValue:function() {
- // create new instance of date
- return this.dateValue ? new Date(this.dateValue) : '';
- } // eo function getValue
- // }}}
- // {{{
- /**
- * @return {Boolean} true = valid, false = invalid
- * @private Calls isValid methods of underlying DateField and TimeField and returns the result
- */
- ,isValid:function() {
- return this.df.isValid() && this.tf.isValid();
- } // eo function isValid
- // }}}
- // {{{
- /**
- * Returns true if this component is visible
- * @return {boolean}
- */
- ,isVisible : function(){
- return this.df.rendered && this.df.getActionEl().isVisible();
- } // eo function isVisible
- // }}}
- // {{{
- /**
- * @private Handles blur event
- */
- ,onBlur:function(f) {
- // called by both DateField and TimeField blur events
- // revert focus to previous field if clicked in between
- if(this.wrapClick) {
- f.focus();
- this.wrapClick = false;
- }
- // update underlying value
- if(f === this.df) {
- this.updateDate();
- }
- else {
- this.updateTime();
- }
- this.updateHidden();
- this.validate();
- // fire events later
- (function() {
- if(!this.df.hasFocus && !this.tf.hasFocus) {
- var v = this.getValue();
- if(String(v) !== String(this.startValue)) {
- this.fireEvent("change", this, v, this.startValue);
- }
- this.hasFocus = false;
- this.fireEvent('blur', this);
- }
- }).defer(100, this);
- } // eo function onBlur
- // }}}
- // {{{
- /**
- * @private Handles focus event
- */
- ,onFocus:function() {
- if(!this.hasFocus){
- this.hasFocus = true;
- this.startValue = this.getValue();
- this.fireEvent("focus", this);
- }
- }
- // }}}
- // {{{
- /**
- * @private Just to prevent blur event when clicked in the middle of fields
- */
- ,onMouseDown:function(e) {
- if(!this.disabled) {
- this.wrapClick = 'td' === e.target.nodeName.toLowerCase();
- }
- }
- // }}}
- // {{{
- /**
- * @private
- * Handles Tab and Shift-Tab events
- */
- ,onSpecialKey:function(t, e) {
- var key = e.getKey();
- if(key === e.TAB) {
- if(t === this.df && !e.shiftKey) {
- e.stopEvent();
- this.tf.focus();
- }
- if(t === this.tf && e.shiftKey) {
- e.stopEvent();
- this.df.focus();
- }
- this.updateValue();
- }
- // otherwise it misbehaves in editor grid
- if(key === e.ENTER) {
- this.updateValue();
- }
- } // eo function onSpecialKey
- // }}}
- // {{{
- /**
- * Resets the current field value to the originally loaded value
- * and clears any validation messages. See Ext.form.BasicForm.trackResetOnLoad
- */
- ,reset:function() {
- this.df.setValue(this.originalValue);
- this.tf.setValue(this.originalValue);
- } // eo function reset
- // }}}
- // {{{
- /**
- * @private Sets the value of DateField
- */
- ,setDate:function(date) {
- if (date && this.offset_time != 0) {
- date = date.add(Date.MINUTE, 60 * new Number(this.offset_time));
- }
- this.df.setValue(date);
- } // eo function setDate
- // }}}
- // {{{
- /**
- * @private Sets the value of TimeField
- */
- ,setTime:function(date) {
- if (date && this.offset_time != 0) {
- date = date.add(Date.MINUTE, 60 * new Number(this.offset_time));
- }
- this.tf.setValue(date);
- } // eo function setTime
- // }}}
- // {{{
- /**
- * @private
- * Sets correct sizes of underlying DateField and TimeField
- * With workarounds for IE bugs
- */
- ,setSize:function(w, h) {
- if(!w) {
- return;
- }
- if('below' === this.timePosition) {
- this.df.setSize(w, h);
- this.tf.setSize(w, h);
- if(Ext.isIE) {
- this.df.el.up('td').setWidth(w);
- this.tf.el.up('td').setWidth(w);
- }
- }
- else {
- this.df.setSize(w - this.timeWidth - 4, h);
- this.tf.setSize(this.timeWidth, h);
- if(Ext.isIE) {
- this.df.el.up('td').setWidth(w - this.timeWidth - 4);
- this.tf.el.up('td').setWidth(this.timeWidth);
- }
- }
- } // eo function setSize
- // }}}
- // {{{
- /**
- * @param {Mixed} val Value to set
- * Sets the value of this field
- */
- ,setValue:function(val) {
- if(!val && true === this.emptyToNow) {
- this.setValue(new Date());
- return;
- }
- else if(!val) {
- this.setDate('');
- this.setTime('');
- this.updateValue();
- return;
- }
- if ('number' === typeof val) {
- val = new Date(val);
- }
- else if('string' === typeof val && this.hiddenFormat) {
- val = Date.parseDate(val, this.hiddenFormat);
- }
- val = val ? val : new Date(1970, 0 ,1, 0, 0, 0);
- var da;
- if(val instanceof Date) {
- this.setDate(val);
- this.setTime(val);
- this.dateValue = new Date(Ext.isIE ? val.getTime() : val);
- }
- else {
- da = val.split(this.dtSeparator);
- this.setDate(da[0]);
- if(da[1]) {
- if(da[2]) {
- // add am/pm part back to time
- da[1] += da[2];
- }
- this.setTime(da[1]);
- }
- }
- this.updateValue();
- } // eo function setValue
- // }}}
- // {{{
- /**
- * Hide or show this component by boolean
- * @return {Ext.Component} this
- */
- ,setVisible: function(visible){
- if(visible) {
- this.df.show();
- this.tf.show();
- }else{
- this.df.hide();
- this.tf.hide();
- }
- return this;
- } // eo function setVisible
- // }}}
- //{{{
- ,show:function() {
- return this.setVisible(true);
- } // eo function show
- //}}}
- //{{{
- ,hide:function() {
- return this.setVisible(false);
- } // eo function hide
- //}}}
- // {{{
- /**
- * @private Updates the date part
- */
- ,updateDate:function() {
- var d = this.df.getValue();
- if(d) {
- if(!(this.dateValue instanceof Date)) {
- this.initDateValue();
- if(!this.tf.getValue()) {
- this.setTime(this.dateValue);
- }
- }
- this.dateValue.setMonth(0); // because of leap years
- this.dateValue.setFullYear(d.getFullYear());
- this.dateValue.setMonth(d.getMonth(), d.getDate());
- // this.dateValue.setDate(d.getDate());
- }
- else {
- this.dateValue = '';
- this.setTime('');
- }
- } // eo function updateDate
- // }}}
- // {{{
- /**
- * @private
- * Updates the time part
- */
- ,updateTime:function() {
- var t = this.tf.getValue();
- if(t && !(t instanceof Date)) {
- t = Date.parseDate(t, this.tf.format);
- }
- if(t && !this.df.getValue()) {
- this.initDateValue();
- this.setDate(this.dateValue);
- }
- if(this.dateValue instanceof Date) {
- if(t) {
- this.dateValue.setHours(t.getHours());
- this.dateValue.setMinutes(t.getMinutes());
- this.dateValue.setSeconds(t.getSeconds());
- }
- else {
- this.dateValue.setHours(0);
- this.dateValue.setMinutes(0);
- this.dateValue.setSeconds(0);
- }
- }
- } // eo function updateTime
- // }}}
- // {{{
- /**
- * @private Updates the underlying hidden field value
- */
- ,updateHidden:function() {
- if(this.isRendered) {
- var value = '';
- if (this.dateValue instanceof Date) {
- value = this.dateValue.add(Date.MINUTE, 0 - 60 * new Number(this.offset_time)).format(this.hiddenFormat);
- }
- this.el.dom.value = value;
- }
- }
- // }}}
- // {{{
- /**
- * @private Updates all of Date, Time and Hidden
- */
- ,updateValue:function() {
- this.updateDate();
- this.updateTime();
- this.updateHidden();
- return;
- } // eo function updateValue
- // }}}
- // {{{
- /**
- * @return {Boolean} true = valid, false = invalid
- * calls validate methods of DateField and TimeField
- */
- ,validate:function() {
- return this.df.validate() && this.tf.validate();
- } // eo function validate
- // }}}
- // {{{
- /**
- * Returns renderer suitable to render this field
- * @param {Object} Column model config
- */
- ,renderer: function(field) {
- var format = field.editor.dateFormat || Ext.ux.form.DateTime.prototype.dateFormat;
- format += ' ' + (field.editor.timeFormat || Ext.ux.form.DateTime.prototype.timeFormat);
- var renderer = function(val) {
- var retval = Ext.util.Format.date(val, format);
- return retval;
- };
- return renderer;
- } // eo function renderer
- // }}}
- }); // eo extend
- // register xtype
- Ext.reg('xdatetime', Ext.ux.form.DateTime);
|