pkg-forms-debug.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:279k
源码类别:

JavaScript

开发平台:

JavaScript

  1.                     cls:'x-font-select',
  2.                     html: this.createFontOptions()
  3.                }
  4.             });                          items.push(                 fontSelectItem,                 '-'             );         }         if(this.enableFormat){             items.push(                 btn('bold'),                 btn('italic'),                 btn('underline')             );         }         if(this.enableFontSize){             items.push(                 '-',                 btn('increasefontsize', false, this.adjustFont),                 btn('decreasefontsize', false, this.adjustFont)             );         }         if(this.enableColors){             items.push(                 '-', {                     itemId:'forecolor',                     cls:'x-btn-icon',                     iconCls: 'x-edit-forecolor',                     clickEvent:'mousedown',                     tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,                     tabIndex:-1,                     menu : new Ext.menu.ColorMenu({                         allowReselect: true,                         focus: Ext.emptyFn,                         value:'000000',                         plain:true,                         listeners: {                             scope: this,                             select: function(cp, color){                                 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);                                 this.deferFocus();                             }                         },                         clickEvent:'mousedown'                     })                 }, {                     itemId:'backcolor',                     cls:'x-btn-icon',                     iconCls: 'x-edit-backcolor',                     clickEvent:'mousedown',                     tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,                     tabIndex:-1,                     menu : new Ext.menu.ColorMenu({                         focus: Ext.emptyFn,                         value:'FFFFFF',                         plain:true,                         allowReselect: true,                         listeners: {                             scope: this,                             select: function(cp, color){                                 if(Ext.isGecko){                                     this.execCmd('useCSS', false);                                     this.execCmd('hilitecolor', color);                                     this.execCmd('useCSS', true);                                     this.deferFocus();                                 }else{                                     this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);                                     this.deferFocus();                                 }                             }                         },                         clickEvent:'mousedown'                     })                 }             );         }         if(this.enableAlignments){             items.push(                 '-',                 btn('justifyleft'),                 btn('justifycenter'),                 btn('justifyright')             );         }         if(!Ext.isSafari2){             if(this.enableLinks){                 items.push(                     '-',                     btn('createlink', false, this.createLink)                 );             }             if(this.enableLists){                 items.push(                     '-',                     btn('insertorderedlist'),                     btn('insertunorderedlist')                 );             }             if(this.enableSourceEdit){                 items.push(                     '-',                     btn('sourceedit', true, function(btn){                         this.toggleSourceEdit(!this.sourceEditMode);                     })                 );             }         }
  5.  
  6.         // build the toolbar
  7.         var tb = new Ext.Toolbar({
  8.             renderTo: this.wrap.dom.firstChild,
  9.             items: items
  10.         });
  11.         
  12.         if (fontSelectItem) {
  13.             this.fontSelect = fontSelectItem.el;
  14.             
  15.             this.mon(this.fontSelect, 'change', function(){
  16.                 var font = this.fontSelect.dom.value;
  17.                 this.relayCmd('fontname', font);
  18.                 this.deferFocus();
  19.             }, this);
  20.         }
  21.         // stop form submits
  22.         this.mon(tb.el, 'click', function(e){
  23.             e.preventDefault();
  24.         });
  25.        
  26.         
  27.                  this.tb = tb;     },     onDisable: function(){         this.wrap.mask();         Ext.form.HtmlEditor.superclass.onDisable.call(this);     },     onEnable: function(){         this.wrap.unmask();         Ext.form.HtmlEditor.superclass.onEnable.call(this);     },     setReadOnly: function(readOnly){         if(this.initialized){             var newDM = readOnly ? 'off' : 'on',                 doc = this.getDoc();             if(String(doc.designMode).toLowerCase() != newDM){                 doc.designMode = newDM;             }             this.disableItems(!readOnly);         }         Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);     },     /**      * Protected method that will not generally be called directly. It      * is called when the editor initializes the iframe with HTML contents. Override this method if you      * want to change the initialization markup of the iframe (e.g. to add stylesheets).      */     getDocMarkup : function(){         return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';     },     // private     getEditorBody : function(){         var doc = this.getDoc();         return doc.body || doc.documentElement;     },     // private     getDoc : function(){         return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);     },     // private     getWin : function(){         return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];     },     // private     onRender : function(ct, position){         Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);         this.el.dom.style.border = '0 none';         this.el.dom.setAttribute('tabIndex', -1);         this.el.addClass('x-hidden');         if(Ext.isIE){ // fix IE 1px bogus margin             this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')         }         this.wrap = this.el.wrap({             cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}         });         this.createToolbar(this);         this.disableItems(true);         // is this needed?         // this.tb.doLayout();         this.createIFrame();         if(!this.width){             var sz = this.el.getSize();             this.setSize(sz.width, this.height || sz.height);         }         this.resizeEl = this.positionEl = this.wrap;     },     createIFrame: function(){         var iframe = document.createElement('iframe');         iframe.name = Ext.id();         iframe.frameBorder = '0';         iframe.src = Ext.SSL_SECURE_URL;         this.wrap.dom.appendChild(iframe);         this.iframe = iframe;         this.monitorTask = Ext.TaskMgr.start({             run: this.checkDesignMode,             scope: this,             interval:100         });     },     initFrame : function(){         Ext.TaskMgr.stop(this.monitorTask);         var doc = this.getDoc();         this.win = this.getWin();         doc.open();         doc.write(this.getDocMarkup());         doc.close();         var task = { // must defer to wait for browser to be ready             run : function(){                 var doc = this.getDoc();                 if(doc.body || doc.readyState == 'complete'){                     Ext.TaskMgr.stop(task);                     doc.designMode="on";                     this.initEditor.defer(10, this);                 }             },             interval : 10,             duration:10000,             scope: this         };         Ext.TaskMgr.start(task);     },     checkDesignMode : function(){         if(this.wrap && this.wrap.dom.offsetWidth){             var doc = this.getDoc();             if(!doc){                 return;             }             if(!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on'){                 this.initFrame();             }         }     },     disableItems: function(disabled){         if(this.fontSelect){             this.fontSelect.dom.disabled = disabled;         }         this.tb.items.each(function(item){             if(item.getItemId() != 'sourceedit'){                 item.setDisabled(disabled);             }         });     },     // private     onResize : function(w, h){         Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);         if(this.el && this.iframe){             if(Ext.isNumber(w)){                 var aw = w - this.wrap.getFrameWidth('lr');                 this.el.setWidth(aw);                 this.tb.setWidth(aw);                 this.iframe.style.width = Math.max(aw, 0) + 'px';             }             if(Ext.isNumber(h)){                 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();                 this.el.setHeight(ah);                 this.iframe.style.height = Math.max(ah, 0) + 'px';                 var bd = this.getEditorBody();                 if(bd){                     bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';                 }             }         }     },     /**      * Toggles the editor between standard and source edit mode.      * @param {Boolean} sourceEdit (optional) True for source edit, false for standard      */     toggleSourceEdit : function(sourceEditMode){         if(sourceEditMode === undefined){             sourceEditMode = !this.sourceEditMode;         }         this.sourceEditMode = sourceEditMode === true;         var btn = this.tb.getComponent('sourceedit');                  if(btn.pressed !== this.sourceEditMode){             btn.toggle(this.sourceEditMode);             if(!btn.xtbHidden){                 return;             }         }         if(this.sourceEditMode){             this.disableItems(true);             this.syncValue();             this.iframe.className = 'x-hidden';             this.el.removeClass('x-hidden');             this.el.dom.removeAttribute('tabIndex');             this.el.focus();         }else{             if(this.initialized && !this.readOnly){                 this.disableItems(false);             }             this.pushValue();             this.iframe.className = '';             this.el.addClass('x-hidden');             this.el.dom.setAttribute('tabIndex', -1);             this.deferFocus();         }         var lastSize = this.lastSize;         if(lastSize){             delete this.lastSize;             this.setSize(lastSize);         }         this.fireEvent('editmodechange', this, this.sourceEditMode);     },     // private used internally     createLink : function(){         var url = prompt(this.createLinkText, this.defaultLinkValue);         if(url && url != 'http:/'+'/'){             this.relayCmd('createlink', url);         }     },     // private     initEvents : function(){         this.originalValue = this.getValue();     },     /**      * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide      * @method      */     markInvalid : Ext.emptyFn,     /**      * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide      * @method      */     clearInvalid : Ext.emptyFn,     // docs inherit from Field     setValue : function(v){         Ext.form.HtmlEditor.superclass.setValue.call(this, v);         this.pushValue();         return this;     },     /**      * Protected method that will not generally be called directly. If you need/want      * custom HTML cleanup, this is the method you should override.      * @param {String} html The HTML to be cleaned      * @return {String} The cleaned HTML      */     cleanHtml: function(html) {         html = String(html);         if(Ext.isWebKit){ // strip safari nonsense             html = html.replace(/sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');         }         /*          * Neat little hack. Strips out all the non-digit characters from the default          * value and compares it to the character code of the first character in the string          * because it can cause encoding issues when posted to the server.          */         if(html.charCodeAt(0) == this.defaultValue.replace(/D/g, '')){             html = html.substring(1);         }         return html;     },     /**      * Protected method that will not generally be called directly. Syncs the contents      * of the editor iframe with the textarea.      */     syncValue : function(){         if(this.initialized){             var bd = this.getEditorBody();             var html = bd.innerHTML;             if(Ext.isWebKit){                 var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!                 var m = bs.match(/text-align:(.*?);/i);                 if(m && m[1]){                     html = '<div style="'+m[0]+'">' + html + '</div>';                 }             }             html = this.cleanHtml(html);             if(this.fireEvent('beforesync', this, html) !== false){                 this.el.dom.value = html;                 this.fireEvent('sync', this, html);             }         }     },     //docs inherit from Field     getValue : function() {         this[this.sourceEditMode ? 'pushValue' : 'syncValue']();         return Ext.form.HtmlEditor.superclass.getValue.call(this);     },     /**      * Protected method that will not generally be called directly. Pushes the value of the textarea      * into the iframe editor.      */     pushValue : function(){         if(this.initialized){             var v = this.el.dom.value;             if(!this.activated && v.length < 1){                 v = this.defaultValue;             }             if(this.fireEvent('beforepush', this, v) !== false){                 this.getEditorBody().innerHTML = v;                 if(Ext.isGecko){                     // Gecko hack, see: https://bugzilla.mozilla.org/show_bug.cgi?id=232791#c8                     var d = this.getDoc(),                         mode = d.designMode.toLowerCase();                     d.designMode = mode.toggle('on', 'off');                     d.designMode = mode;                 }                 this.fireEvent('push', this, v);             }         }     },     // private     deferFocus : function(){         this.focus.defer(10, this);     },     // docs inherit from Field     focus : function(){         if(this.win && !this.sourceEditMode){             this.win.focus();         }else{             this.el.focus();         }     },     // private     initEditor : function(){         //Destroying the component during/before initEditor can cause issues.         try{             var dbody = this.getEditorBody(),                 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat'),                 doc,                 fn;                              ss['background-attachment'] = 'fixed'; // w3c             dbody.bgProperties = 'fixed'; // ie             Ext.DomHelper.applyStyles(dbody, ss);                          doc = this.getDoc();             if(doc){                 try{                     Ext.EventManager.removeAll(doc);                 }catch(e){}             }             /*              * We need to use createDelegate here, because when using buffer, the delayed task is added              * as a property to the function. When the listener is removed, the task is deleted from the function.              * Since onEditorEvent is shared on the prototype, if we have multiple html editors, the first time one of the editors              * is destroyed, it causes the fn to be deleted from the prototype, which causes errors. Essentially, we're just anonymizing the function.              */             fn = this.onEditorEvent.createDelegate(this);             Ext.EventManager.on(doc, {                 mousedown: fn,                 dblclick: fn,                 click: fn,                 keyup: fn,                 buffer:100             });             if(Ext.isGecko){                 Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);             }             if(Ext.isIE || Ext.isWebKit || Ext.isOpera){                 Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);             }             doc.editorInitialized = true;             this.initialized = true;             this.pushValue();             this.setReadOnly(this.readOnly);             this.fireEvent('initialize', this);         }catch(e){}     },     // private     onDestroy : function(){         if(this.monitorTask){             Ext.TaskMgr.stop(this.monitorTask);         }         if(this.rendered){             Ext.destroy(this.tb);             var doc = this.getDoc();             if(doc){                 try{                     Ext.EventManager.removeAll(doc);                     for (var prop in doc){                         delete doc[prop];                     }                 }catch(e){}             }             if(this.wrap){                 this.wrap.dom.innerHTML = '';                 this.wrap.remove();             }         }                  if(this.el){             this.el.removeAllListeners();             this.el.remove();         }         this.purgeListeners();     },     // private     onFirstFocus : function(){         this.activated = true;         this.disableItems(false);         if(Ext.isGecko){ // prevent silly gecko errors             this.win.focus();             var s = this.win.getSelection();             if(!s.focusNode || s.focusNode.nodeType != 3){                 var r = s.getRangeAt(0);                 r.selectNodeContents(this.getEditorBody());                 r.collapse(true);                 this.deferFocus();             }             try{                 this.execCmd('useCSS', true);                 this.execCmd('styleWithCSS', false);             }catch(e){}         }         this.fireEvent('activate', this);     },     // private     adjustFont: function(btn){         var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,             doc = this.getDoc(),             v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);         if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){             // Safari 3 values             // 1 = 10px, 2 = 13px, 3 = 16px, 4 = 18px, 5 = 24px, 6 = 32px             if(v <= 10){                 v = 1 + adjust;             }else if(v <= 13){                 v = 2 + adjust;             }else if(v <= 16){                 v = 3 + adjust;             }else if(v <= 18){                 v = 4 + adjust;             }else if(v <= 24){                 v = 5 + adjust;             }else {                 v = 6 + adjust;             }             v = v.constrain(1, 6);         }else{             if(Ext.isSafari){ // safari                 adjust *= 2;             }             v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);         }         this.execCmd('FontSize', v);     },     // private     onEditorEvent : function(e){         this.updateToolbar();     },     /**      * Protected method that will not generally be called directly. It triggers      * a toolbar update by reading the markup state of the current selection in the editor.      */     updateToolbar: function(){         if(this.readOnly){             return;         }         if(!this.activated){             this.onFirstFocus();             return;         }         var btns = this.tb.items.map,              doc = this.getDoc();         if(this.enableFont && !Ext.isSafari2){             var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();             if(name != this.fontSelect.dom.value){                 this.fontSelect.dom.value = name;             }         }         if(this.enableFormat){             btns.bold.toggle(doc.queryCommandState('bold'));             btns.italic.toggle(doc.queryCommandState('italic'));             btns.underline.toggle(doc.queryCommandState('underline'));         }         if(this.enableAlignments){             btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));             btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));             btns.justifyright.toggle(doc.queryCommandState('justifyright'));         }         if(!Ext.isSafari2 && this.enableLists){             btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));             btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));         }         Ext.menu.MenuMgr.hideAll();         this.syncValue();     },     // private     relayBtnCmd : function(btn){         this.relayCmd(btn.getItemId());     },     /**      * Executes a Midas editor command on the editor document and performs necessary focus and      * toolbar updates. <b>This should only be called after the editor is initialized.</b>      * @param {String} cmd The Midas command      * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)      */     relayCmd : function(cmd, value){         (function(){             this.focus();             this.execCmd(cmd, value);             this.updateToolbar();         }).defer(10, this);     },     /**      * Executes a Midas editor command directly on the editor document.      * For visual commands, you should use {@link #relayCmd} instead.      * <b>This should only be called after the editor is initialized.</b>      * @param {String} cmd The Midas command      * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)      */     execCmd : function(cmd, value){         var doc = this.getDoc();         doc.execCommand(cmd, false, value === undefined ? null : value);         this.syncValue();     },     // private     applyCommand : function(e){         if(e.ctrlKey){             var c = e.getCharCode(), cmd;             if(c > 0){                 c = String.fromCharCode(c);                 switch(c){                     case 'b':                         cmd = 'bold';                     break;                     case 'i':                         cmd = 'italic';                     break;                     case 'u':                         cmd = 'underline';                     break;                 }                 if(cmd){                     this.win.focus();                     this.execCmd(cmd);                     this.deferFocus();                     e.preventDefault();                 }             }         }     },     /**      * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated      * to insert text.      * @param {String} text      */     insertAtCursor : function(text){         if(!this.activated){             return;         }         if(Ext.isIE){             this.win.focus();             var doc = this.getDoc(),                 r = doc.selection.createRange();             if(r){                 r.pasteHTML(text);                 this.syncValue();                 this.deferFocus();             }         }else{             this.win.focus();             this.execCmd('InsertHTML', text);             this.deferFocus();         }     },     // private     fixKeys : function(){ // load time branching for fastest keydown performance         if(Ext.isIE){             return function(e){                 var k = e.getKey(),                      doc = this.getDoc(),                         r;                 if(k == e.TAB){                     e.stopEvent();                     r = doc.selection.createRange();                     if(r){                         r.collapse(true);                         r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');                         this.deferFocus();                     }                 }else if(k == e.ENTER){                     r = doc.selection.createRange();                     if(r){                         var target = r.parentElement();                         if(!target || target.tagName.toLowerCase() != 'li'){                             e.stopEvent();                             r.pasteHTML('<br />');                             r.collapse(false);                             r.select();                         }                     }                 }             };         }else if(Ext.isOpera){             return function(e){                 var k = e.getKey();                 if(k == e.TAB){                     e.stopEvent();                     this.win.focus();                     this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');                     this.deferFocus();                 }             };         }else if(Ext.isWebKit){             return function(e){                 var k = e.getKey();                 if(k == e.TAB){                     e.stopEvent();                     this.execCmd('InsertText','t');                     this.deferFocus();                 }else if(k == e.ENTER){                     e.stopEvent();                     this.execCmd('InsertHtml','<br /><br />');                     this.deferFocus();                 }              };         }     }(),     /**      * Returns the editor's toolbar. <b>This is only available after the editor has been rendered.</b>      * @return {Ext.Toolbar}      */     getToolbar : function(){         return this.tb;     },     /**      * Object collection of toolbar tooltips for the buttons in the editor. The key      * is the command id associated with that button and the value is a valid QuickTips object.      * For example: <pre><code> {     bold : {         title: 'Bold (Ctrl+B)',         text: 'Make the selected text bold.',         cls: 'x-html-editor-tip'     },     italic : {         title: 'Italic (Ctrl+I)',         text: 'Make the selected text italic.',         cls: 'x-html-editor-tip'     },     ... </code></pre>     * @type Object      */     buttonTips : {         bold : {             title: 'Bold (Ctrl+B)',             text: 'Make the selected text bold.',             cls: 'x-html-editor-tip'         },         italic : {             title: 'Italic (Ctrl+I)',             text: 'Make the selected text italic.',             cls: 'x-html-editor-tip'         },         underline : {             title: 'Underline (Ctrl+U)',             text: 'Underline the selected text.',             cls: 'x-html-editor-tip'         },         increasefontsize : {             title: 'Grow Text',             text: 'Increase the font size.',             cls: 'x-html-editor-tip'         },         decreasefontsize : {             title: 'Shrink Text',             text: 'Decrease the font size.',             cls: 'x-html-editor-tip'         },         backcolor : {             title: 'Text Highlight Color',             text: 'Change the background color of the selected text.',             cls: 'x-html-editor-tip'         },         forecolor : {             title: 'Font Color',             text: 'Change the color of the selected text.',             cls: 'x-html-editor-tip'         },         justifyleft : {             title: 'Align Text Left',             text: 'Align text to the left.',             cls: 'x-html-editor-tip'         },         justifycenter : {             title: 'Center Text',             text: 'Center text in the editor.',             cls: 'x-html-editor-tip'         },         justifyright : {             title: 'Align Text Right',             text: 'Align text to the right.',             cls: 'x-html-editor-tip'         },         insertunorderedlist : {             title: 'Bullet List',             text: 'Start a bulleted list.',             cls: 'x-html-editor-tip'         },         insertorderedlist : {             title: 'Numbered List',             text: 'Start a numbered list.',             cls: 'x-html-editor-tip'         },         createlink : {             title: 'Hyperlink',             text: 'Make the selected text a hyperlink.',             cls: 'x-html-editor-tip'         },         sourceedit : {             title: 'Source Edit',             text: 'Switch to source editing mode.',             cls: 'x-html-editor-tip'         }     }     // hide stuff that is not compatible     /**      * @event blur      * @hide      */     /**      * @event change      * @hide      */     /**      * @event focus      * @hide      */     /**      * @event specialkey      * @hide      */     /**      * @cfg {String} fieldClass @hide      */     /**      * @cfg {String} focusClass @hide      */     /**      * @cfg {String} autoCreate @hide      */     /**      * @cfg {String} inputType @hide      */     /**      * @cfg {String} invalidClass @hide      */     /**      * @cfg {String} invalidText @hide      */     /**      * @cfg {String} msgFx @hide      */     /**      * @cfg {String} validateOnBlur @hide      */     /**      * @cfg {Boolean} allowDomMove  @hide      */     /**      * @cfg {String} applyTo @hide      */     /**      * @cfg {String} autoHeight  @hide      */     /**      * @cfg {String} autoWidth  @hide      */     /**      * @cfg {String} cls  @hide      */     /**      * @cfg {String} disabled  @hide      */     /**      * @cfg {String} disabledClass  @hide      */     /**      * @cfg {String} msgTarget  @hide      */     /**      * @cfg {String} readOnly  @hide      */     /**      * @cfg {String} style  @hide      */     /**      * @cfg {String} validationDelay  @hide      */     /**      * @cfg {String} validationEvent  @hide      */     /**      * @cfg {String} tabIndex  @hide      */     /**      * @property disabled      * @hide      */     /**      * @method applyToMarkup      * @hide      */     /**      * @method disable      * @hide      */     /**      * @method enable      * @hide      */     /**      * @method validate      * @hide      */     /**      * @event valid      * @hide      */     /**      * @method setDisabled      * @hide      */     /**      * @cfg keys      * @hide      */ }); Ext.reg('htmleditor', Ext.form.HtmlEditor);/**
  28.  * @class Ext.form.TimeField
  29.  * @extends Ext.form.ComboBox
  30.  * Provides a time input field with a time dropdown and automatic time validation.  Example usage:
  31.  * <pre><code>
  32. new Ext.form.TimeField({
  33.     minValue: '9:00 AM',
  34.     maxValue: '6:00 PM',
  35.     increment: 30
  36. });
  37. </code></pre>
  38.  * @constructor
  39.  * Create a new TimeField
  40.  * @param {Object} config
  41.  * @xtype timefield
  42.  */
  43. Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
  44.     /**
  45.      * @cfg {Date/String} minValue
  46.      * The minimum allowed time. Can be either a Javascript date object with a valid time value or a string 
  47.      * time in a valid format -- see {@link #format} and {@link #altFormats} (defaults to undefined).
  48.      */
  49.     minValue : undefined,
  50.     /**
  51.      * @cfg {Date/String} maxValue
  52.      * The maximum allowed time. Can be either a Javascript date object with a valid time value or a string 
  53.      * time in a valid format -- see {@link #format} and {@link #altFormats} (defaults to undefined).
  54.      */
  55.     maxValue : undefined,
  56.     /**
  57.      * @cfg {String} minText
  58.      * The error text to display when the date in the cell is before minValue (defaults to
  59.      * 'The time in this field must be equal to or after {0}').
  60.      */
  61.     minText : "The time in this field must be equal to or after {0}",
  62.     /**
  63.      * @cfg {String} maxText
  64.      * The error text to display when the time is after maxValue (defaults to
  65.      * 'The time in this field must be equal to or before {0}').
  66.      */
  67.     maxText : "The time in this field must be equal to or before {0}",
  68.     /**
  69.      * @cfg {String} invalidText
  70.      * The error text to display when the time in the field is invalid (defaults to
  71.      * '{value} is not a valid time').
  72.      */
  73.     invalidText : "{0} is not a valid time",
  74.     /**
  75.      * @cfg {String} format
  76.      * The default time format string which can be overriden for localization support.  The format must be
  77.      * valid according to {@link Date#parseDate} (defaults to 'g:i A', e.g., '3:15 PM').  For 24-hour time
  78.      * format try 'H:i' instead.
  79.      */
  80.     format : "g:i A",
  81.     /**
  82.      * @cfg {String} altFormats
  83.      * Multiple date formats separated by "|" to try when parsing a user input value and it doesn't match the defined
  84.      * format (defaults to 'g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H').
  85.      */
  86.     altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H",
  87.     /**
  88.      * @cfg {Number} increment
  89.      * The number of minutes between each time value in the list (defaults to 15).
  90.      */
  91.     increment: 15,
  92.     // private override
  93.     mode: 'local',
  94.     // private override
  95.     triggerAction: 'all',
  96.     // private override
  97.     typeAhead: false,
  98.     
  99.     // private - This is the date to use when generating time values in the absence of either minValue
  100.     // or maxValue.  Using the current date causes DST issues on DST boundary dates, so this is an 
  101.     // arbitrary "safe" date that can be any date aside from DST boundary dates.
  102.     initDate: '1/1/2008',
  103.     // private
  104.     initComponent : function(){
  105.         if(Ext.isDefined(this.minValue)){
  106.             this.setMinValue(this.minValue, true);
  107.         }
  108.         if(Ext.isDefined(this.maxValue)){
  109.             this.setMaxValue(this.maxValue, true);
  110.         }
  111.         if(!this.store){
  112.             this.generateStore(true);
  113.         }
  114.         Ext.form.TimeField.superclass.initComponent.call(this);
  115.     },
  116.     
  117.     /**
  118.      * Replaces any existing {@link #minValue} with the new time and refreshes the store.
  119.      * @param {Date/String} value The minimum time that can be selected
  120.      */
  121.     setMinValue: function(value, /* private */ initial){
  122.         this.setLimit(value, true, initial);
  123.         return this;
  124.     },
  125.     /**
  126.      * Replaces any existing {@link #maxValue} with the new time and refreshes the store.
  127.      * @param {Date/String} value The maximum time that can be selected
  128.      */
  129.     setMaxValue: function(value, /* private */ initial){
  130.         this.setLimit(value, false, initial);
  131.         return this;
  132.     },
  133.     
  134.     // private
  135.     generateStore: function(initial){
  136.         var min = this.minValue || new Date(this.initDate).clearTime(),
  137.             max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
  138.             times = [];
  139.             
  140.         while(min <= max){
  141.             times.push(min.dateFormat(this.format));
  142.             min = min.add('mi', this.increment);
  143.         }
  144.         this.bindStore(times, initial);
  145.     },
  146.     // private
  147.     setLimit: function(value, isMin, initial){
  148.         var d;
  149.         if(Ext.isString(value)){
  150.             d = this.parseDate(value);
  151.         }else if(Ext.isDate(value)){
  152.             d = value;
  153.         }
  154.         if(d){
  155.             var val = new Date(this.initDate).clearTime();
  156.             val.setHours(d.getHours(), d.getMinutes(), isMin ? 0 : 59, 0);
  157.             this[isMin ? 'minValue' : 'maxValue'] = val;
  158.             if(!initial){
  159.                 this.generateStore();
  160.             }
  161.         }
  162.     },
  163.     
  164.     // inherited docs
  165.     getValue : function(){
  166.         var v = Ext.form.TimeField.superclass.getValue.call(this);
  167.         return this.formatDate(this.parseDate(v)) || '';
  168.     },
  169.     // inherited docs
  170.     setValue : function(value){
  171.         return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
  172.     },
  173.     // private overrides
  174.     validateValue : Ext.form.DateField.prototype.validateValue,
  175.     parseDate : Ext.form.DateField.prototype.parseDate,
  176.     formatDate : Ext.form.DateField.prototype.formatDate,
  177.     // private
  178.     beforeBlur : function(){
  179.         var v = this.parseDate(this.getRawValue());
  180.         if(v){
  181.             this.setValue(v.dateFormat(this.format));
  182.         }
  183.         Ext.form.TimeField.superclass.beforeBlur.call(this);
  184.     }
  185.     /**
  186.      * @cfg {Boolean} grow @hide
  187.      */
  188.     /**
  189.      * @cfg {Number} growMin @hide
  190.      */
  191.     /**
  192.      * @cfg {Number} growMax @hide
  193.      */
  194.     /**
  195.      * @hide
  196.      * @method autoSize
  197.      */
  198. });
  199. Ext.reg('timefield', Ext.form.TimeField);/**  * @class Ext.form.Label  * @extends Ext.BoxComponent  * Basic Label field.  * @constructor  * Creates a new Label  * @param {Ext.Element/String/Object} config The configuration options.  If an element is passed, it is set as the internal  * element and its id used as the component id.  If a string is passed, it is assumed to be the id of an existing element  * and is used as the component id.  Otherwise, it is assumed to be a standard config object and is applied to the component.  * @xtype label  */ Ext.form.Label = Ext.extend(Ext.BoxComponent, {     /**      * @cfg {String} text The plain text to display within the label (defaults to ''). If you need to include HTML      * tags within the label's innerHTML, use the {@link #html} config instead.      */     /**      * @cfg {String} forId The id of the input element to which this label will be bound via the standard HTML 'for'      * attribute. If not specified, the attribute will not be added to the label.      */     /**      * @cfg {String} html An HTML fragment that will be used as the label's innerHTML (defaults to '').      * Note that if {@link #text} is specified it will take precedence and this value will be ignored.      */     // private     onRender : function(ct, position){         if(!this.el){             this.el = document.createElement('label');             this.el.id = this.getId();             this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');             if(this.forId){                 this.el.setAttribute('for', this.forId);             }         }         Ext.form.Label.superclass.onRender.call(this, ct, position);     },     /**      * Updates the label's innerHTML with the specified string.      * @param {String} text The new label text      * @param {Boolean} encode (optional) False to skip HTML-encoding the text when rendering it      * to the label (defaults to true which encodes the value). This might be useful if you want to include      * tags in the label's innerHTML rather than rendering them as string literals per the default logic.      * @return {Label} this      */     setText : function(t, encode){         var e = encode === false;         this[!e ? 'text' : 'html'] = t;         delete this[e ? 'text' : 'html'];         if(this.rendered){             this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;         }         return this;     } }); Ext.reg('label', Ext.form.Label);/**  * @class Ext.form.Action  * <p>The subclasses of this class provide actions to perform upon {@link Ext.form.BasicForm Form}s.</p>  * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when  * the Form needs to perform an action such as submit or load. The Configuration options  * listed for this class are set through the Form's action methods: {@link Ext.form.BasicForm#submit submit},  * {@link Ext.form.BasicForm#load load} and {@link Ext.form.BasicForm#doAction doAction}</p>  * <p>The instance of Action which performed the action is passed to the success  * and failure callbacks of the Form's action methods ({@link Ext.form.BasicForm#submit submit},  * {@link Ext.form.BasicForm#load load} and {@link Ext.form.BasicForm#doAction doAction}),  * and to the {@link Ext.form.BasicForm#actioncomplete actioncomplete} and  * {@link Ext.form.BasicForm#actionfailed actionfailed} event handlers.</p>  */ Ext.form.Action = function(form, options){     this.form = form;     this.options = options || {}; }; /**  * Failure type returned when client side validation of the Form fails  * thus aborting a submit action. Client side validation is performed unless  * {@link #clientValidation} is explicitly set to <tt>false</tt>.  * @type {String}  * @static  */ Ext.form.Action.CLIENT_INVALID = 'client'; /**  * <p>Failure type returned when server side processing fails and the {@link #result}'s  * <tt style="font-weight:bold">success</tt> property is set to <tt>false</tt>.</p>  * <p>In the case of a form submission, field-specific error messages may be returned in the  * {@link #result}'s <tt style="font-weight:bold">errors</tt> property.</p>  * @type {String}  * @static  */ Ext.form.Action.SERVER_INVALID = 'server'; /**  * Failure type returned when a communication error happens when attempting  * to send a request to the remote server. The {@link #response} may be examined to  * provide further information.  * @type {String}  * @static  */ Ext.form.Action.CONNECT_FAILURE = 'connect'; /**  * Failure type returned when the response's <tt style="font-weight:bold">success</tt>  * property is set to <tt>false</tt>, or no field values are returned in the response's  * <tt style="font-weight:bold">data</tt> property.  * @type {String}  * @static  */ Ext.form.Action.LOAD_FAILURE = 'load'; Ext.form.Action.prototype = { /**  * @cfg {String} url The URL that the Action is to invoke.  */ /**  * @cfg {Boolean} reset When set to <tt><b>true</b></tt>, causes the Form to be  * {@link Ext.form.BasicForm.reset reset} on Action success. If specified, this happens  * <b>before</b> the {@link #success} callback is called and before the Form's  * {@link Ext.form.BasicForm.actioncomplete actioncomplete} event fires.  */ /**  * @cfg {String} method The HTTP method to use to access the requested URL. Defaults to the  * {@link Ext.form.BasicForm}'s method, or if that is not specified, the underlying DOM form's method.  */ /**  * @cfg {Mixed} params <p>Extra parameter values to pass. These are added to the Form's  * {@link Ext.form.BasicForm#baseParams} and passed to the specified URL along with the Form's  * input fields.</p>  * <p>Parameters are encoded as standard HTTP parameters using {@link Ext#urlEncode}.</p>  */ /**  * @cfg {Number} timeout The number of seconds to wait for a server response before  * failing with the {@link #failureType} as {@link #Action.CONNECT_FAILURE}. If not specified,  * defaults to the configured <tt>{@link Ext.form.BasicForm#timeout timeout}</tt> of the  * {@link Ext.form.BasicForm form}.  */ /**  * @cfg {Function} success The function to call when a valid success return packet is recieved.  * The function is passed the following parameters:<ul class="mdetail-params">  * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The form that requested the action</div></li>  * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The Action class. The {@link #result}  * property of this object may be examined to perform custom postprocessing.</div></li>  * </ul>  */ /**  * @cfg {Function} failure The function to call when a failure packet was recieved, or when an  * error ocurred in the Ajax communication.  * The function is passed the following parameters:<ul class="mdetail-params">  * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The form that requested the action</div></li>  * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The Action class. If an Ajax  * error ocurred, the failure type will be in {@link #failureType}. The {@link #result}  * property of this object may be examined to perform custom postprocessing.</div></li>  * </ul>  */ /**  * @cfg {Object} scope The scope in which to call the callback functions (The <tt>this</tt> reference  * for the callback functions).  */ /**  * @cfg {String} waitMsg The message to be displayed by a call to {@link Ext.MessageBox#wait}  * during the time the action is being processed.  */ /**  * @cfg {String} waitTitle The title to be displayed by a call to {@link Ext.MessageBox#wait}  * during the time the action is being processed.  */ /**  * The type of action this Action instance performs.  * Currently only "submit" and "load" are supported.  * @type {String}  */     type : 'default', /**  * The type of failure detected will be one of these: {@link #CLIENT_INVALID},  * {@link #SERVER_INVALID}, {@link #CONNECT_FAILURE}, or {@link #LOAD_FAILURE}.  Usage:  * <pre><code> var fp = new Ext.form.FormPanel({ ... buttons: [{     text: 'Save',     formBind: true,     handler: function(){         if(fp.getForm().isValid()){             fp.getForm().submit({                 url: 'form-submit.php',                 waitMsg: 'Submitting your data...',                 success: function(form, action){                     // server responded with success = true                     var result = action.{@link #result};                 },                 failure: function(form, action){                     if (action.{@link #failureType} === Ext.form.Action.{@link #CONNECT_FAILURE}) {                         Ext.Msg.alert('Error',                             'Status:'+action.{@link #response}.status+': '+                             action.{@link #response}.statusText);                     }                     if (action.failureType === Ext.form.Action.{@link #SERVER_INVALID}){                         // server responded with success = false                         Ext.Msg.alert('Invalid', action.{@link #result}.errormsg);                     }                 }             });         }     } },{     text: 'Reset',     handler: function(){         fp.getForm().reset();     } }]  * </code></pre>  * @property failureType  * @type {String}  */  /**  * The XMLHttpRequest object used to perform the action.  * @property response  * @type {Object}  */  /**  * The decoded response object containing a boolean <tt style="font-weight:bold">success</tt> property and  * other, action-specific properties.  * @property result  * @type {Object}  */     // interface method     run : function(options){     },     // interface method     success : function(response){     },     // interface method     handleResponse : function(response){     },     // default connection failure     failure : function(response){         this.response = response;         this.failureType = Ext.form.Action.CONNECT_FAILURE;         this.form.afterAction(this, false);     },     // private     // shared code among all Actions to validate that there was a response     // with either responseText or responseXml     processResponse : function(response){         this.response = response;         if(!response.responseText && !response.responseXML){             return true;         }         this.result = this.handleResponse(response);         return this.result;     },     // utility functions used internally     getUrl : function(appendParams){         var url = this.options.url || this.form.url || this.form.el.dom.action;         if(appendParams){             var p = this.getParams();             if(p){                 url = Ext.urlAppend(url, p);             }         }         return url;     },     // private     getMethod : function(){         return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();     },     // private     getParams : function(){         var bp = this.form.baseParams;         var p = this.options.params;         if(p){             if(typeof p == "object"){                 p = Ext.urlEncode(Ext.applyIf(p, bp));             }else if(typeof p == 'string' && bp){                 p += '&' + Ext.urlEncode(bp);             }         }else if(bp){             p = Ext.urlEncode(bp);         }         return p;     },     // private     createCallback : function(opts){         var opts = opts || {};         return {             success: this.success,             failure: this.failure,             scope: this,             timeout: (opts.timeout*1000) || (this.form.timeout*1000),             upload: this.form.fileUpload ? this.success : undefined         };     } }; /**  * @class Ext.form.Action.Submit  * @extends Ext.form.Action  * <p>A class which handles submission of data from {@link Ext.form.BasicForm Form}s  * and processes the returned response.</p>  * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when  * {@link Ext.form.BasicForm#submit submit}ting.</p>  * <p><u><b>Response Packet Criteria</b></u></p>  * <p>A response packet may contain:  * <div class="mdetail-params"><ul>  * <li><b><code>success</code></b> property : Boolean  * <div class="sub-desc">The <code>success</code> property is required.</div></li>  * <li><b><code>errors</code></b> property : Object  * <div class="sub-desc"><div class="sub-desc">The <code>errors</code> property,  * which is optional, contains error messages for invalid fields.</div></li>  * </ul></div>  * <p><u><b>JSON Packets</b></u></p>  * <p>By default, response packets are assumed to be JSON, so a typical response  * packet may look like this:</p><pre><code> {     success: false,     errors: {         clientCode: "Client not found",         portOfLoading: "This field must not be null"     } }</code></pre>  * <p>Other data may be placed into the response for processing by the {@link Ext.form.BasicForm}'s callback  * or event handler methods. The object decoded from this JSON is available in the  * {@link Ext.form.Action#result result} property.</p>  * <p>Alternatively, if an {@link #errorReader} is specified as an {@link Ext.data.XmlReader XmlReader}:</p><pre><code>     errorReader: new Ext.data.XmlReader({             record : 'field',             success: '@success'         }, [             'id', 'msg'         ]     ) </code></pre>  * <p>then the results may be sent back in XML format:</p><pre><code> &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;message success="false"&gt; &lt;errors&gt;     &lt;field&gt;         &lt;id&gt;clientCode&lt;/id&gt;         &lt;msg&gt;&lt;![CDATA[Code not found. &lt;br /&gt;&lt;i&gt;This is a test validation message from the server &lt;/i&gt;]]&gt;&lt;/msg&gt;     &lt;/field&gt;     &lt;field&gt;         &lt;id&gt;portOfLoading&lt;/id&gt;         &lt;msg&gt;&lt;![CDATA[Port not found. &lt;br /&gt;&lt;i&gt;This is a test validation message from the server &lt;/i&gt;]]&gt;&lt;/msg&gt;     &lt;/field&gt; &lt;/errors&gt; &lt;/message&gt; </code></pre>  * <p>Other elements may be placed into the response XML for processing by the {@link Ext.form.BasicForm}'s callback  * or event handler methods. The XML document is available in the {@link #errorReader}'s {@link Ext.data.XmlReader#xmlData xmlData} property.</p>  */ Ext.form.Action.Submit = function(form, options){     Ext.form.Action.Submit.superclass.constructor.call(this, form, options); }; Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {     /**      * @cfg {Ext.data.DataReader} errorReader <p><b>Optional. JSON is interpreted with      * no need for an errorReader.</b></p>      * <p>A Reader which reads a single record from the returned data. The DataReader's      * <b>success</b> property specifies how submission success is determined. The Record's      * data provides the error messages to apply to any invalid form Fields.</p>      */     /**      * @cfg {boolean} clientValidation Determines whether a Form's fields are validated      * in a final call to {@link Ext.form.BasicForm#isValid isValid} prior to submission.      * Pass <tt>false</tt> in the Form's submit options to prevent this. If not defined, pre-submission field validation      * is performed.      */     type : 'submit',     // private     run : function(){         var o = this.options;         var method = this.getMethod();         var isGet = method == 'GET';         if(o.clientValidation === false || this.form.isValid()){             Ext.Ajax.request(Ext.apply(this.createCallback(o), {                 form:this.form.el.dom,                 url:this.getUrl(isGet),                 method: method,                 headers: o.headers,                 params:!isGet ? this.getParams() : null,                 isUpload: this.form.fileUpload             }));         }else if (o.clientValidation !== false){ // client validation failed             this.failureType = Ext.form.Action.CLIENT_INVALID;             this.form.afterAction(this, false);         }     },     // private     success : function(response){         var result = this.processResponse(response);         if(result === true || result.success){             this.form.afterAction(this, true);             return;         }         if(result.errors){             this.form.markInvalid(result.errors);         }         this.failureType = Ext.form.Action.SERVER_INVALID;         this.form.afterAction(this, false);     },     // private     handleResponse : function(response){         if(this.form.errorReader){             var rs = this.form.errorReader.read(response);             var errors = [];             if(rs.records){                 for(var i = 0, len = rs.records.length; i < len; i++) {                     var r = rs.records[i];                     errors[i] = r.data;                 }             }             if(errors.length < 1){                 errors = null;             }             return {                 success : rs.success,                 errors : errors             };         }         return Ext.decode(response.responseText);     } }); /**  * @class Ext.form.Action.Load  * @extends Ext.form.Action  * <p>A class which handles loading of data from a server into the Fields of an {@link Ext.form.BasicForm}.</p>  * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when  * {@link Ext.form.BasicForm#load load}ing.</p>  * <p><u><b>Response Packet Criteria</b></u></p>  * <p>A response packet <b>must</b> contain:  * <div class="mdetail-params"><ul>  * <li><b><code>success</code></b> property : Boolean</li>  * <li><b><code>data</code></b> property : Object</li>  * <div class="sub-desc">The <code>data</code> property contains the values of Fields to load.  * The individual value object for each Field is passed to the Field's  * {@link Ext.form.Field#setValue setValue} method.</div></li>  * </ul></div>  * <p><u><b>JSON Packets</b></u></p>  * <p>By default, response packets are assumed to be JSON, so for the following form load call:<pre><code> var myFormPanel = new Ext.form.FormPanel({     title: 'Client and routing info',     items: [{         fieldLabel: 'Client',         name: 'clientName'     }, {         fieldLabel: 'Port of loading',         name: 'portOfLoading'     }, {         fieldLabel: 'Port of discharge',         name: 'portOfDischarge'     }] }); myFormPanel.{@link Ext.form.FormPanel#getForm getForm}().{@link Ext.form.BasicForm#load load}({     url: '/getRoutingInfo.php',     params: {         consignmentRef: myConsignmentRef     },     failure: function(form, action) {         Ext.Msg.alert("Load failed", action.result.errorMessage);     } }); </code></pre>  * a <b>success response</b> packet may look like this:</p><pre><code> {     success: true,     data: {         clientName: "Fred. Olsen Lines",         portOfLoading: "FXT",         portOfDischarge: "OSL"     } }</code></pre>  * while a <b>failure response</b> packet may look like this:</p><pre><code> {     success: false,     errorMessage: "Consignment reference not found" }</code></pre>  * <p>Other data may be placed into the response for processing the {@link Ext.form.BasicForm Form}'s  * callback or event handler methods. The object decoded from this JSON is available in the  * {@link Ext.form.Action#result result} property.</p>  */ Ext.form.Action.Load = function(form, options){     Ext.form.Action.Load.superclass.constructor.call(this, form, options);     this.reader = this.form.reader; }; Ext.extend(Ext.form.Action.Load, Ext.form.Action, {     // private     type : 'load',     // private     run : function(){         Ext.Ajax.request(Ext.apply(                 this.createCallback(this.options), {                     method:this.getMethod(),                     url:this.getUrl(false),                     headers: this.options.headers,                     params:this.getParams()         }));     },     // private     success : function(response){         var result = this.processResponse(response);         if(result === true || !result.success || !result.data){             this.failureType = Ext.form.Action.LOAD_FAILURE;             this.form.afterAction(this, false);             return;         }         this.form.clearInvalid();         this.form.setValues(result.data);         this.form.afterAction(this, true);     },     // private     handleResponse : function(response){         if(this.form.reader){             var rs = this.form.reader.read(response);             var data = rs.records && rs.records[0] ? rs.records[0].data : null;             return {                 success : rs.success,                 data : data             };         }         return Ext.decode(response.responseText);     } }); /**  * @class Ext.form.Action.DirectLoad  * @extends Ext.form.Action.Load  * <p>Provides Ext.direct support for loading form data.</p>  * <p>This example illustrates usage of Ext.Direct to <b>load</b> a form through Ext.Direct.</p>  * <pre><code> var myFormPanel = new Ext.form.FormPanel({     // configs for FormPanel     title: 'Basic Information',     renderTo: document.body,     width: 300, height: 160,     padding: 10,     // configs apply to child items     defaults: {anchor: '100%'},     defaultType: 'textfield',     items: [{         fieldLabel: 'Name',         name: 'name'     },{         fieldLabel: 'Email',         name: 'email'     },{         fieldLabel: 'Company',         name: 'company'     }],     // configs for BasicForm     api: {         // The server-side method to call for load() requests         load: Profile.getBasicInfo,         // The server-side must mark the submit handler as a 'formHandler'         submit: Profile.updateBasicInfo     },     // specify the order for the passed params     paramOrder: ['uid', 'foo'] }); // load the form myFormPanel.getForm().load({     // pass 2 arguments to server side getBasicInfo method (len=2)     params: {         foo: 'bar',         uid: 34     } });  * </code></pre>  * The data packet sent to the server will resemble something like:  * <pre><code> [     {         "action":"Profile","method":"getBasicInfo","type":"rpc","tid":2,         "data":[34,"bar"] // note the order of the params     } ]  * </code></pre>  * The form will process a data packet returned by the server that is similar  * to the following format:  * <pre><code> [     {         "action":"Profile","method":"getBasicInfo","type":"rpc","tid":2,         "result":{             "success":true,             "data":{                 "name":"Fred Flintstone",                 "company":"Slate Rock and Gravel",                 "email":"fred.flintstone@slaterg.com"             }         }     } ]  * </code></pre>  */ Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {     constructor: function(form, opts) {         Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);     },     type : 'directload',     run : function(){         var args = this.getParams();         args.push(this.success, this);         this.form.api.load.apply(window, args);     },     getParams : function() {         var buf = [], o = {};         var bp = this.form.baseParams;         var p = this.options.params;         Ext.apply(o, p, bp);         var paramOrder = this.form.paramOrder;         if(paramOrder){             for(var i = 0, len = paramOrder.length; i < len; i++){                 buf.push(o[paramOrder[i]]);             }         }else if(this.form.paramsAsHash){             buf.push(o);         }         return buf;     },     // Direct actions have already been processed and therefore     // we can directly set the result; Direct Actions do not have     // a this.response property.     processResponse : function(result) {         this.result = result;         return result;     },          success : function(response, trans){         if(trans.type == Ext.Direct.exceptions.SERVER){             response = {};         }         Ext.form.Action.DirectLoad.superclass.success.call(this, response);     } }); /**  * @class Ext.form.Action.DirectSubmit  * @extends Ext.form.Action.Submit  * <p>Provides Ext.direct support for submitting form data.</p>  * <p>This example illustrates usage of Ext.Direct to <b>submit</b> a form through Ext.Direct.</p>  * <pre><code> var myFormPanel = new Ext.form.FormPanel({     // configs for FormPanel     title: 'Basic Information',     renderTo: document.body,     width: 300, height: 160,     padding: 10,     buttons:[{         text: 'Submit',         handler: function(){             myFormPanel.getForm().submit({                 params: {                     foo: 'bar',                     uid: 34                 }             });         }     }],     // configs apply to child items     defaults: {anchor: '100%'},     defaultType: 'textfield',     items: [{         fieldLabel: 'Name',         name: 'name'     },{         fieldLabel: 'Email',         name: 'email'     },{         fieldLabel: 'Company',         name: 'company'     }],     // configs for BasicForm     api: {         // The server-side method to call for load() requests         load: Profile.getBasicInfo,         // The server-side must mark the submit handler as a 'formHandler'         submit: Profile.updateBasicInfo     },     // specify the order for the passed params     paramOrder: ['uid', 'foo'] });  * </code></pre>  * The data packet sent to the server will resemble something like:  * <pre><code> {     "action":"Profile","method":"updateBasicInfo","type":"rpc","tid":"6",     "result":{         "success":true,         "id":{             "extAction":"Profile","extMethod":"updateBasicInfo",             "extType":"rpc","extTID":"6","extUpload":"false",             "name":"Aaron Conran","email":"aaron@extjs.com","company":"Ext JS, LLC"         }     } }  * </code></pre>  * The form will process a data packet returned by the server that is similar  * to the following:  * <pre><code> // sample success packet (batched requests) [     {         "action":"Profile","method":"updateBasicInfo","type":"rpc","tid":3,         "result":{             "success":true         }     } ] // sample failure packet (one request) {         "action":"Profile","method":"updateBasicInfo","type":"rpc","tid":"6",         "result":{             "errors":{                 "email":"already taken"             },             "success":false,             "foo":"bar"         } }  * </code></pre>  * Also see the discussion in {@link Ext.form.Action.DirectLoad}.  */ Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {     constructor : function(form, opts) {         Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);     },     type : 'directsubmit',     // override of Submit     run : function(){         var o = this.options;         if(o.clientValidation === false || this.form.isValid()){             // tag on any additional params to be posted in the             // form scope             this.success.params = this.getParams();             this.form.api.submit(this.form.el.dom, this.success, this);         }else if (o.clientValidation !== false){ // client validation failed             this.failureType = Ext.form.Action.CLIENT_INVALID;             this.form.afterAction(this, false);         }     },     getParams : function() {         var o = {};         var bp = this.form.baseParams;         var p = this.options.params;         Ext.apply(o, p, bp);         return o;     },     // Direct actions have already been processed and therefore     // we can directly set the result; Direct Actions do not have     // a this.response property.     processResponse : function(result) {         this.result = result;         return result;     },          success : function(response, trans){         if(trans.type == Ext.Direct.exceptions.SERVER){             response = {};         }         Ext.form.Action.DirectSubmit.superclass.success.call(this, response);     } }); Ext.form.Action.ACTION_TYPES = {     'load' : Ext.form.Action.Load,     'submit' : Ext.form.Action.Submit,     'directload' : Ext.form.Action.DirectLoad,     'directsubmit' : Ext.form.Action.DirectSubmit }; /**  * @class Ext.form.VTypes  * <p>This is a singleton object which contains a set of commonly used field validation functions.  * The validations provided are basic and intended to be easily customizable and extended.</p>  * <p>To add custom VTypes specify the <code>{@link Ext.form.TextField#vtype vtype}</code> validation  * test function, and optionally specify any corresponding error text to display and any keystroke  * filtering mask to apply. For example:</p>  * <pre><code> // custom Vtype for vtype:'time' var timeTest = /^([1-9]|1[0-9]):([0-5][0-9])(s[a|p]m)$/i; Ext.apply(Ext.form.VTypes, {     //  vtype validation function     time: function(val, field) {         return timeTest.test(val);     },     // vtype Text property: The error text to display when the validation function returns false     timeText: 'Not a valid time.  Must be in the format "12:34 PM".',     // vtype Mask property: The keystroke filter mask     timeMask: /[ds:amp]/i });  * </code></pre>  * Another example:   * <pre><code> // custom Vtype for vtype:'IPAddress' Ext.apply(Ext.form.VTypes, {     IPAddress:  function(v) {         return /^d{1,3}.d{1,3}.d{1,3}.d{1,3}$/.test(v);     },     IPAddressText: 'Must be a numeric IP address',     IPAddressMask: /[d.]/i });  * </code></pre>  * @singleton  */ Ext.form.VTypes = function(){     // closure these in so they are only created once.     var alpha = /^[a-zA-Z_]+$/,         alphanum = /^[a-zA-Z0-9_]+$/,         email = /^(w+)([-+.][w]+)*@(w[-w]*.){1,5}([A-Za-z]){2,6}$/,         url = /(((^https?)|(^ftp))://([-w]+.)+w{2,3}(/[%-w]+(.w{2,})?)*(([w-.?\/+@&#;`~=%!]*)(.w{2,})?)*/?)/i;     // All these messages and functions are configurable     return {         /**          * The function used to validate email addresses.  Note that this is a very basic validation -- complete          * validation per the email RFC specifications is very complex and beyond the scope of this class, although          * this function can be overridden if a more comprehensive validation scheme is desired.  See the validation          * section of the <a href="http://en.wikipedia.org/wiki/E-mail_address">Wikipedia article on email addresses</a>           * for additional information.  This implementation is intended to validate the following emails:<tt>          * 'barney@example.de', 'barney.rubble@example.com', 'barney-rubble@example.coop', 'barney+rubble@example.com'          * </tt>.          * @param {String} value The email address          * @return {Boolean} true if the RegExp test passed, and false if not.          */         'email' : function(v){             return email.test(v);         },         /**          * The error text to display when the email validation function returns false.  Defaults to:          * <tt>'This field should be an e-mail address in the format "user@example.com"'</tt>          * @type String          */         'emailText' : 'This field should be an e-mail address in the format "user@example.com"',         /**          * The keystroke filter mask to be applied on email input.  See the {@link #email} method for           * information about more complex email validation. Defaults to:          * <tt>/[a-z0-9_.-@]/i</tt>          * @type RegExp          */         'emailMask' : /[a-z0-9_.-@]/i,         /**          * The function used to validate URLs          * @param {String} value The URL          * @return {Boolean} true if the RegExp test passed, and false if not.          */         'url' : function(v){             return url.test(v);         },         /**          * The error text to display when the url validation function returns false.  Defaults to:          * <tt>'This field should be a URL in the format "http:/'+'/www.example.com"'</tt>          * @type String          */         'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',                  /**          * The function used to validate alpha values          * @param {String} value The value          * @return {Boolean} true if the RegExp test passed, and false if not.          */         'alpha' : function(v){             return alpha.test(v);         },         /**          * The error text to display when the alpha validation function returns false.  Defaults to:          * <tt>'This field should only contain letters and _'</tt>          * @type String          */         'alphaText' : 'This field should only contain letters and _',         /**          * The keystroke filter mask to be applied on alpha input.  Defaults to:          * <tt>/[a-z_]/i</tt>          * @type RegExp          */         'alphaMask' : /[a-z_]/i,         /**          * The function used to validate alphanumeric values          * @param {String} value The value          * @return {Boolean} true if the RegExp test passed, and false if not.          */         'alphanum' : function(v){             return alphanum.test(v);         },         /**          * The error text to display when the alphanumeric validation function returns false.  Defaults to:          * <tt>'This field should only contain letters, numbers and _'</tt>          * @type String          */         'alphanumText' : 'This field should only contain letters, numbers and _',         /**          * The keystroke filter mask to be applied on alphanumeric input.  Defaults to:          * <tt>/[a-z0-9_]/i</tt>          * @type RegExp          */         'alphanumMask' : /[a-z0-9_]/i     }; }();