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

JavaScript

开发平台:

JavaScript

  1.             this.focus();
  2.         }
  3.     },
  4.     
  5.     autoSize : function(){
  6.         if(!this.grow || !this.rendered){
  7.             return;
  8.         }
  9.         if(!this.metrics){
  10.             this.metrics = Ext.util.TextMetrics.createInstance(this.el);
  11.         }
  12.         var el = this.el;
  13.         var v = el.dom.value;
  14.         var d = document.createElement('div');
  15.         d.appendChild(document.createTextNode(v));
  16.         v = d.innerHTML;
  17.         Ext.removeNode(d);
  18.         d = null;
  19.         v += ' ';
  20.         var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) +  10, this.growMin));
  21.         this.el.setWidth(w);
  22.         this.fireEvent('autosize', this, w);
  23.     },
  24. onDestroy: function(){
  25. if(this.validationTask){
  26. this.validationTask.cancel();
  27. this.validationTask = null;
  28. }
  29. Ext.form.TextField.superclass.onDestroy.call(this);
  30. }
  31. });
  32. Ext.reg('textfield', Ext.form.TextField);
  33. Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
  34.     
  35.     
  36.     
  37.     defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
  38.     
  39.     hideTrigger:false,
  40.     
  41.     editable: true,
  42.     
  43.     readOnly: false,
  44.     
  45.     wrapFocusClass: 'x-trigger-wrap-focus',
  46.     
  47.     autoSize: Ext.emptyFn,
  48.     
  49.     monitorTab : true,
  50.     
  51.     deferHeight : true,
  52.     
  53.     mimicing : false,
  54.     actionMode: 'wrap',
  55.     removeMode: 'container',
  56.     defaultTriggerWidth: 17,
  57.     
  58.     onResize : function(w, h){
  59.         Ext.form.TriggerField.superclass.onResize.call(this, w, h);
  60.         var tw = this.getTriggerWidth();
  61.         if(Ext.isNumber(w)){
  62.             this.el.setWidth(w - tw);
  63.         }
  64.         this.wrap.setWidth(this.el.getWidth() + tw);
  65.     },
  66.     getTriggerWidth: function(){
  67.         var tw = this.trigger.getWidth();
  68.         if(!this.hideTrigger && tw === 0){
  69.             tw = this.defaultTriggerWidth;
  70.         }
  71.         return tw;
  72.     },
  73.     
  74.     alignErrorIcon : function(){
  75.         if(this.wrap){
  76.             this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
  77.         }
  78.     },
  79.     
  80.     onRender : function(ct, position){
  81.         this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
  82.         Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
  83.         this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
  84.         this.trigger = this.wrap.createChild(this.triggerConfig ||
  85.                 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
  86.         this.initTrigger();
  87.         if(!this.width){
  88.             this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
  89.         }
  90.         this.resizeEl = this.positionEl = this.wrap;
  91.         this.updateEditState();
  92.     },
  93.     updateEditState: function(){
  94.         if(this.rendered){
  95.             if (this.readOnly) {
  96.                 this.el.dom.readOnly = true;
  97.                 this.el.addClass('x-trigger-noedit');
  98.                 this.mun(this.el, 'click', this.onTriggerClick, this);
  99.                 this.trigger.setDisplayed(false);
  100.             } else {
  101.                 if (!this.editable) {
  102.                     this.el.dom.readOnly = true;
  103.                     this.el.addClass('x-trigger-noedit');
  104.                     this.mon(this.el, 'click', this.onTriggerClick, this);
  105.                 } else {
  106.                     this.el.dom.readOnly = false;
  107.                     this.el.removeClass('x-trigger-noedit');
  108.                     this.mun(this.el, 'click', this.onTriggerClick, this);
  109.                 }
  110.                 this.trigger.setDisplayed(!this.hideTrigger);
  111.             }
  112.             this.onResize(this.width || this.wrap.getWidth());
  113.         }
  114.     },
  115.     setHideTrigger: function(hideTrigger){
  116.         if(hideTrigger != this.hideTrigger){
  117.             this.hideTrigger = hideTrigger;
  118.             this.updateEditState();
  119.         }
  120.     },
  121.     
  122.     setEditable: function(editable){
  123.         if(editable != this.editable){
  124.             this.editable = editable;
  125.             this.updateEditState();
  126.         }
  127.     },
  128.     
  129.     setReadOnly: function(readOnly){
  130.         if(readOnly != this.readOnly){
  131.             this.readOnly = readOnly;
  132.             this.updateEditState();
  133.         }
  134.     },
  135.     afterRender : function(){
  136.         Ext.form.TriggerField.superclass.afterRender.call(this);
  137.     },
  138.     
  139.     initTrigger : function(){
  140.         this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
  141.         this.trigger.addClassOnOver('x-form-trigger-over');
  142.         this.trigger.addClassOnClick('x-form-trigger-click');
  143.     },
  144.     
  145.     onDestroy : function(){
  146.         Ext.destroy(this.trigger, this.wrap);
  147.         if (this.mimicing){
  148.             this.doc.un('mousedown', this.mimicBlur, this);
  149.         }
  150.         delete this.doc;
  151.         Ext.form.TriggerField.superclass.onDestroy.call(this);
  152.     },
  153.     
  154.     onFocus : function(){
  155.         Ext.form.TriggerField.superclass.onFocus.call(this);
  156.         if(!this.mimicing){
  157.             this.wrap.addClass(this.wrapFocusClass);
  158.             this.mimicing = true;
  159.             this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});
  160.             if(this.monitorTab){
  161.                 this.on('specialkey', this.checkTab, this);
  162.             }
  163.         }
  164.     },
  165.     
  166.     checkTab : function(me, e){
  167.         if(e.getKey() == e.TAB){
  168.             this.triggerBlur();
  169.         }
  170.     },
  171.     
  172.     onBlur : Ext.emptyFn,
  173.     
  174.     mimicBlur : function(e){
  175.         if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
  176.             this.triggerBlur();
  177.         }
  178.     },
  179.     
  180.     triggerBlur : function(){
  181.         this.mimicing = false;
  182.         this.doc.un('mousedown', this.mimicBlur, this);
  183.         if(this.monitorTab && this.el){
  184.             this.un('specialkey', this.checkTab, this);
  185.         }
  186.         Ext.form.TriggerField.superclass.onBlur.call(this);
  187.         if(this.wrap){
  188.             this.wrap.removeClass(this.wrapFocusClass);
  189.         }
  190.     },
  191.     beforeBlur : Ext.emptyFn,
  192.     
  193.     
  194.     validateBlur : function(e){
  195.         return true;
  196.     },
  197.     
  198.     onTriggerClick : Ext.emptyFn
  199.     
  200.     
  201.     
  202. });
  203. Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
  204.     
  205.     
  206.     
  207.     initComponent : function(){
  208.         Ext.form.TwinTriggerField.superclass.initComponent.call(this);
  209.         this.triggerConfig = {
  210.             tag:'span', cls:'x-form-twin-triggers', cn:[
  211.             {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
  212.             {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
  213.         ]};
  214.     },
  215.     getTrigger : function(index){
  216.         return this.triggers[index];
  217.     },
  218.     initTrigger : function(){
  219.         var ts = this.trigger.select('.x-form-trigger', true);
  220.         var triggerField = this;
  221.         ts.each(function(t, all, index){
  222.             var triggerIndex = 'Trigger'+(index+1);
  223.             t.hide = function(){
  224.                 var w = triggerField.wrap.getWidth();
  225.                 this.dom.style.display = 'none';
  226.                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
  227.                 this['hidden' + triggerIndex] = true;
  228.             };
  229.             t.show = function(){
  230.                 var w = triggerField.wrap.getWidth();
  231.                 this.dom.style.display = '';
  232.                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
  233.                 this['hidden' + triggerIndex] = false;
  234.             };
  235.             if(this['hide'+triggerIndex]){
  236.                 t.dom.style.display = 'none';
  237.                 this['hidden' + triggerIndex] = true;
  238.             }
  239.             this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
  240.             t.addClassOnOver('x-form-trigger-over');
  241.             t.addClassOnClick('x-form-trigger-click');
  242.         }, this);
  243.         this.triggers = ts.elements;
  244.     },
  245.     getTriggerWidth: function(){
  246.         var tw = 0;
  247.         Ext.each(this.triggers, function(t, index){
  248.             var triggerIndex = 'Trigger' + (index + 1),
  249.                 w = t.getWidth();
  250.             if(w === 0 && !this['hidden' + triggerIndex]){
  251.                 tw += this.defaultTriggerWidth;
  252.             }else{
  253.                 tw += w;
  254.             }
  255.         }, this);
  256.         return tw;
  257.     },
  258.     
  259.     onDestroy : function() {
  260.         Ext.destroy(this.triggers);
  261.         Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
  262.     },
  263.     
  264.     onTrigger1Click : Ext.emptyFn,
  265.     
  266.     onTrigger2Click : Ext.emptyFn
  267. });
  268. Ext.reg('trigger', Ext.form.TriggerField);
  269. Ext.form.TextArea = Ext.extend(Ext.form.TextField,  {
  270.     
  271.     growMin : 60,
  272.     
  273.     growMax: 1000,
  274.     growAppend : ' n ',
  275.     enterIsSpecial : false,
  276.     
  277.     preventScrollbars: false,
  278.     
  279.     
  280.     onRender : function(ct, position){
  281.         if(!this.el){
  282.             this.defaultAutoCreate = {
  283.                 tag: "textarea",
  284.                 style:"width:100px;height:60px;",
  285.                 autocomplete: "off"
  286.             };
  287.         }
  288.         Ext.form.TextArea.superclass.onRender.call(this, ct, position);
  289.         if(this.grow){
  290.             this.textSizeEl = Ext.DomHelper.append(document.body, {
  291.                 tag: "pre", cls: "x-form-grow-sizer"
  292.             });
  293.             if(this.preventScrollbars){
  294.                 this.el.setStyle("overflow", "hidden");
  295.             }
  296.             this.el.setHeight(this.growMin);
  297.         }
  298.     },
  299.     onDestroy : function(){
  300.         Ext.removeNode(this.textSizeEl);
  301.         Ext.form.TextArea.superclass.onDestroy.call(this);
  302.     },
  303.     fireKey : function(e){
  304.         if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
  305.             this.fireEvent("specialkey", this, e);
  306.         }
  307.     },
  308.     
  309.     
  310.     doAutoSize : function(e){
  311.         return !e.isNavKeyPress() || e.getKey() == e.ENTER;
  312.     },
  313.     
  314.     autoSize: function(){
  315.         if(!this.grow || !this.textSizeEl){
  316.             return;
  317.         }
  318.         var el = this.el,
  319.             v = Ext.util.Format.htmlEncode(el.dom.value),
  320.             ts = this.textSizeEl,
  321.             h;
  322.             
  323.         Ext.fly(ts).setWidth(this.el.getWidth());
  324.         if(v.length < 1){
  325.             v = "&#160;&#160;";
  326.         }else{
  327.             v += this.growAppend;
  328.             if(Ext.isIE){
  329.                 v = v.replace(/n/g, '&#160;<br />');
  330.             }
  331.         }
  332.         ts.innerHTML = v;
  333.         h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
  334.         if(h != this.lastHeight){
  335.             this.lastHeight = h;
  336.             this.el.setHeight(h);
  337.             this.fireEvent("autosize", this, h);
  338.         }
  339.     }
  340. });
  341. Ext.reg('textarea', Ext.form.TextArea);
  342. Ext.form.NumberField = Ext.extend(Ext.form.TextField,  {
  343.     
  344.     
  345.     
  346.     fieldClass: "x-form-field x-form-num-field",
  347.     
  348.     allowDecimals : true,
  349.     
  350.     decimalSeparator : ".",
  351.     
  352.     decimalPrecision : 2,
  353.     
  354.     allowNegative : true,
  355.     
  356.     minValue : Number.NEGATIVE_INFINITY,
  357.     
  358.     maxValue : Number.MAX_VALUE,
  359.     
  360.     minText : "The minimum value for this field is {0}",
  361.     
  362.     maxText : "The maximum value for this field is {0}",
  363.     
  364.     nanText : "{0} is not a valid number",
  365.     
  366.     baseChars : "0123456789",
  367.     
  368.     initEvents : function(){
  369.         var allowed = this.baseChars + '';
  370.         if (this.allowDecimals) {
  371.             allowed += this.decimalSeparator;
  372.         }
  373.         if (this.allowNegative) {
  374.             allowed += '-';
  375.         }
  376.         this.maskRe = new RegExp('[' + Ext.escapeRe(allowed) + ']');
  377.         Ext.form.NumberField.superclass.initEvents.call(this);
  378.     },
  379.     
  380.     validateValue : function(value){
  381.         if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
  382.             return false;
  383.         }
  384.         if(value.length < 1){ 
  385.              return true;
  386.         }
  387.         value = String(value).replace(this.decimalSeparator, ".");
  388.         if(isNaN(value)){
  389.             this.markInvalid(String.format(this.nanText, value));
  390.             return false;
  391.         }
  392.         var num = this.parseValue(value);
  393.         if(num < this.minValue){
  394.             this.markInvalid(String.format(this.minText, this.minValue));
  395.             return false;
  396.         }
  397.         if(num > this.maxValue){
  398.             this.markInvalid(String.format(this.maxText, this.maxValue));
  399.             return false;
  400.         }
  401.         return true;
  402.     },
  403.     getValue : function(){
  404.         return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
  405.     },
  406.     setValue : function(v){
  407.      v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
  408.         v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
  409.         return Ext.form.NumberField.superclass.setValue.call(this, v);
  410.     },
  411.     
  412.     
  413.     setMinValue : function(value){
  414.         this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
  415.     },
  416.     
  417.     
  418.     setMaxValue : function(value){
  419.         this.maxValue = Ext.num(value, Number.MAX_VALUE);    
  420.     },
  421.     
  422.     parseValue : function(value){
  423.         value = parseFloat(String(value).replace(this.decimalSeparator, "."));
  424.         return isNaN(value) ? '' : value;
  425.     },
  426.     
  427.     fixPrecision : function(value){
  428.         var nan = isNaN(value);
  429.         if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
  430.            return nan ? '' : value;
  431.         }
  432.         return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
  433.     },
  434.     beforeBlur : function(){
  435.         var v = this.parseValue(this.getRawValue());
  436.         if(!Ext.isEmpty(v)){
  437.             this.setValue(this.fixPrecision(v));
  438.         }
  439.     }
  440. });
  441. Ext.reg('numberfield', Ext.form.NumberField);
  442. Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
  443.     
  444.     format : "m/d/Y",
  445.     
  446.     altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",
  447.     
  448.     disabledDaysText : "Disabled",
  449.     
  450.     disabledDatesText : "Disabled",
  451.     
  452.     minText : "The date in this field must be equal to or after {0}",
  453.     
  454.     maxText : "The date in this field must be equal to or before {0}",
  455.     
  456.     invalidText : "{0} is not a valid date - it must be in the format {1}",
  457.     
  458.     triggerClass : 'x-form-date-trigger',
  459.     
  460.     showToday : true,
  461.     
  462.     
  463.     
  464.     
  465.     
  466.     
  467.     defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
  468.     initComponent : function(){
  469.         Ext.form.DateField.superclass.initComponent.call(this);
  470.         this.addEvents(
  471.             
  472.             'select'
  473.         );
  474.         if(Ext.isString(this.minValue)){
  475.             this.minValue = this.parseDate(this.minValue);
  476.         }
  477.         if(Ext.isString(this.maxValue)){
  478.             this.maxValue = this.parseDate(this.maxValue);
  479.         }
  480.         this.disabledDatesRE = null;
  481.         this.initDisabledDays();
  482.     },
  483.     
  484.     initEvents: function() {
  485.         Ext.form.DateField.superclass.initEvents.call(this);
  486.         this.keyNav = new Ext.KeyNav(this.el, {
  487.             "down": function(e) {
  488.                 this.onTriggerClick();
  489.             },
  490.             scope: this,
  491.             forceKeyDown: true
  492.         });
  493.     },
  494.     
  495.     initDisabledDays : function(){
  496.         if(this.disabledDates){
  497.             var dd = this.disabledDates,
  498.                 len = dd.length - 1, 
  499.                 re = "(?:";
  500.                 
  501.             Ext.each(dd, function(d, i){
  502.                 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
  503.                 if(i != len){
  504.                     re += '|';
  505.                 }
  506.             }, this);
  507.             this.disabledDatesRE = new RegExp(re + ')');
  508.         }
  509.     },
  510.     
  511.     setDisabledDates : function(dd){
  512.         this.disabledDates = dd;
  513.         this.initDisabledDays();
  514.         if(this.menu){
  515.             this.menu.picker.setDisabledDates(this.disabledDatesRE);
  516.         }
  517.     },
  518.     
  519.     setDisabledDays : function(dd){
  520.         this.disabledDays = dd;
  521.         if(this.menu){
  522.             this.menu.picker.setDisabledDays(dd);
  523.         }
  524.     },
  525.     
  526.     setMinValue : function(dt){
  527.         this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
  528.         if(this.menu){
  529.             this.menu.picker.setMinDate(this.minValue);
  530.         }
  531.     },
  532.     
  533.     setMaxValue : function(dt){
  534.         this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
  535.         if(this.menu){
  536.             this.menu.picker.setMaxDate(this.maxValue);
  537.         }
  538.     },
  539.     
  540.     validateValue : function(value){
  541.         value = this.formatDate(value);
  542.         if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
  543.             return false;
  544.         }
  545.         if(value.length < 1){ 
  546.              return true;
  547.         }
  548.         var svalue = value;
  549.         value = this.parseDate(value);
  550.         if(!value){
  551.             this.markInvalid(String.format(this.invalidText, svalue, this.format));
  552.             return false;
  553.         }
  554.         var time = value.getTime();
  555.         if(this.minValue && time < this.minValue.getTime()){
  556.             this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
  557.             return false;
  558.         }
  559.         if(this.maxValue && time > this.maxValue.getTime()){
  560.             this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
  561.             return false;
  562.         }
  563.         if(this.disabledDays){
  564.             var day = value.getDay();
  565.             for(var i = 0; i < this.disabledDays.length; i++) {
  566.                 if(day === this.disabledDays[i]){
  567.                     this.markInvalid(this.disabledDaysText);
  568.                     return false;
  569.                 }
  570.             }
  571.         }
  572.         var fvalue = this.formatDate(value);
  573.         if(this.disabledDatesRE && this.disabledDatesRE.test(fvalue)){
  574.             this.markInvalid(String.format(this.disabledDatesText, fvalue));
  575.             return false;
  576.         }
  577.         return true;
  578.     },
  579.     
  580.     
  581.     validateBlur : function(){
  582.         return !this.menu || !this.menu.isVisible();
  583.     },
  584.     
  585.     getValue : function(){
  586.         return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
  587.     },
  588.     
  589.     setValue : function(date){
  590.         return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
  591.     },
  592.     
  593.     parseDate : function(value){
  594.         if(!value || Ext.isDate(value)){
  595.             return value;
  596.         }
  597.         var v = Date.parseDate(value, this.format);
  598.         if(!v && this.altFormats){
  599.             if(!this.altFormatsArray){
  600.                 this.altFormatsArray = this.altFormats.split("|");
  601.             }
  602.             for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
  603.                 v = Date.parseDate(value, this.altFormatsArray[i]);
  604.             }
  605.         }
  606.         return v;
  607.     },
  608.     
  609.     onDestroy : function(){
  610. Ext.destroy(this.menu, this.keyNav);
  611.         Ext.form.DateField.superclass.onDestroy.call(this);
  612.     },
  613.     
  614.     formatDate : function(date){
  615.         return Ext.isDate(date) ? date.dateFormat(this.format) : date;
  616.     },
  617.     
  618.     
  619.     
  620.     onTriggerClick : function(){
  621.         if(this.disabled){
  622.             return;
  623.         }
  624.         if(this.menu == null){
  625.             this.menu = new Ext.menu.DateMenu({
  626.                 hideOnClick: false,
  627.                 focusOnSelect: false
  628.             });
  629.         }
  630.         this.onFocus();
  631.         Ext.apply(this.menu.picker,  {
  632.             minDate : this.minValue,
  633.             maxDate : this.maxValue,
  634.             disabledDatesRE : this.disabledDatesRE,
  635.             disabledDatesText : this.disabledDatesText,
  636.             disabledDays : this.disabledDays,
  637.             disabledDaysText : this.disabledDaysText,
  638.             format : this.format,
  639.             showToday : this.showToday,
  640.             minText : String.format(this.minText, this.formatDate(this.minValue)),
  641.             maxText : String.format(this.maxText, this.formatDate(this.maxValue))
  642.         });
  643.         this.menu.picker.setValue(this.getValue() || new Date());
  644.         this.menu.show(this.el, "tl-bl?");
  645.         this.menuEvents('on');
  646.     },
  647.     
  648.     
  649.     menuEvents: function(method){
  650.         this.menu[method]('select', this.onSelect, this);
  651.         this.menu[method]('hide', this.onMenuHide, this);
  652.         this.menu[method]('show', this.onFocus, this);
  653.     },
  654.     
  655.     onSelect: function(m, d){
  656.         this.setValue(d);
  657.         this.fireEvent('select', this, d);
  658.         this.menu.hide();
  659.     },
  660.     
  661.     onMenuHide: function(){
  662.         this.focus(false, 60);
  663.         this.menuEvents('un');
  664.     },
  665.     
  666.     beforeBlur : function(){
  667.         var v = this.parseDate(this.getRawValue());
  668.         if(v){
  669.             this.setValue(v);
  670.         }
  671.     }
  672.     
  673.     
  674.     
  675.     
  676. });
  677. Ext.reg('datefield', Ext.form.DateField);
  678. Ext.form.DisplayField = Ext.extend(Ext.form.Field,  {
  679.     validationEvent : false,
  680.     validateOnBlur : false,
  681.     defaultAutoCreate : {tag: "div"},
  682.     
  683.     fieldClass : "x-form-display-field",
  684.     
  685.     htmlEncode: false,
  686.     
  687.     initEvents : Ext.emptyFn,
  688.     isValid : function(){
  689.         return true;
  690.     },
  691.     validate : function(){
  692.         return true;
  693.     },
  694.     getRawValue : function(){
  695.         var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
  696.         if(v === this.emptyText){
  697.             v = '';
  698.         }
  699.         if(this.htmlEncode){
  700.             v = Ext.util.Format.htmlDecode(v);
  701.         }
  702.         return v;
  703.     },
  704.     getValue : function(){
  705.         return this.getRawValue();
  706.     },
  707.     
  708.     getName: function() {
  709.         return this.name;
  710.     },
  711.     setRawValue : function(v){
  712.         if(this.htmlEncode){
  713.             v = Ext.util.Format.htmlEncode(v);
  714.         }
  715.         return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
  716.     },
  717.     setValue : function(v){
  718.         this.setRawValue(v);
  719.         return this;
  720.     }
  721.     
  722.     
  723.     
  724.     
  725.     
  726.     
  727. });
  728. Ext.reg('displayfield', Ext.form.DisplayField);
  729. Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
  730.     
  731.     
  732.     
  733.     
  734.     
  735.     
  736.     defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
  737.     
  738.     
  739.     
  740.     
  741.     
  742.     
  743.     
  744.     listClass : '',
  745.     
  746.     selectedClass : 'x-combo-selected',
  747.     
  748.     listEmptyText: '',
  749.     
  750.     triggerClass : 'x-form-arrow-trigger',
  751.     
  752.     shadow : 'sides',
  753.     
  754.     listAlign : 'tl-bl?',
  755.     
  756.     maxHeight : 300,
  757.     
  758.     minHeight : 90,
  759.     
  760.     triggerAction : 'query',
  761.     
  762.     minChars : 4,
  763.     
  764.     typeAhead : false,
  765.     
  766.     queryDelay : 500,
  767.     
  768.     pageSize : 0,
  769.     
  770.     selectOnFocus : false,
  771.     
  772.     queryParam : 'query',
  773.     
  774.     loadingText : 'Loading...',
  775.     
  776.     resizable : false,
  777.     
  778.     handleHeight : 8,
  779.     
  780.     allQuery: '',
  781.     
  782.     mode: 'remote',
  783.     
  784.     minListWidth : 70,
  785.     
  786.     forceSelection : false,
  787.     
  788.     typeAheadDelay : 250,
  789.     
  790.     
  791.     lazyInit : true,
  792.     
  793.     clearFilterOnReset : true,
  794.     
  795.     submitValue: undefined,
  796.     
  797.     
  798.     initComponent : function(){
  799.         Ext.form.ComboBox.superclass.initComponent.call(this);
  800.         this.addEvents(
  801.             
  802.             'expand',
  803.             
  804.             'collapse',
  805.             
  806.             'beforeselect',
  807.             
  808.             'select',
  809.             
  810.             'beforequery'
  811.         );
  812.         if(this.transform){
  813.             var s = Ext.getDom(this.transform);
  814.             if(!this.hiddenName){
  815.                 this.hiddenName = s.name;
  816.             }
  817.             if(!this.store){
  818.                 this.mode = 'local';
  819.                 var d = [], opts = s.options;
  820.                 for(var i = 0, len = opts.length;i < len; i++){
  821.                     var o = opts[i],
  822.                         value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
  823.                     if(o.selected && Ext.isEmpty(this.value, true)) {
  824.                         this.value = value;
  825.                     }
  826.                     d.push([value, o.text]);
  827.                 }
  828.                 this.store = new Ext.data.ArrayStore({
  829.                     'id': 0,
  830.                     fields: ['value', 'text'],
  831.                     data : d,
  832.                     autoDestroy: true
  833.                 });
  834.                 this.valueField = 'value';
  835.                 this.displayField = 'text';
  836.             }
  837.             s.name = Ext.id(); 
  838.             if(!this.lazyRender){
  839.                 this.target = true;
  840.                 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
  841.                 this.render(this.el.parentNode, s);
  842.             }
  843.             Ext.removeNode(s);
  844.         }
  845.         
  846.         else if(this.store){
  847.             this.store = Ext.StoreMgr.lookup(this.store);
  848.             if(this.store.autoCreated){
  849.                 this.displayField = this.valueField = 'field1';
  850.                 if(!this.store.expandData){
  851.                     this.displayField = 'field2';
  852.                 }
  853.                 this.mode = 'local';
  854.             }
  855.         }
  856.         this.selectedIndex = -1;
  857.         if(this.mode == 'local'){
  858.             if(!Ext.isDefined(this.initialConfig.queryDelay)){
  859.                 this.queryDelay = 10;
  860.             }
  861.             if(!Ext.isDefined(this.initialConfig.minChars)){
  862.                 this.minChars = 0;
  863.             }
  864.         }
  865.     },
  866.     
  867.     onRender : function(ct, position){
  868.         if(this.hiddenName && !Ext.isDefined(this.submitValue)){
  869.             this.submitValue = false;
  870.         }
  871.         Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
  872.         if(this.hiddenName){
  873.             this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
  874.                     id: (this.hiddenId||this.hiddenName)}, 'before', true);
  875.         }
  876.         if(Ext.isGecko){
  877.             this.el.dom.setAttribute('autocomplete', 'off');
  878.         }
  879.         if(!this.lazyInit){
  880.             this.initList();
  881.         }else{
  882.             this.on('focus', this.initList, this, {single: true});
  883.         }
  884.     },
  885.     
  886.     initValue : function(){
  887.         Ext.form.ComboBox.superclass.initValue.call(this);
  888.         if(this.hiddenField){
  889.             this.hiddenField.value =
  890.                 Ext.isDefined(this.hiddenValue) ? this.hiddenValue :
  891.                 Ext.isDefined(this.value) ? this.value : '';
  892.         }
  893.     },
  894.     
  895.     initList : function(){
  896.         if(!this.list){
  897.             var cls = 'x-combo-list';
  898.             this.list = new Ext.Layer({
  899.                 parentEl: this.getListParent(),
  900.                 shadow: this.shadow,
  901.                 cls: [cls, this.listClass].join(' '),
  902.                 constrain:false,
  903.                 zindex: 12000
  904.             });
  905.             var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
  906.             this.list.setSize(lw, 0);
  907.             this.list.swallowEvent('mousewheel');
  908.             this.assetHeight = 0;
  909.             if(this.syncFont !== false){
  910.                 this.list.setStyle('font-size', this.el.getStyle('font-size'));
  911.             }
  912.             if(this.title){
  913.                 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
  914.                 this.assetHeight += this.header.getHeight();
  915.             }
  916.             this.innerList = this.list.createChild({cls:cls+'-inner'});
  917.             this.mon(this.innerList, 'mouseover', this.onViewOver, this);
  918.             this.mon(this.innerList, 'mousemove', this.onViewMove, this);
  919.             this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
  920.             if(this.pageSize){
  921.                 this.footer = this.list.createChild({cls:cls+'-ft'});
  922.                 this.pageTb = new Ext.PagingToolbar({
  923.                     store: this.store,
  924.                     pageSize: this.pageSize,
  925.                     renderTo:this.footer
  926.                 });
  927.                 this.assetHeight += this.footer.getHeight();
  928.             }
  929.             if(!this.tpl){
  930.                 
  931.                 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
  932.                 
  933.             }
  934.             
  935.             this.view = new Ext.DataView({
  936.                 applyTo: this.innerList,
  937.                 tpl: this.tpl,
  938.                 singleSelect: true,
  939.                 selectedClass: this.selectedClass,
  940.                 itemSelector: this.itemSelector || '.' + cls + '-item',
  941.                 emptyText: this.listEmptyText
  942.             });
  943.             this.mon(this.view, 'click', this.onViewClick, this);
  944.             this.bindStore(this.store, true);
  945.             if(this.resizable){
  946.                 this.resizer = new Ext.Resizable(this.list,  {
  947.                    pinned:true, handles:'se'
  948.                 });
  949.                 this.mon(this.resizer, 'resize', function(r, w, h){
  950.                     this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
  951.                     this.listWidth = w;
  952.                     this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
  953.                     this.restrictHeight();
  954.                 }, this);
  955.                 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
  956.             }
  957.         }
  958.     },
  959.     
  960.     getListParent : function() {
  961.         return document.body;
  962.     },
  963.     
  964.     getStore : function(){
  965.         return this.store;
  966.     },
  967.     
  968.     bindStore : function(store, initial){
  969.         if(this.store && !initial){
  970.             if(this.store !== store && this.store.autoDestroy){
  971.                 this.store.destroy();
  972.             }else{
  973.                 this.store.un('beforeload', this.onBeforeLoad, this);
  974.                 this.store.un('load', this.onLoad, this);
  975.                 this.store.un('exception', this.collapse, this);
  976.             }
  977.             if(!store){
  978.                 this.store = null;
  979.                 if(this.view){
  980.                     this.view.bindStore(null);
  981.                 }
  982.                 if(this.pageTb){
  983.                     this.pageTb.bindStore(null);
  984.                 }
  985.             }
  986.         }
  987.         if(store){
  988.             if(!initial) {
  989.                 this.lastQuery = null;
  990.                 if(this.pageTb) {
  991.                     this.pageTb.bindStore(store);
  992.                 }
  993.             }
  994.             this.store = Ext.StoreMgr.lookup(store);
  995.             this.store.on({
  996.                 scope: this,
  997.                 beforeload: this.onBeforeLoad,
  998.                 load: this.onLoad,
  999.                 exception: this.collapse
  1000.             });
  1001.             if(this.view){
  1002.                 this.view.bindStore(store);
  1003.             }
  1004.         }
  1005.     },
  1006.     reset : function(){
  1007.         Ext.form.ComboBox.superclass.reset.call(this);
  1008.         if(this.clearFilterOnReset && this.mode == 'local'){
  1009.             this.store.clearFilter();
  1010.         }
  1011.     },
  1012.     
  1013.     initEvents : function(){
  1014.         Ext.form.ComboBox.superclass.initEvents.call(this);
  1015.         this.keyNav = new Ext.KeyNav(this.el, {
  1016.             "up" : function(e){
  1017.                 this.inKeyMode = true;
  1018.                 this.selectPrev();
  1019.             },
  1020.             "down" : function(e){
  1021.                 if(!this.isExpanded()){
  1022.                     this.onTriggerClick();
  1023.                 }else{
  1024.                     this.inKeyMode = true;
  1025.                     this.selectNext();
  1026.                 }
  1027.             },
  1028.             "enter" : function(e){
  1029.                 this.onViewClick();
  1030.             },
  1031.             "esc" : function(e){
  1032.                 this.collapse();
  1033.             },
  1034.             "tab" : function(e){
  1035.                 this.onViewClick(false);
  1036.                 return true;
  1037.             },
  1038.             scope : this,
  1039.             doRelay : function(e, h, hname){
  1040.                 if(hname == 'down' || this.scope.isExpanded()){
  1041.                     
  1042.                     var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
  1043.                     if(!Ext.isIE && Ext.EventManager.useKeydown){
  1044.                         
  1045.                         this.scope.fireKey(e);
  1046.                     }
  1047.                     return relay;
  1048.                 }
  1049.                 return true;
  1050.             },
  1051.             forceKeyDown : true,
  1052.             defaultEventAction: 'stopEvent'
  1053.         });
  1054.         this.queryDelay = Math.max(this.queryDelay || 10,
  1055.                 this.mode == 'local' ? 10 : 250);
  1056.         this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
  1057.         if(this.typeAhead){
  1058.             this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
  1059.         }
  1060.         if(!this.enableKeyEvents){
  1061.             this.mon(this.el, 'keyup', this.onKeyUp, this);
  1062.         }
  1063.     },
  1064.     
  1065.     onDestroy : function(){
  1066.         if (this.dqTask){
  1067.             this.dqTask.cancel();
  1068.             this.dqTask = null;
  1069.         }
  1070.         this.bindStore(null);
  1071.         Ext.destroy(
  1072.             this.resizer,
  1073.             this.view,
  1074.             this.pageTb,
  1075.             this.list
  1076.         );
  1077.         Ext.destroyMembers(this, 'hiddenField');
  1078.         Ext.form.ComboBox.superclass.onDestroy.call(this);
  1079.     },
  1080.     
  1081.     fireKey : function(e){
  1082.         if (!this.isExpanded()) {
  1083.             Ext.form.ComboBox.superclass.fireKey.call(this, e);
  1084.         }
  1085.     },
  1086.     
  1087.     onResize : function(w, h){
  1088.         Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
  1089.         if(this.isVisible() && this.list){
  1090.             this.doResize(w);
  1091.         }else{
  1092.             this.bufferSize = w;
  1093.         }
  1094.     },
  1095.     doResize: function(w){
  1096.         if(!Ext.isDefined(this.listWidth)){
  1097.             var lw = Math.max(w, this.minListWidth);
  1098.             this.list.setWidth(lw);
  1099.             this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
  1100.         }
  1101.     },
  1102.     
  1103.     onEnable : function(){
  1104.         Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
  1105.         if(this.hiddenField){
  1106.             this.hiddenField.disabled = false;
  1107.         }
  1108.     },
  1109.     
  1110.     onDisable : function(){
  1111.         Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
  1112.         if(this.hiddenField){
  1113.             this.hiddenField.disabled = true;
  1114.         }
  1115.     },
  1116.     
  1117.     onBeforeLoad : function(){
  1118.         if(!this.hasFocus){
  1119.             return;
  1120.         }
  1121.         this.innerList.update(this.loadingText ?
  1122.                '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
  1123.         this.restrictHeight();
  1124.         this.selectedIndex = -1;
  1125.     },
  1126.     
  1127.     onLoad : function(){
  1128.         if(!this.hasFocus){
  1129.             return;
  1130.         }
  1131.         if(this.store.getCount() > 0 || this.listEmptyText){
  1132.             this.expand();
  1133.             this.restrictHeight();
  1134.             if(this.lastQuery == this.allQuery){
  1135.                 if(this.editable){
  1136.                     this.el.dom.select();
  1137.                 }
  1138.                 if(!this.selectByValue(this.value, true)){
  1139.                     this.select(0, true);
  1140.                 }
  1141.             }else{
  1142.                 this.selectNext();
  1143.                 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
  1144.                     this.taTask.delay(this.typeAheadDelay);
  1145.                 }
  1146.             }
  1147.         }else{
  1148.             this.onEmptyResults();
  1149.         }
  1150.         
  1151.     },
  1152.     
  1153.     onTypeAhead : function(){
  1154.         if(this.store.getCount() > 0){
  1155.             var r = this.store.getAt(0);
  1156.             var newValue = r.data[this.displayField];
  1157.             var len = newValue.length;
  1158.             var selStart = this.getRawValue().length;
  1159.             if(selStart != len){
  1160.                 this.setRawValue(newValue);
  1161.                 this.selectText(selStart, newValue.length);
  1162.             }
  1163.         }
  1164.     },
  1165.     
  1166.     onSelect : function(record, index){
  1167.         if(this.fireEvent('beforeselect', this, record, index) !== false){
  1168.             this.setValue(record.data[this.valueField || this.displayField]);
  1169.             this.collapse();
  1170.             this.fireEvent('select', this, record, index);
  1171.         }
  1172.     },
  1173.     
  1174.     getName: function(){
  1175.         var hf = this.hiddenField;
  1176.         return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
  1177.     },
  1178.     
  1179.     getValue : function(){
  1180.         if(this.valueField){
  1181.             return Ext.isDefined(this.value) ? this.value : '';
  1182.         }else{
  1183.             return Ext.form.ComboBox.superclass.getValue.call(this);
  1184.         }
  1185.     },
  1186.     
  1187.     clearValue : function(){
  1188.         if(this.hiddenField){
  1189.             this.hiddenField.value = '';
  1190.         }
  1191.         this.setRawValue('');
  1192.         this.lastSelectionText = '';
  1193.         this.applyEmptyText();
  1194.         this.value = '';
  1195.     },
  1196.     
  1197.     setValue : function(v){
  1198.         var text = v;
  1199.         if(this.valueField){
  1200.             var r = this.findRecord(this.valueField, v);
  1201.             if(r){
  1202.                 text = r.data[this.displayField];
  1203.             }else if(Ext.isDefined(this.valueNotFoundText)){
  1204.                 text = this.valueNotFoundText;
  1205.             }
  1206.         }
  1207.         this.lastSelectionText = text;
  1208.         if(this.hiddenField){
  1209.             this.hiddenField.value = v;
  1210.         }
  1211.         Ext.form.ComboBox.superclass.setValue.call(this, text);
  1212.         this.value = v;
  1213.         return this;
  1214.     },
  1215.     
  1216.     findRecord : function(prop, value){
  1217.         var record;
  1218.         if(this.store.getCount() > 0){
  1219.             this.store.each(function(r){
  1220.                 if(r.data[prop] == value){
  1221.                     record = r;
  1222.                     return false;
  1223.                 }
  1224.             });
  1225.         }
  1226.         return record;
  1227.     },
  1228.     
  1229.     onViewMove : function(e, t){
  1230.         this.inKeyMode = false;
  1231.     },
  1232.     
  1233.     onViewOver : function(e, t){
  1234.         if(this.inKeyMode){ 
  1235.             return;
  1236.         }
  1237.         var item = this.view.findItemFromChild(t);
  1238.         if(item){
  1239.             var index = this.view.indexOf(item);
  1240.             this.select(index, false);
  1241.         }
  1242.     },
  1243.     
  1244.     onViewClick : function(doFocus){
  1245.         var index = this.view.getSelectedIndexes()[0],
  1246.             s = this.store,
  1247.             r = s.getAt(index);
  1248.         if(r){
  1249.             this.onSelect(r, index);
  1250.         }else if(s.getCount() === 0){
  1251.             this.onEmptyResults();
  1252.         }
  1253.         if(doFocus !== false){
  1254.             this.el.focus();
  1255.         }
  1256.     },
  1257.     
  1258.     restrictHeight : function(){
  1259.         this.innerList.dom.style.height = '';
  1260.         var inner = this.innerList.dom,
  1261.             pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
  1262.             h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
  1263.             ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
  1264.             hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
  1265.             space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
  1266.         h = Math.min(h, space, this.maxHeight);
  1267.         this.innerList.setHeight(h);
  1268.         this.list.beginUpdate();
  1269.         this.list.setHeight(h+pad);
  1270.         this.list.alignTo(this.wrap, this.listAlign);
  1271.         this.list.endUpdate();
  1272.     },
  1273.     
  1274.     onEmptyResults : function(){
  1275.         this.collapse();
  1276.     },
  1277.     
  1278.     isExpanded : function(){
  1279.         return this.list && this.list.isVisible();
  1280.     },
  1281.     
  1282.     selectByValue : function(v, scrollIntoView){
  1283.         if(!Ext.isEmpty(v, true)){
  1284.             var r = this.findRecord(this.valueField || this.displayField, v);
  1285.             if(r){
  1286.                 this.select(this.store.indexOf(r), scrollIntoView);
  1287.                 return true;
  1288.             }
  1289.         }
  1290.         return false;
  1291.     },
  1292.     
  1293.     select : function(index, scrollIntoView){
  1294.         this.selectedIndex = index;
  1295.         this.view.select(index);
  1296.         if(scrollIntoView !== false){
  1297.             var el = this.view.getNode(index);
  1298.             if(el){
  1299.                 this.innerList.scrollChildIntoView(el, false);
  1300.             }
  1301.         }
  1302.     },
  1303.     
  1304.     selectNext : function(){
  1305.         var ct = this.store.getCount();
  1306.         if(ct > 0){
  1307.             if(this.selectedIndex == -1){
  1308.                 this.select(0);
  1309.             }else if(this.selectedIndex < ct-1){
  1310.                 this.select(this.selectedIndex+1);
  1311.             }
  1312.         }
  1313.     },
  1314.     
  1315.     selectPrev : function(){
  1316.         var ct = this.store.getCount();
  1317.         if(ct > 0){
  1318.             if(this.selectedIndex == -1){
  1319.                 this.select(0);
  1320.             }else if(this.selectedIndex !== 0){
  1321.                 this.select(this.selectedIndex-1);
  1322.             }
  1323.         }
  1324.     },
  1325.     
  1326.     onKeyUp : function(e){
  1327.         var k = e.getKey();
  1328.         if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
  1329.             this.lastKey = k;
  1330.             this.dqTask.delay(this.queryDelay);
  1331.         }
  1332.         Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
  1333.     },
  1334.     
  1335.     validateBlur : function(){
  1336.         return !this.list || !this.list.isVisible();
  1337.     },
  1338.     
  1339.     initQuery : function(){
  1340.         this.doQuery(this.getRawValue());
  1341.     },
  1342.     
  1343.     beforeBlur : function(){
  1344.         var val = this.getRawValue(),
  1345.             rec = this.findRecord(this.displayField, val);
  1346.         if(!rec && this.forceSelection){
  1347.             if(val.length > 0 && val != this.emptyText){
  1348.                 this.el.dom.value = Ext.isEmpty(this.lastSelectionText) ? '' : this.lastSelectionText;
  1349.                 this.applyEmptyText();
  1350.             }else{
  1351.                 this.clearValue();
  1352.             }
  1353.         }else{
  1354.             if(rec){
  1355.                 val = rec.get(this.valueField || this.displayField);
  1356.             }
  1357.             this.setValue(val);
  1358.         }
  1359.     },
  1360.     
  1361.     doQuery : function(q, forceAll){
  1362.         q = Ext.isEmpty(q) ? '' : q;
  1363.         var qe = {
  1364.             query: q,
  1365.             forceAll: forceAll,
  1366.             combo: this,
  1367.             cancel:false
  1368.         };
  1369.         if(this.fireEvent('beforequery', qe)===false || qe.cancel){
  1370.             return false;
  1371.         }
  1372.         q = qe.query;
  1373.         forceAll = qe.forceAll;
  1374.         if(forceAll === true || (q.length >= this.minChars)){
  1375.             if(this.lastQuery !== q){
  1376.                 this.lastQuery = q;
  1377.                 if(this.mode == 'local'){
  1378.                     this.selectedIndex = -1;
  1379.                     if(forceAll){
  1380.                         this.store.clearFilter();
  1381.                     }else{
  1382.                         this.store.filter(this.displayField, q);
  1383.                     }
  1384.                     this.onLoad();
  1385.                 }else{
  1386.                     this.store.baseParams[this.queryParam] = q;
  1387.                     this.store.load({
  1388.                         params: this.getParams(q)
  1389.                     });
  1390.                     this.expand();
  1391.                 }
  1392.             }else{
  1393.                 this.selectedIndex = -1;
  1394.                 this.onLoad();
  1395.             }
  1396.         }
  1397.     },
  1398.     
  1399.     getParams : function(q){
  1400.         var p = {};
  1401.         
  1402.         if(this.pageSize){
  1403.             p.start = 0;
  1404.             p.limit = this.pageSize;
  1405.         }
  1406.         return p;
  1407.     },
  1408.     
  1409.     collapse : function(){
  1410.         if(!this.isExpanded()){
  1411.             return;
  1412.         }
  1413.         this.list.hide();
  1414.         Ext.getDoc().un('mousewheel', this.collapseIf, this);
  1415.         Ext.getDoc().un('mousedown', this.collapseIf, this);
  1416.         this.fireEvent('collapse', this);
  1417.     },
  1418.     
  1419.     collapseIf : function(e){
  1420.         if(!e.within(this.wrap) && !e.within(this.list)){
  1421.             this.collapse();
  1422.         }
  1423.     },
  1424.     
  1425.     expand : function(){
  1426.         if(this.isExpanded() || !this.hasFocus){
  1427.             return;
  1428.         }
  1429.         if(this.bufferSize){
  1430.             this.doResize(this.bufferSize);
  1431.             delete this.bufferSize;
  1432.         }
  1433.         this.list.alignTo(this.wrap, this.listAlign);
  1434.         this.list.show();
  1435.         if(Ext.isGecko2){
  1436.             this.innerList.setOverflow('auto'); 
  1437.         }
  1438.         this.mon(Ext.getDoc(), {
  1439.             scope: this,
  1440.             mousewheel: this.collapseIf,
  1441.             mousedown: this.collapseIf
  1442.         });
  1443.         this.fireEvent('expand', this);
  1444.     },
  1445.     
  1446.     
  1447.     
  1448.     onTriggerClick : function(){
  1449.         if(this.readOnly || this.disabled){
  1450.             return;
  1451.         }
  1452.         if(this.isExpanded()){
  1453.             this.collapse();
  1454.             this.el.focus();
  1455.         }else {
  1456.             this.onFocus({});
  1457.             if(this.triggerAction == 'all') {
  1458.                 this.doQuery(this.allQuery, true);
  1459.             } else {
  1460.                 this.doQuery(this.getRawValue());
  1461.             }
  1462.             this.el.focus();
  1463.         }
  1464.     }
  1465.     
  1466.     
  1467.     
  1468.     
  1469. });
  1470. Ext.reg('combo', Ext.form.ComboBox);
  1471. Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
  1472.     
  1473.     focusClass : undefined,
  1474.     
  1475.     fieldClass : 'x-form-field',
  1476.     
  1477.     checked : false,
  1478.     
  1479.     defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
  1480.     
  1481.     
  1482.     
  1483.     
  1484.     
  1485.     actionMode : 'wrap',
  1486.     
  1487.     initComponent : function(){
  1488.         Ext.form.Checkbox.superclass.initComponent.call(this);
  1489.         this.addEvents(
  1490.             
  1491.             'check'
  1492.         );
  1493.     },
  1494.     
  1495.     onResize : function(){
  1496.         Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
  1497.         if(!this.boxLabel && !this.fieldLabel){
  1498.             this.el.alignTo(this.wrap, 'c-c');
  1499.         }
  1500.     },
  1501.     
  1502.     initEvents : function(){
  1503.         Ext.form.Checkbox.superclass.initEvents.call(this);
  1504.         this.mon(this.el, {
  1505.             scope: this,
  1506.             click: this.onClick,
  1507.             change: this.onClick
  1508.         });
  1509.     },
  1510.     
  1511.     markInvalid : Ext.emptyFn,
  1512.     
  1513.     clearInvalid : Ext.emptyFn,
  1514.     
  1515.     onRender : function(ct, position){
  1516.         Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
  1517.         if(this.inputValue !== undefined){
  1518.             this.el.dom.value = this.inputValue;
  1519.         }
  1520.         this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
  1521.         if(this.boxLabel){
  1522.             this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
  1523.         }
  1524.         if(this.checked){
  1525.             this.setValue(true);
  1526.         }else{
  1527.             this.checked = this.el.dom.checked;
  1528.         }
  1529.         
  1530.         if(Ext.isIE){
  1531.             this.wrap.repaint();
  1532.         }
  1533.         this.resizeEl = this.positionEl = this.wrap;
  1534.     },
  1535.     
  1536.     onDestroy : function(){
  1537.         Ext.destroy(this.wrap);
  1538.         Ext.form.Checkbox.superclass.onDestroy.call(this);
  1539.     },
  1540.     
  1541.     initValue : function() {
  1542.         this.originalValue = this.getValue();
  1543.     },
  1544.     
  1545.     getValue : function(){
  1546.         if(this.rendered){
  1547.             return this.el.dom.checked;
  1548.         }
  1549.         return this.checked;
  1550.     },
  1551.     onClick : function(){
  1552.         if(this.el.dom.checked != this.checked){
  1553.             this.setValue(this.el.dom.checked);
  1554.         }
  1555.     },
  1556.     
  1557.     setValue : function(v){
  1558.         var checked = this.checked ;
  1559.         this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
  1560.         if(this.rendered){
  1561.             this.el.dom.checked = this.checked;
  1562.             this.el.dom.defaultChecked = this.checked;
  1563.         }
  1564.         if(checked != this.checked){
  1565.             this.fireEvent('check', this, this.checked);
  1566.             if(this.handler){
  1567.                 this.handler.call(this.scope || this, this, this.checked);
  1568.             }
  1569.         }
  1570.         return this;
  1571.     }
  1572. });
  1573. Ext.reg('checkbox', Ext.form.Checkbox);
  1574. Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
  1575.     
  1576.     
  1577.     columns : 'auto',
  1578.     
  1579.     vertical : false,
  1580.     
  1581.     allowBlank : true,
  1582.     
  1583.     blankText : "You must select at least one item in this group",
  1584.     
  1585.     defaultType : 'checkbox',
  1586.     
  1587.     groupCls : 'x-form-check-group',
  1588.     
  1589.     initComponent: function(){
  1590.         this.addEvents(
  1591.             
  1592.             'change'
  1593.         );
  1594.         this.on('change', this.validate, this);
  1595.         Ext.form.CheckboxGroup.superclass.initComponent.call(this);
  1596.     },
  1597.     
  1598.     onRender : function(ct, position){
  1599.         if(!this.el){
  1600.             var panelCfg = {
  1601.                 autoEl: {
  1602.                     id: this.id
  1603.                 },
  1604.                 cls: this.groupCls,
  1605.                 layout: 'column',
  1606.                 renderTo: ct,
  1607.                 bufferResize: false 
  1608.             };
  1609.             var colCfg = {
  1610.                 xtype: 'container',
  1611.                 defaultType: this.defaultType,
  1612.                 layout: 'form',
  1613.                 defaults: {
  1614.                     hideLabel: true,
  1615.                     anchor: '100%'
  1616.                 }
  1617.             };
  1618.             if(this.items[0].items){
  1619.                 
  1620.                 Ext.apply(panelCfg, {
  1621.                     layoutConfig: {columns: this.items.length},
  1622.                     defaults: this.defaults,
  1623.                     items: this.items
  1624.                 });
  1625.                 for(var i=0, len=this.items.length; i<len; i++){
  1626.                     Ext.applyIf(this.items[i], colCfg);
  1627.                 }
  1628.             }else{
  1629.                 
  1630.                 
  1631.                 var numCols, cols = [];
  1632.                 if(typeof this.columns == 'string'){ 
  1633.                     this.columns = this.items.length;
  1634.                 }
  1635.                 if(!Ext.isArray(this.columns)){
  1636.                     var cs = [];
  1637.                     for(var i=0; i<this.columns; i++){
  1638.                         cs.push((100/this.columns)*.01); 
  1639.                     }
  1640.                     this.columns = cs;
  1641.                 }
  1642.                 numCols = this.columns.length;
  1643.                 
  1644.                 for(var i=0; i<numCols; i++){
  1645.                     var cc = Ext.apply({items:[]}, colCfg);
  1646.                     cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
  1647.                     if(this.defaults){
  1648.                         cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)
  1649.                     }
  1650.                     cols.push(cc);
  1651.                 };
  1652.                 
  1653.                 if(this.vertical){
  1654.                     var rows = Math.ceil(this.items.length / numCols), ri = 0;
  1655.                     for(var i=0, len=this.items.length; i<len; i++){
  1656.                         if(i>0 && i%rows==0){
  1657.                             ri++;
  1658.                         }
  1659.                         if(this.items[i].fieldLabel){
  1660.                             this.items[i].hideLabel = false;
  1661.                         }
  1662.                         cols[ri].items.push(this.items[i]);
  1663.                     };
  1664.                 }else{
  1665.                     for(var i=0, len=this.items.length; i<len; i++){
  1666.                         var ci = i % numCols;
  1667.                         if(this.items[i].fieldLabel){
  1668.                             this.items[i].hideLabel = false;
  1669.                         }
  1670.                         cols[ci].items.push(this.items[i]);
  1671.                     };
  1672.                 }
  1673.                 Ext.apply(panelCfg, {
  1674.                     layoutConfig: {columns: numCols},
  1675.                     items: cols
  1676.                 });
  1677.             }
  1678.             this.panel = new Ext.Container(panelCfg);
  1679.             this.panel.ownerCt = this;
  1680.             this.el = this.panel.getEl();
  1681.             if(this.forId && this.itemCls){
  1682.                 var l = this.el.up(this.itemCls).child('label', true);
  1683.                 if(l){
  1684.                     l.setAttribute('htmlFor', this.forId);
  1685.                 }
  1686.             }
  1687.             var fields = this.panel.findBy(function(c){
  1688.                 return c.isFormField;
  1689.             }, this);
  1690.             this.items = new Ext.util.MixedCollection();
  1691.             this.items.addAll(fields);
  1692.         }
  1693.         Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
  1694.     },
  1695.     initValue : function(){
  1696.         if(this.value){
  1697.             this.setValue.apply(this, this.buffered ? this.value : [this.value]);
  1698.             delete this.buffered;
  1699.             delete this.value;
  1700.         }
  1701.     },
  1702.     afterRender : function(){
  1703.         Ext.form.CheckboxGroup.superclass.afterRender.call(this);
  1704.         this.eachItem(function(item){
  1705.             item.on('check', this.fireChecked, this);
  1706.             item.inGroup = true;
  1707.         });
  1708.     },
  1709.     
  1710.     doLayout: function(){
  1711.         
  1712.         if(this.rendered){
  1713.             this.panel.forceLayout = this.ownerCt.forceLayout;
  1714.             this.panel.doLayout();
  1715.         }
  1716.     },
  1717.     
  1718.     fireChecked: function(){
  1719.         var arr = [];
  1720.         this.eachItem(function(item){
  1721.             if(item.checked){
  1722.                 arr.push(item);
  1723.             }
  1724.         });
  1725.         this.fireEvent('change', this, arr);
  1726.     },
  1727.     
  1728.     validateValue : function(value){
  1729.         if(!this.allowBlank){
  1730.             var blank = true;
  1731.             this.eachItem(function(f){
  1732.                 if(f.checked){
  1733.                     return (blank = false);
  1734.                 }
  1735.             });
  1736.             if(blank){
  1737.                 this.markInvalid(this.blankText);
  1738.                 return false;
  1739.             }
  1740.         }
  1741.         return true;
  1742.     },
  1743.     
  1744.     isDirty: function(){
  1745.         
  1746.         if (this.disabled || !this.rendered) {
  1747.             return false;
  1748.         }
  1749.         var dirty = false;
  1750.         this.eachItem(function(item){
  1751.             if(item.isDirty()){
  1752.                 dirty = true;
  1753.                 return false;
  1754.             }
  1755.         });
  1756.         return dirty;
  1757.     },
  1758.     
  1759.     onDisable : function(){
  1760.         this.eachItem(function(item){
  1761.             item.disable();
  1762.         });
  1763.     },
  1764.     
  1765.     onEnable : function(){
  1766.         this.eachItem(function(item){
  1767.             item.enable();
  1768.         });
  1769.     },
  1770.     
  1771.     doLayout: function(){
  1772.         if(this.rendered){
  1773.             this.panel.forceLayout = this.ownerCt.forceLayout;
  1774.             this.panel.doLayout();
  1775.         }
  1776.     },
  1777.     
  1778.     onResize : function(w, h){
  1779.         this.panel.setSize(w, h);
  1780.         this.panel.doLayout();
  1781.     },
  1782.     
  1783.     reset : function(){
  1784.         this.eachItem(function(c){
  1785.             if(c.reset){
  1786.                 c.reset();
  1787.             }
  1788.         });
  1789.         
  1790.         
  1791.         (function() {
  1792.             this.clearInvalid();
  1793.         }).defer(50, this);
  1794.     },
  1795.     
  1796.     setValue: function(){
  1797.         if(this.rendered){
  1798.             this.onSetValue.apply(this, arguments);
  1799.         }else{
  1800.             this.buffered = true;
  1801.             this.value = arguments;
  1802.         }
  1803.         return this;
  1804.     },
  1805.     onSetValue: function(id, value){
  1806.         if(arguments.length == 1){
  1807.             if(Ext.isArray(id)){
  1808.                 
  1809.                 Ext.each(id, function(val, idx){
  1810.                     var item = this.items.itemAt(idx);
  1811.                     if(item){
  1812.                         item.setValue(val);
  1813.                     }
  1814.                 }, this);
  1815.             }else if(Ext.isObject(id)){
  1816.                 
  1817.                 for(var i in id){
  1818.                     var f = this.getBox(i);
  1819.                     if(f){
  1820.                         f.setValue(id[i]);
  1821.                     }
  1822.                 }
  1823.             }else{
  1824.                 this.setValueForItem(id);
  1825.             }
  1826.         }else{
  1827.             var f = this.getBox(id);
  1828.             if(f){
  1829.                 f.setValue(value);
  1830.             }
  1831.         }
  1832.     },
  1833.     
  1834.     beforeDestroy: function(){
  1835.         Ext.destroy(this.panel);
  1836.         Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
  1837.     },
  1838.     setValueForItem : function(val){
  1839.         val = String(val).split(',');
  1840.         this.eachItem(function(item){
  1841.             if(val.indexOf(item.inputValue)> -1){
  1842.                 item.setValue(true);
  1843.             }
  1844.         });
  1845.     },
  1846.     
  1847.     getBox : function(id){
  1848.         var box = null;
  1849.         this.eachItem(function(f){
  1850.             if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
  1851.                 box = f;
  1852.                 return false;
  1853.             }
  1854.         });
  1855.         return box;
  1856.     },
  1857.     
  1858.     getValue : function(){
  1859.         var out = [];
  1860.         this.eachItem(function(item){
  1861.             if(item.checked){
  1862.                 out.push(item);
  1863.             }
  1864.         });
  1865.         return out;
  1866.     },
  1867.     
  1868.     eachItem: function(fn){
  1869.         if(this.items && this.items.each){
  1870.             this.items.each(fn, this);
  1871.         }
  1872.     },
  1873.     
  1874.     
  1875.     getRawValue : Ext.emptyFn,
  1876.     
  1877.     setRawValue : Ext.emptyFn
  1878. });
  1879. Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
  1880. Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
  1881.     inputType: 'radio',
  1882.     
  1883.     markInvalid : Ext.emptyFn,
  1884.     
  1885.     clearInvalid : Ext.emptyFn,
  1886.     
  1887.     getGroupValue : function(){
  1888.      var p = this.el.up('form') || Ext.getBody();
  1889.         var c = p.child('input[name='+this.el.dom.name+']:checked', true);
  1890.         return c ? c.value : null;
  1891.     },
  1892.     
  1893.     onClick : function(){
  1894.      if(this.el.dom.checked != this.checked){
  1895. var els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
  1896. els.each(function(el){
  1897. if(el.dom.id == this.id){
  1898. this.setValue(true);
  1899. }else{
  1900. Ext.getCmp(el.dom.id).setValue(false);
  1901. }
  1902. }, this);
  1903. }
  1904.     },
  1905.     
  1906.     setValue : function(v){
  1907.      if (typeof v == 'boolean') {
  1908.             Ext.form.Radio.superclass.setValue.call(this, v);
  1909.         } else {
  1910.             var r = this.getCheckEl().child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
  1911.             if(r){
  1912.                 Ext.getCmp(r.id).setValue(true);
  1913.             }
  1914.         }
  1915.         return this;
  1916.     },
  1917.     
  1918.     
  1919.     getCheckEl: function(){
  1920.         if(this.inGroup){
  1921.             return this.el.up('.x-form-radio-group')
  1922.         }
  1923.         return this.el.up('form') || Ext.getBody();
  1924.     }
  1925. });
  1926. Ext.reg('radio', Ext.form.Radio);
  1927. Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
  1928.     
  1929.     
  1930.     allowBlank : true,
  1931.     
  1932.     blankText : 'You must select one item in this group',
  1933.     
  1934.     
  1935.     defaultType : 'radio',
  1936.     
  1937.     
  1938.     groupCls : 'x-form-radio-group',
  1939.     
  1940.     
  1941.     
  1942.     
  1943.     getValue : function(){
  1944.         var out = null;
  1945.         this.eachItem(function(item){
  1946.             if(item.checked){
  1947.                 out = item;
  1948.                 return false;
  1949.             }
  1950.         });
  1951.         return out;
  1952.     },
  1953.     
  1954.     
  1955.     onSetValue : function(id, value){
  1956.         if(arguments.length > 1){
  1957.             var f = this.getBox(id);
  1958.             if(f){
  1959.                 f.setValue(value);
  1960.                 if(f.checked){
  1961.                     this.eachItem(function(item){
  1962.                         if (item !== f){
  1963.                             item.setValue(false);
  1964.                         }
  1965.                     });
  1966.                 }
  1967.             }
  1968.         }else{
  1969.             this.setValueForItem(id);
  1970.         }
  1971.     },
  1972.     
  1973.     setValueForItem : function(val){
  1974.         val = String(val).split(',')[0];
  1975.         this.eachItem(function(item){
  1976.             item.setValue(val == item.inputValue);
  1977.         });
  1978.     },
  1979.     
  1980.     
  1981.     fireChecked : function(){
  1982.         if(!this.checkTask){
  1983.             this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
  1984.         }
  1985.         this.checkTask.delay(10);
  1986.     },
  1987.     
  1988.     
  1989.     bufferChecked : function(){
  1990.         var out = null;
  1991.         this.eachItem(function(item){
  1992.             if(item.checked){
  1993.                 out = item;
  1994.                 return false;
  1995.             }
  1996.         });
  1997.         this.fireEvent('change', this, out);
  1998.     },
  1999.     
  2000.     onDestroy : function(){
  2001.         if(this.checkTask){
  2002.             this.checkTask.cancel();
  2003.             this.checkTask = null;
  2004.         }
  2005.         Ext.form.RadioGroup.superclass.onDestroy.call(this);
  2006.     }
  2007. });
  2008. Ext.reg('radiogroup', Ext.form.RadioGroup);
  2009. Ext.form.Hidden = Ext.extend(Ext.form.Field, {
  2010.     
  2011.     inputType : 'hidden',
  2012.     
  2013.     onRender : function(){
  2014.         Ext.form.Hidden.superclass.onRender.apply(this, arguments);
  2015.     },
  2016.     
  2017.     initEvents : function(){
  2018.         this.originalValue = this.getValue();
  2019.     },
  2020.     
  2021.     setSize : Ext.emptyFn,
  2022.     setWidth : Ext.emptyFn,
  2023.     setHeight : Ext.emptyFn,
  2024.     setPosition : Ext.emptyFn,
  2025.     setPagePosition : Ext.emptyFn,
  2026.     markInvalid : Ext.emptyFn,
  2027.     clearInvalid : Ext.emptyFn
  2028. });
  2029. Ext.reg('hidden', Ext.form.Hidden);
  2030. Ext.form.BasicForm = function(el, config){
  2031.     Ext.apply(this, config);
  2032.     if(Ext.isString(this.paramOrder)){
  2033.         this.paramOrder = this.paramOrder.split(/[s,|]/);
  2034.     }
  2035.     
  2036.     this.items = new Ext.util.MixedCollection(false, function(o){
  2037.         return o.getItemId();
  2038.     });
  2039.     this.addEvents(
  2040.         
  2041.         'beforeaction',
  2042.         
  2043.         'actionfailed',
  2044.         
  2045.         'actioncomplete'
  2046.     );
  2047.     if(el){
  2048.         this.initEl(el);
  2049.     }
  2050.     Ext.form.BasicForm.superclass.constructor.call(this);
  2051. };
  2052. Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
  2053.     
  2054.     
  2055.     
  2056.     
  2057.     
  2058.     
  2059.     
  2060.     timeout: 30,
  2061.     
  2062.     
  2063.     paramOrder: undefined,
  2064.     
  2065.     paramsAsHash: false,
  2066.     
  2067.     
  2068.     waitTitle: 'Please Wait...',
  2069.     
  2070.     activeAction : null,
  2071.     
  2072.     trackResetOnLoad : false,
  2073.     
  2074.     
  2075.     
  2076.     initEl : function(el){
  2077.         this.el = Ext.get(el);
  2078.         this.id = this.el.id || Ext.id();
  2079.         if(!this.standardSubmit){
  2080.             this.el.on('submit', this.onSubmit, this);
  2081.         }
  2082.         this.el.addClass('x-form');
  2083.     },
  2084.     
  2085.     getEl: function(){
  2086.         return this.el;
  2087.     },
  2088.     
  2089.     onSubmit : function(e){
  2090.         e.stopEvent();
  2091.     },
  2092.     
  2093.     destroy: function() {
  2094.         this.items.each(function(f){
  2095.             Ext.destroy(f);
  2096.         });
  2097.         if(this.el){
  2098.             this.el.removeAllListeners();
  2099.             this.el.remove();
  2100.         }
  2101.         this.purgeListeners();
  2102.     },
  2103.     
  2104.     isValid : function(){
  2105.         var valid = true;
  2106.         this.items.each(function(f){
  2107.            if(!f.validate()){
  2108.                valid = false;
  2109.            }
  2110.         });
  2111.         return valid;
  2112.     },
  2113.     
  2114.     isDirty : function(){
  2115.         var dirty = false;
  2116.         this.items.each(function(f){
  2117.            if(f.isDirty()){
  2118.                dirty = true;
  2119.                return false;
  2120.            }
  2121.         });
  2122.         return dirty;
  2123.     },
  2124.     
  2125.     doAction : function(action, options){
  2126.         if(Ext.isString(action)){
  2127.             action = new Ext.form.Action.ACTION_TYPES[action](this, options);
  2128.         }
  2129.         if(this.fireEvent('beforeaction', this, action) !== false){
  2130.             this.beforeAction(action);
  2131.             action.run.defer(100, action);
  2132.         }
  2133.         return this;
  2134.     },
  2135.     
  2136.     submit : function(options){
  2137.         if(this.standardSubmit){
  2138.             var v = this.isValid();
  2139.             if(v){
  2140.                 var el = this.el.dom;
  2141.                 if(this.url && Ext.isEmpty(el.action)){
  2142.                     el.action = this.url;
  2143.                 }
  2144.                 el.submit();
  2145.             }
  2146.             return v;
  2147.         }
  2148.         var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
  2149.         this.doAction(submitAction, options);
  2150.         return this;
  2151.     },
  2152.     
  2153.     load : function(options){
  2154.         var loadAction = String.format('{0}load', this.api ? 'direct' : '');
  2155.         this.doAction(loadAction, options);
  2156.         return this;
  2157.     },
  2158.     
  2159.     updateRecord : function(record){
  2160.         record.beginEdit();
  2161.         var fs = record.fields;
  2162.         fs.each(function(f){
  2163.             var field = this.findField(f.name);
  2164.             if(field){
  2165.                 record.set(f.name, field.getValue());
  2166.             }
  2167.         }, this);
  2168.         record.endEdit();
  2169.         return this;
  2170.     },
  2171.     
  2172.     loadRecord : function(record){
  2173.         this.setValues(record.data);
  2174.         return this;
  2175.     },
  2176.     
  2177.     beforeAction : function(action){
  2178.         var o = action.options;
  2179.         if(o.waitMsg){
  2180.             if(this.waitMsgTarget === true){
  2181.                 this.el.mask(o.waitMsg, 'x-mask-loading');
  2182.             }else if(this.waitMsgTarget){
  2183.                 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
  2184.                 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
  2185.             }else{
  2186.                 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
  2187.             }
  2188.         }
  2189.     },
  2190.     
  2191.     afterAction : function(action, success){
  2192.         this.activeAction = null;
  2193.         var o = action.options;
  2194.         if(o.waitMsg){
  2195.             if(this.waitMsgTarget === true){
  2196.                 this.el.unmask();
  2197.             }else if(this.waitMsgTarget){
  2198.                 this.waitMsgTarget.unmask();
  2199.             }else{
  2200.                 Ext.MessageBox.updateProgress(1);
  2201.                 Ext.MessageBox.hide();
  2202.             }
  2203.         }
  2204.         if(success){
  2205.             if(o.reset){
  2206.                 this.reset();
  2207.             }
  2208.             Ext.callback(o.success, o.scope, [this, action]);
  2209.             this.fireEvent('actioncomplete', this, action);
  2210.         }else{
  2211.             Ext.callback(o.failure, o.scope, [this, action]);
  2212.             this.fireEvent('actionfailed', this, action);
  2213.         }
  2214.     },
  2215.     
  2216.     findField : function(id){
  2217.         var field = this.items.get(id);
  2218.         if(!Ext.isObject(field)){
  2219.             this.items.each(function(f){
  2220.                 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
  2221.                     field = f;
  2222.                     return false;
  2223.                 }
  2224.             });
  2225.         }
  2226.         return field || null;
  2227.     },
  2228.     
  2229.     markInvalid : function(errors){
  2230.         if(Ext.isArray(errors)){
  2231.             for(var i = 0, len = errors.length; i < len; i++){
  2232.                 var fieldError = errors[i];
  2233.                 var f = this.findField(fieldError.id);
  2234.                 if(f){
  2235.                     f.markInvalid(fieldError.msg);
  2236.                 }
  2237.             }
  2238.         }else{
  2239.             var field, id;
  2240.             for(id in errors){
  2241.                 if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
  2242.                     field.markInvalid(errors[id]);
  2243.                 }
  2244.             }
  2245.         }
  2246.         return this;
  2247.     },
  2248.     
  2249.     setValues : function(values){
  2250.         if(Ext.isArray(values)){ 
  2251.             for(var i = 0, len = values.length; i < len; i++){
  2252.                 var v = values[i];
  2253.                 var f = this.findField(v.id);
  2254.                 if(f){
  2255.                     f.setValue(v.value);
  2256.                     if(this.trackResetOnLoad){
  2257.                         f.originalValue = f.getValue();
  2258.                     }
  2259.                 }
  2260.             }
  2261.         }else{ 
  2262.             var field, id;
  2263.             for(id in values){
  2264.                 if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
  2265.                     field.setValue(values[id]);
  2266.                     if(this.trackResetOnLoad){
  2267.                         field.originalValue = field.getValue();
  2268.                     }
  2269.                 }
  2270.             }
  2271.         }
  2272.         return this;
  2273.     },
  2274.     
  2275.     getValues : function(asString){
  2276.         var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
  2277.         if(asString === true){
  2278.             return fs;
  2279.         }
  2280.         return Ext.urlDecode(fs);
  2281.     },
  2282.     
  2283.     getFieldValues : function(dirtyOnly){
  2284.         var o = {},
  2285.             n,
  2286.             key,
  2287.             val;
  2288.         this.items.each(function(f){
  2289.             if(dirtyOnly !== true || f.isDirty()){
  2290.                 n = f.getName();
  2291.                 key = o[n];
  2292.                 val = f.getValue();
  2293.                 
  2294.                 if(Ext.isDefined(key)){
  2295.                     if(Ext.isArray(key)){
  2296.                         o[n].push(val);
  2297.                     }else{
  2298.                         o[n] = [key, val];
  2299.                     }
  2300.                 }else{
  2301.                     o[n] = val;
  2302.                 }
  2303.             }
  2304.         });
  2305.         return o;
  2306.     },
  2307.     
  2308.     clearInvalid : function(){
  2309.         this.items.each(function(f){
  2310.            f.clearInvalid();
  2311.         });
  2312.         return this;
  2313.     },
  2314.     
  2315.     reset : function(){
  2316.         this.items.each(function(f){
  2317.             f.reset();
  2318.         });
  2319.         return this;
  2320.     },
  2321.     
  2322.     add : function(){
  2323.         this.items.addAll(Array.prototype.slice.call(arguments, 0));
  2324.         return this;
  2325.     },
  2326.     
  2327.     remove : function(field){
  2328.         this.items.remove(field);
  2329.         return this;
  2330.     },
  2331.     
  2332.     render : function(){
  2333.         this.items.each(function(f){
  2334.             if(f.isFormField && !f.rendered && document.getElementById(f.id)){ 
  2335.                 f.applyToMarkup(f.id);
  2336.             }
  2337.         });
  2338.         return this;
  2339.     },
  2340.     
  2341.     applyToFields : function(o){
  2342.         this.items.each(function(f){
  2343.            Ext.apply(f, o);
  2344.         });
  2345.         return this;
  2346.     },
  2347.     
  2348.     applyIfToFields : function(o){
  2349.         this.items.each(function(f){
  2350.            Ext.applyIf(f, o);
  2351.         });
  2352.         return this;
  2353.     },
  2354.     callFieldMethod : function(fnName, args){
  2355.         args = args || [];
  2356.         this.items.each(function(f){
  2357.             if(Ext.isFunction(f[fnName])){
  2358.                 f[fnName].apply(f, args);
  2359.             }
  2360.         });
  2361.         return this;
  2362.     }
  2363. });
  2364. Ext.BasicForm = Ext.form.BasicForm;
  2365. Ext.FormPanel = Ext.extend(Ext.Panel, {
  2366.     
  2367.     
  2368.     
  2369.     
  2370.     
  2371.     
  2372.     
  2373.     
  2374.     minButtonWidth : 75,
  2375.     
  2376.     labelAlign : 'left',
  2377.     
  2378.     monitorValid : false,
  2379.     
  2380.     monitorPoll : 200,
  2381.     
  2382.     layout : 'form',
  2383.     
  2384.     initComponent : function(){
  2385.         this.form = this.createForm();
  2386.         Ext.FormPanel.superclass.initComponent.call(this);
  2387.         this.bodyCfg = {
  2388.             tag: 'form',
  2389.             cls: this.baseCls + '-body',
  2390.             method : this.method || 'POST',
  2391.             id : this.formId || Ext.id()
  2392.         };
  2393.         if(this.fileUpload) {
  2394.             this.bodyCfg.enctype = 'multipart/form-data';
  2395.         }
  2396.         this.initItems();
  2397.         this.addEvents(
  2398.             
  2399.             'clientvalidation'
  2400.         );
  2401.         this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
  2402.     },
  2403.     
  2404.     createForm : function(){
  2405.         var config = Ext.applyIf({listeners: {}}, this.initialConfig);
  2406.         return new Ext.form.BasicForm(null, config);
  2407.     },
  2408.     
  2409.     initFields : function(){
  2410.         var f = this.form;
  2411.         var formPanel = this;
  2412.         var fn = function(c){
  2413.             if(formPanel.isField(c)){
  2414.                 f.add(c);
  2415.             }else if(c.findBy && c != formPanel){
  2416.                 formPanel.applySettings(c);
  2417.                 
  2418.                 if(c.items && c.items.each){
  2419.                     c.items.each(fn, this);
  2420.                 }
  2421.             }
  2422.         };
  2423.         this.items.each(fn, this);
  2424.     },
  2425.     
  2426.     applySettings: function(c){
  2427.         var ct = c.ownerCt;
  2428.         Ext.applyIf(c, {
  2429.             labelAlign: ct.labelAlign,
  2430.             labelWidth: ct.labelWidth,
  2431.             itemCls: ct.itemCls
  2432.         });
  2433.     },
  2434.     
  2435.     getLayoutTarget : function(){
  2436.         return this.form.el;
  2437.     },
  2438.     
  2439.     getForm : function(){
  2440.         return this.form;
  2441.     },
  2442.     
  2443.     onRender : function(ct, position){
  2444.         this.initFields();
  2445.         Ext.FormPanel.superclass.onRender.call(this, ct, position);
  2446.         this.form.initEl(this.body);
  2447.     },
  2448.     
  2449.     beforeDestroy : function(){
  2450.         this.stopMonitoring();
  2451.         
  2452.         Ext.destroy(this.form);
  2453.         this.form.items.clear();
  2454.         Ext.FormPanel.superclass.beforeDestroy.call(this);
  2455.     },
  2456.     
  2457.     isField : function(c) {
  2458.         return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
  2459.     },
  2460.     
  2461.     initEvents : function(){
  2462.         Ext.FormPanel.superclass.initEvents.call(this);
  2463.         
  2464.         this.on({
  2465.             scope: this,
  2466.             add: this.onAddEvent,
  2467.             remove: this.onRemoveEvent
  2468.         });
  2469.         if(this.monitorValid){ 
  2470.             this.startMonitoring();
  2471.         }
  2472.     },
  2473.     
  2474.     onAdd: function(c){
  2475.         Ext.FormPanel.superclass.onAdd.call(this, c);
  2476.         this.processAdd(c);
  2477.     },
  2478.     
  2479.     onAddEvent: function(ct, c){
  2480.         if(ct !== this){
  2481.             this.processAdd(c);
  2482.         }
  2483.     },
  2484.     
  2485.     processAdd : function(c){
  2486.         
  2487.         if(this.isField(c)){
  2488.             this.form.add(c);
  2489.         
  2490.         }else if(c.findBy){
  2491.             this.applySettings(c);
  2492.             this.form.add.apply(this.form, c.findBy(this.isField));
  2493.         }
  2494.     },
  2495.     
  2496.     onRemove: function(c){
  2497.         Ext.FormPanel.superclass.onRemove.call(this, c);
  2498.         this.processRemove(c);
  2499.     },
  2500.     onRemoveEvent: function(ct, c){
  2501.         if(ct !== this){
  2502.             this.processRemove(c);
  2503.         }
  2504.     },
  2505.     
  2506.     processRemove : function(c){
  2507.         
  2508.         if(this.isField(c)){
  2509.             this.form.remove(c);
  2510.         
  2511.         }else if(c.findBy){
  2512.             var isDestroyed = function(o) {
  2513.                 return !!o.isDestroyed;
  2514.             }
  2515.             this.form.items.filterBy(isDestroyed, this.form).each(this.form.remove, this.form);
  2516.         }
  2517.     },
  2518.     
  2519.     startMonitoring : function(){
  2520.         if(!this.validTask){
  2521.             this.validTask = new Ext.util.TaskRunner();
  2522.             this.validTask.start({
  2523.                 run : this.bindHandler,
  2524.                 interval : this.monitorPoll || 200,
  2525.                 scope: this
  2526.             });
  2527.         }
  2528.     },
  2529.     
  2530.     stopMonitoring : function(){
  2531.         if(this.validTask){
  2532.             this.validTask.stopAll();
  2533.             this.validTask = null;
  2534.         }
  2535.     },
  2536.     
  2537.     load : function(){
  2538.         this.form.load.apply(this.form, arguments);
  2539.     },
  2540.     
  2541.     onDisable : function(){
  2542.         Ext.FormPanel.superclass.onDisable.call(this);
  2543.         if(this.form){
  2544.             this.form.items.each(function(){
  2545.                  this.disable();
  2546.             });
  2547.         }
  2548.     },
  2549.     
  2550.     onEnable : function(){
  2551.         Ext.FormPanel.superclass.onEnable.call(this);
  2552.         if(this.form){
  2553.             this.form.items.each(function(){
  2554.                  this.enable();
  2555.             });
  2556.         }
  2557.     },
  2558.     
  2559.     bindHandler : function(){
  2560.         var valid = true;
  2561.         this.form.items.each(function(f){
  2562.             if(!f.isValid(true)){
  2563.                 valid = false;
  2564.                 return false;
  2565.             }
  2566.         });
  2567.         if(this.fbar){
  2568.             var fitems = this.fbar.items.items;
  2569.             for(var i = 0, len = fitems.length; i < len; i++){
  2570.                 var btn = fitems[i];
  2571.                 if(btn.formBind === true && btn.disabled === valid){
  2572.                     btn.setDisabled(!valid);
  2573.                 }
  2574.             }
  2575.         }
  2576.         this.fireEvent('clientvalidation', this, valid);
  2577.     }
  2578. });
  2579. Ext.reg('form', Ext.FormPanel);
  2580. Ext.form.FormPanel = Ext.FormPanel;
  2581. Ext.form.FieldSet = Ext.extend(Ext.Panel, {
  2582.     
  2583.     
  2584.     
  2585.     
  2586.     
  2587.     
  2588.     baseCls : 'x-fieldset',
  2589.     
  2590.     layout : 'form',
  2591.     
  2592.     animCollapse : false,
  2593.     
  2594.     onRender : function(ct, position){
  2595.         if(!this.el){
  2596.             this.el = document.createElement('fieldset');
  2597.             this.el.id = this.id;
  2598.             if (this.title || this.header || this.checkboxToggle) {
  2599.                 this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
  2600.             }
  2601.         }
  2602.         Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
  2603.         if(this.checkboxToggle){
  2604.             var o = typeof this.checkboxToggle == 'object' ?
  2605.                     this.checkboxToggle :
  2606.                     {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
  2607.             this.checkbox = this.header.insertFirst(o);
  2608.             this.checkbox.dom.checked = !this.collapsed;
  2609.             this.mon(this.checkbox, 'click', this.onCheckClick, this);
  2610.         }
  2611.     },
  2612.     
  2613.     onCollapse : function(doAnim, animArg){
  2614.         if(this.checkbox){
  2615.             this.checkbox.dom.checked = false;
  2616.         }
  2617.         Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
  2618.     },
  2619.     
  2620.     onExpand : function(doAnim, animArg){
  2621.         if(this.checkbox){
  2622.             this.checkbox.dom.checked = true;
  2623.         }
  2624.         Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
  2625.     },
  2626.     
  2627.     onCheckClick : function(){
  2628.         this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
  2629.     }
  2630.     
  2631.     
  2632.     
  2633.     
  2634.     
  2635.     
  2636.     
  2637.     
  2638.     
  2639.     
  2640.     
  2641.     
  2642.     
  2643.     
  2644.     
  2645.     
  2646.     
  2647.     
  2648.     
  2649.     
  2650.     
  2651.     
  2652.     
  2653.     
  2654.     
  2655.     
  2656.     
  2657.     
  2658.     
  2659.     
  2660.     
  2661.     
  2662.     
  2663.     
  2664. });
  2665. Ext.reg('fieldset', Ext.form.FieldSet);
  2666. Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
  2667.     
  2668.     enableFormat : true,
  2669.     
  2670.     enableFontSize : true,
  2671.     
  2672.     enableColors : true,
  2673.     
  2674.     enableAlignments : true,
  2675.     
  2676.     enableLists : true,
  2677.     
  2678.     enableSourceEdit : true,
  2679.     
  2680.     enableLinks : true,
  2681.     
  2682.     enableFont : true,
  2683.     
  2684.     createLinkText : 'Please enter the URL for the link:',
  2685.     
  2686.     defaultLinkValue : 'http:/'+'/',
  2687.     
  2688.     fontFamilies : [
  2689.         'Arial',
  2690.         'Courier New',
  2691.         'Tahoma',
  2692.         'Times New Roman',
  2693.         'Verdana'
  2694.     ],
  2695.     defaultFont: 'tahoma',
  2696.     
  2697.     defaultValue: (Ext.isOpera || Ext.isIE6) ? '&#160;' : '&#8203;',
  2698.     
  2699.     actionMode: 'wrap',
  2700.     validationEvent : false,
  2701.     deferHeight: true,
  2702.     initialized : false,
  2703.     activated : false,
  2704.     sourceEditMode : false,
  2705.     onFocus : Ext.emptyFn,
  2706.     iframePad:3,
  2707.     hideMode:'offsets',
  2708.     defaultAutoCreate : {
  2709.         tag: "textarea",
  2710.         style:"width:500px;height:300px;",
  2711.         autocomplete: "off"
  2712.     },
  2713.     
  2714.     initComponent : function(){
  2715.         this.addEvents(
  2716.             
  2717.             'initialize',
  2718.             
  2719.             'activate',
  2720.              
  2721.             'beforesync',
  2722.              
  2723.             'beforepush',
  2724.              
  2725.             'sync',
  2726.              
  2727.             'push',
  2728.              
  2729.             'editmodechange'
  2730.         )
  2731.     },
  2732.     
  2733.     createFontOptions : function(){
  2734.         var buf = [], fs = this.fontFamilies, ff, lc;
  2735.         for(var i = 0, len = fs.length; i< len; i++){
  2736.             ff = fs[i];
  2737.             lc = ff.toLowerCase();
  2738.             buf.push(
  2739.                 '<option value="',lc,'" style="font-family:',ff,';"',
  2740.                     (this.defaultFont == lc ? ' selected="true">' : '>'),
  2741.                     ff,
  2742.                 '</option>'
  2743.             );
  2744.         }
  2745.         return buf.join('');
  2746.     },
  2747.     
  2748.     createToolbar : function(editor){
  2749.         var items = [];
  2750.         var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
  2751.         
  2752.         function btn(id, toggle, handler){
  2753.             return {
  2754.                 itemId : id,
  2755.                 cls : 'x-btn-icon',
  2756.                 iconCls: 'x-edit-'+id,
  2757.                 enableToggle:toggle !== false,
  2758.                 scope: editor,
  2759.                 handler:handler||editor.relayBtnCmd,
  2760.                 clickEvent:'mousedown',
  2761.                 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
  2762.                 overflowText: editor.buttonTips[id].title || undefined,
  2763.                 tabIndex:-1
  2764.             };
  2765.         }
  2766.         if(this.enableFont && !Ext.isSafari2){
  2767.             var fontSelectItem = new Ext.Toolbar.Item({
  2768.                autoEl: {
  2769.                     tag:'select',
  2770.                     cls:'x-font-select',
  2771.                     html: this.createFontOptions()
  2772.                }
  2773.             });
  2774.             
  2775.             items.push(
  2776.                 fontSelectItem,
  2777.                 '-'
  2778.             );
  2779.         }
  2780.         if(this.enableFormat){
  2781.             items.push(
  2782.                 btn('bold'),
  2783.                 btn('italic'),
  2784.                 btn('underline')
  2785.             );
  2786.         }
  2787.         if(this.enableFontSize){
  2788.             items.push(
  2789.                 '-',
  2790.                 btn('increasefontsize', false, this.adjustFont),
  2791.                 btn('decreasefontsize', false, this.adjustFont)
  2792.             );
  2793.         }
  2794.         if(this.enableColors){
  2795.             items.push(
  2796.                 '-', {
  2797.                     itemId:'forecolor',
  2798.                     cls:'x-btn-icon',
  2799.                     iconCls: 'x-edit-forecolor',
  2800.                     clickEvent:'mousedown',
  2801.                     tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
  2802.                     tabIndex:-1,
  2803.                     menu : new Ext.menu.ColorMenu({
  2804.                         allowReselect: true,
  2805.                         focus: Ext.emptyFn,
  2806.                         value:'000000',
  2807.                         plain:true,
  2808.                         listeners: {
  2809.                             scope: this,
  2810.                             select: function(cp, color){
  2811.                                 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
  2812.                                 this.deferFocus();
  2813.                             }
  2814.                         },
  2815.                         clickEvent:'mousedown'
  2816.                     })
  2817.                 }, {
  2818.                     itemId:'backcolor',
  2819.                     cls:'x-btn-icon',
  2820.                     iconCls: 'x-edit-backcolor',
  2821.                     clickEvent:'mousedown',
  2822.                     tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
  2823.                     tabIndex:-1,
  2824.                     menu : new Ext.menu.ColorMenu({
  2825.                         focus: Ext.emptyFn,
  2826.                         value:'FFFFFF',
  2827.                         plain:true,
  2828.                         allowReselect: true,
  2829.                         listeners: {
  2830.                             scope: this,
  2831.                             select: function(cp, color){
  2832.                                 if(Ext.isGecko){
  2833.                                     this.execCmd('useCSS', false);
  2834.                                     this.execCmd('hilitecolor', color);
  2835.                                     this.execCmd('useCSS', true);
  2836.                                     this.deferFocus();
  2837.                                 }else{
  2838.                                     this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
  2839.                                     this.deferFocus();
  2840.                                 }
  2841.                             }
  2842.                         },
  2843.                         clickEvent:'mousedown'
  2844.                     })
  2845.                 }
  2846.             );
  2847.         }
  2848.         if(this.enableAlignments){
  2849.             items.push(
  2850.                 '-',
  2851.                 btn('justifyleft'),
  2852.                 btn('justifycenter'),
  2853.                 btn('justifyright')
  2854.             );
  2855.         }
  2856.         if(!Ext.isSafari2){
  2857.             if(this.enableLinks){
  2858.                 items.push(
  2859.                     '-',
  2860.                     btn('createlink', false, this.createLink)
  2861.                 );
  2862.             }
  2863.             if(this.enableLists){
  2864.                 items.push(
  2865.                     '-',
  2866.                     btn('insertorderedlist'),
  2867.                     btn('insertunorderedlist')
  2868.                 );
  2869.             }
  2870.             if(this.enableSourceEdit){
  2871.                 items.push(
  2872.                     '-',
  2873.                     btn('sourceedit', true, function(btn){
  2874.                         this.toggleSourceEdit(!this.sourceEditMode);
  2875.                     })
  2876.                 );
  2877.             }
  2878.         }
  2879.  
  2880.         
  2881.         var tb = new Ext.Toolbar({
  2882.             renderTo: this.wrap.dom.firstChild,
  2883.             items: items
  2884.         });
  2885.         
  2886.         if (fontSelectItem) {
  2887.             this.fontSelect = fontSelectItem.el;
  2888.             
  2889.             this.mon(this.fontSelect, 'change', function(){
  2890.                 var font = this.fontSelect.dom.value;
  2891.                 this.relayCmd('fontname', font);
  2892.                 this.deferFocus();
  2893.             }, this);
  2894.         }
  2895.         
  2896.         this.mon(tb.el, 'click', function(e){
  2897.             e.preventDefault();
  2898.         });
  2899.        
  2900.         
  2901.         
  2902.         this.tb = tb;
  2903.     },
  2904.     onDisable: function(){
  2905.         this.wrap.mask();
  2906.         Ext.form.HtmlEditor.superclass.onDisable.call(this);
  2907.     },
  2908.     onEnable: function(){
  2909.         this.wrap.unmask();
  2910.         Ext.form.HtmlEditor.superclass.onEnable.call(this);
  2911.     },
  2912.     setReadOnly: function(readOnly){
  2913.         if(this.initialized){
  2914.             var newDM = readOnly ? 'off' : 'on',
  2915.                 doc = this.getDoc();
  2916.             if(String(doc.designMode).toLowerCase() != newDM){
  2917.                 doc.designMode = newDM;
  2918.             }
  2919.             this.disableItems(!readOnly);
  2920.         }
  2921.         Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
  2922.     },
  2923.     
  2924.     getDocMarkup : function(){
  2925.         return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
  2926.     },
  2927.     
  2928.     getEditorBody : function(){
  2929.         var doc = this.getDoc();
  2930.         return doc.body || doc.documentElement;
  2931.     },
  2932.     
  2933.     getDoc : function(){
  2934.         return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
  2935.     },
  2936.     
  2937.     getWin : function(){
  2938.         return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
  2939.     },
  2940.     
  2941.     onRender : function(ct, position){
  2942.         Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
  2943.         this.el.dom.style.border = '0 none';
  2944.         this.el.dom.setAttribute('tabIndex', -1);
  2945.         this.el.addClass('x-hidden');
  2946.         if(Ext.isIE){ 
  2947.             this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
  2948.         }
  2949.         this.wrap = this.el.wrap({
  2950.             cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
  2951.         });
  2952.         this.createToolbar(this);
  2953.         this.disableItems(true);
  2954.         
  2955.         
  2956.         this.createIFrame();
  2957.         if(!this.width){
  2958.             var sz = this.el.getSize();
  2959.             this.setSize(sz.width, this.height || sz.height);
  2960.         }
  2961.         this.resizeEl = this.positionEl = this.wrap;
  2962.     },
  2963.     createIFrame: function(){
  2964.         var iframe = document.createElement('iframe');
  2965.         iframe.name = Ext.id();
  2966.         iframe.frameBorder = '0';
  2967.         iframe.src = Ext.SSL_SECURE_URL;
  2968.         this.wrap.dom.appendChild(iframe);
  2969.         this.iframe = iframe;
  2970.         this.monitorTask = Ext.TaskMgr.start({
  2971.             run: this.checkDesignMode,
  2972.             scope: this,
  2973.             interval:100
  2974.         });
  2975.     },
  2976.     initFrame : function(){
  2977.         Ext.TaskMgr.stop(this.monitorTask);
  2978.         var doc = this.getDoc();
  2979.         this.win = this.getWin();
  2980.         doc.open();
  2981.         doc.write(this.getDocMarkup());
  2982.         doc.close();
  2983.         var task = { 
  2984.             run : function(){
  2985.                 var doc = this.getDoc();
  2986.                 if(doc.body || doc.readyState == 'complete'){
  2987.                     Ext.TaskMgr.stop(task);
  2988.                     doc.designMode="on";
  2989.                     this.initEditor.defer(10, this);
  2990.                 }
  2991.             },
  2992.             interval : 10,
  2993.             duration:10000,
  2994.             scope: this
  2995.         };
  2996.         Ext.TaskMgr.start(task);
  2997.     },
  2998.     checkDesignMode : function(){
  2999.         if(this.wrap && this.wrap.dom.offsetWidth){
  3000.             var doc = this.getDoc();
  3001.             if(!doc){
  3002.                 return;
  3003.             }
  3004.             if(!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on'){
  3005.                 this.initFrame();
  3006.             }
  3007.         }
  3008.     },
  3009.     disableItems: function(disabled){
  3010.         if(this.fontSelect){
  3011.             this.fontSelect.dom.disabled = disabled;
  3012.         }
  3013.         this.tb.items.each(function(item){
  3014.             if(item.getItemId() != 'sourceedit'){
  3015.                 item.setDisabled(disabled);
  3016.             }
  3017.         });
  3018.     },
  3019.     
  3020.     onResize : function(w, h){
  3021.         Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
  3022.         if(this.el && this.iframe){
  3023.             if(Ext.isNumber(w)){
  3024.                 var aw = w - this.wrap.getFrameWidth('lr');
  3025.                 this.el.setWidth(aw);
  3026.                 this.tb.setWidth(aw);
  3027.                 this.iframe.style.width = Math.max(aw, 0) + 'px';
  3028.             }
  3029.             if(Ext.isNumber(h)){
  3030.                 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
  3031.                 this.el.setHeight(ah);
  3032.                 this.iframe.style.height = Math.max(ah, 0) + 'px';
  3033.                 var bd = this.getEditorBody();
  3034.                 if(bd){
  3035.                     bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
  3036.                 }
  3037.             }
  3038.         }
  3039.     },
  3040.     
  3041.     toggleSourceEdit : function(sourceEditMode){
  3042.         if(sourceEditMode === undefined){
  3043.             sourceEditMode = !this.sourceEditMode;
  3044.         }
  3045.         this.sourceEditMode = sourceEditMode === true;
  3046.         var btn = this.tb.getComponent('sourceedit');
  3047.         
  3048.         if(btn.pressed !== this.sourceEditMode){
  3049.             btn.toggle(this.sourceEditMode);
  3050.             if(!btn.xtbHidden){
  3051.                 return;
  3052.             }
  3053.         }
  3054.         if(this.sourceEditMode){
  3055.             this.disableItems(true);
  3056.             this.syncValue();
  3057.             this.iframe.className = 'x-hidden';
  3058.             this.el.removeClass('x-hidden');
  3059.             this.el.dom.removeAttribute('tabIndex');
  3060.             this.el.focus();
  3061.         }else{
  3062.             if(this.initialized && !this.readOnly){
  3063.                 this.disableItems(false);
  3064.             }
  3065.             this.pushValue();
  3066.             this.iframe.className = '';
  3067.             this.el.addClass('x-hidden');
  3068.             this.el.dom.setAttribute('tabIndex', -1);
  3069.             this.deferFocus();
  3070.         }
  3071.         var lastSize = this.lastSize;
  3072.         if(lastSize){
  3073.             delete this.lastSize;
  3074.             this.setSize(lastSize);
  3075.         }
  3076.         this.fireEvent('editmodechange', this, this.sourceEditMode);
  3077.     },
  3078.     
  3079.     createLink : function(){
  3080.         var url = prompt(this.createLinkText, this.defaultLinkValue);
  3081.         if(url && url != 'http:/'+'/'){
  3082.             this.relayCmd('createlink', url);
  3083.         }
  3084.     },
  3085.     
  3086.     initEvents : function(){
  3087.         this.originalValue = this.getValue();
  3088.     },
  3089.     
  3090.     markInvalid : Ext.emptyFn,
  3091.     
  3092.     clearInvalid : Ext.emptyFn,
  3093.     
  3094.     setValue : function(v){
  3095.         Ext.form.HtmlEditor.superclass.setValue.call(this, v);
  3096.         this.pushValue();
  3097.         return this;
  3098.     },
  3099.     
  3100.     cleanHtml: function(html) {
  3101.         html = String(html);
  3102.         if(Ext.isWebKit){ 
  3103.             html = html.replace(/sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
  3104.         }
  3105.         
  3106.         if(html.charCodeAt(0) == this.defaultValue.replace(/D/g, '')){
  3107.             html = html.substring(1);
  3108.         }
  3109.         return html;
  3110.     },
  3111.     
  3112.     syncValue : function(){
  3113.         if(this.initialized){
  3114.             var bd = this.getEditorBody();
  3115.             var html = bd.innerHTML;
  3116.             if(Ext.isWebKit){
  3117.                 var bs = bd.getAttribute('style'); 
  3118.                 var m = bs.match(/text-align:(.*?);/i);
  3119.                 if(m && m[1]){
  3120.                     html = '<div style="'+m[0]+'">' + html + '</div>';
  3121.                 }
  3122.             }
  3123.             html = this.cleanHtml(html);
  3124.             if(this.fireEvent('beforesync', this, html) !== false){
  3125.                 this.el.dom.value = html;
  3126.                 this.fireEvent('sync', this, html);
  3127.             }
  3128.         }
  3129.     },
  3130.     
  3131.     getValue : function() {
  3132.         this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
  3133.         return Ext.form.HtmlEditor.superclass.getValue.call(this);
  3134.     },
  3135.     
  3136.     pushValue : function(){
  3137.         if(this.initialized){
  3138.             var v = this.el.dom.value;
  3139.             if(!this.activated && v.length < 1){
  3140.                 v = this.defaultValue;
  3141.             }
  3142.             if(this.fireEvent('beforepush', this, v) !== false){
  3143.                 this.getEditorBody().innerHTML = v;
  3144.                 if(Ext.isGecko){
  3145.                     
  3146.                     var d = this.getDoc(),
  3147.                         mode = d.designMode.toLowerCase();
  3148.                     d.designMode = mode.toggle('on', 'off');
  3149.                     d.designMode = mode;
  3150.                 }
  3151.                 this.fireEvent('push', this, v);
  3152.             }
  3153.         }
  3154.     },
  3155.     
  3156.     deferFocus : function(){
  3157.         this.focus.defer(10, this);
  3158.     },
  3159.     
  3160.     focus : function(){
  3161.         if(this.win && !this.sourceEditMode){
  3162.             this.win.focus();
  3163.         }else{
  3164.             this.el.focus();
  3165.         }
  3166.     },
  3167.     
  3168.     initEditor : function(){
  3169.         
  3170.         try{
  3171.             var dbody = this.getEditorBody(),
  3172.                 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat'),
  3173.                 doc,
  3174.                 fn;
  3175.                 
  3176.             ss['background-attachment'] = 'fixed'; 
  3177.             dbody.bgProperties = 'fixed'; 
  3178.             Ext.DomHelper.applyStyles(dbody, ss);
  3179.             
  3180.             doc = this.getDoc();
  3181.             if(doc){
  3182.                 try{
  3183.                     Ext.EventManager.removeAll(doc);
  3184.                 }catch(e){}
  3185.             }
  3186.             
  3187.             fn = this.onEditorEvent.createDelegate(this);
  3188.             Ext.EventManager.on(doc, {
  3189.                 mousedown: fn,
  3190.                 dblclick: fn,
  3191.                 click: fn,
  3192.                 keyup: fn,
  3193.                 buffer:100
  3194.             });
  3195.             if(Ext.isGecko){
  3196.                 Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
  3197.             }
  3198.             if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
  3199.                 Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
  3200.             }
  3201.             doc.editorInitialized = true;
  3202.             this.initialized = true;
  3203.             this.pushValue();
  3204.             this.setReadOnly(this.readOnly);
  3205.             this.fireEvent('initialize', this);
  3206.         }catch(e){}
  3207.     },
  3208.     
  3209.     onDestroy : function(){
  3210.         if(this.monitorTask){
  3211.             Ext.TaskMgr.stop(this.monitorTask);
  3212.         }
  3213.         if(this.rendered){
  3214.             Ext.destroy(this.tb);
  3215.             var doc = this.getDoc();
  3216.             if(doc){
  3217.                 try{
  3218.                     Ext.EventManager.removeAll(doc);
  3219.                     for (var prop in doc){
  3220.                         delete doc[prop];
  3221.                     }
  3222.                 }catch(e){}
  3223.             }
  3224.             if(this.wrap){
  3225.                 this.wrap.dom.innerHTML = '';
  3226.                 this.wrap.remove();
  3227.             }
  3228.         }
  3229.         
  3230.         if(this.el){
  3231.             this.el.removeAllListeners();
  3232.             this.el.remove();
  3233.         }
  3234.         this.purgeListeners();
  3235.     },
  3236.     
  3237.     onFirstFocus : function(){
  3238.         this.activated = true;
  3239.         this.disableItems(false);
  3240.         if(Ext.isGecko){ 
  3241.             this.win.focus();
  3242.             var s = this.win.getSelection();
  3243.             if(!s.focusNode || s.focusNode.nodeType != 3){
  3244.                 var r = s.getRangeAt(0);
  3245.                 r.selectNodeContents(this.getEditorBody());
  3246.                 r.collapse(true);
  3247.                 this.deferFocus();
  3248.             }
  3249.             try{
  3250.                 this.execCmd('useCSS', true);
  3251.                 this.execCmd('styleWithCSS', false);
  3252.             }catch(e){}
  3253.         }
  3254.         this.fireEvent('activate', this);
  3255.     },
  3256.     
  3257.     adjustFont: function(btn){
  3258.         var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
  3259.             doc = this.getDoc(),
  3260.             v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
  3261.         if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
  3262.             
  3263.             
  3264.             if(v <= 10){
  3265.                 v = 1 + adjust;
  3266.             }else if(v <= 13){
  3267.                 v = 2 + adjust;
  3268.             }else if(v <= 16){
  3269.                 v = 3 + adjust;
  3270.             }else if(v <= 18){
  3271.                 v = 4 + adjust;
  3272.             }else if(v <= 24){
  3273.                 v = 5 + adjust;
  3274.             }else {
  3275.                 v = 6 + adjust;
  3276.             }
  3277.             v = v.constrain(1, 6);
  3278.         }else{
  3279.             if(Ext.isSafari){ 
  3280.                 adjust *= 2;
  3281.             }
  3282.             v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
  3283.         }
  3284.         this.execCmd('FontSize', v);
  3285.     },
  3286.     
  3287.     onEditorEvent : function(e){
  3288.         this.updateToolbar();
  3289.     },
  3290.     
  3291.     updateToolbar: function(){
  3292.         if(this.readOnly){
  3293.             return;
  3294.         }
  3295.         if(!this.activated){
  3296.             this.onFirstFocus();
  3297.             return;
  3298.         }
  3299.         var btns = this.tb.items.map, 
  3300.             doc = this.getDoc();
  3301.         if(this.enableFont && !Ext.isSafari2){
  3302.             var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
  3303.             if(name != this.fontSelect.dom.value){
  3304.                 this.fontSelect.dom.value = name;
  3305.             }
  3306.         }
  3307.         if(this.enableFormat){
  3308.             btns.bold.toggle(doc.queryCommandState('bold'));
  3309.             btns.italic.toggle(doc.queryCommandState('italic'));
  3310.             btns.underline.toggle(doc.queryCommandState('underline'));
  3311.         }
  3312.         if(this.enableAlignments){
  3313.             btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
  3314.             btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
  3315.             btns.justifyright.toggle(doc.queryCommandState('justifyright'));
  3316.         }
  3317.         if(!Ext.isSafari2 && this.enableLists){
  3318.             btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
  3319.             btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
  3320.         }
  3321.         Ext.menu.MenuMgr.hideAll();
  3322.         this.syncValue();
  3323.     },
  3324.     
  3325.     relayBtnCmd : function(btn){
  3326.         this.relayCmd(btn.getItemId());
  3327.     },
  3328.     
  3329.     relayCmd : function(cmd, value){
  3330.         (function(){
  3331.             this.focus();
  3332.             this.execCmd(cmd, value);
  3333.             this.updateToolbar();
  3334.         }).defer(10, this);
  3335.     },
  3336.     
  3337.     execCmd : function(cmd, value){
  3338.         var doc = this.getDoc();
  3339.         doc.execCommand(cmd, false, value === undefined ? null : value);
  3340.         this.syncValue();
  3341.     },
  3342.     
  3343.     applyCommand : function(e){
  3344.         if(e.ctrlKey){
  3345.             var c = e.getCharCode(), cmd;
  3346.             if(c > 0){
  3347.                 c = String.fromCharCode(c);
  3348.                 switch(c){
  3349.                     case 'b':
  3350.                         cmd = 'bold';
  3351.                     break;
  3352.                     case 'i':
  3353.                         cmd = 'italic';
  3354.                     break;
  3355.                     case 'u':
  3356.                         cmd = 'underline';
  3357.                     break;
  3358.                 }
  3359.                 if(cmd){
  3360.                     this.win.focus();
  3361.                     this.execCmd(cmd);
  3362.                     this.deferFocus();
  3363.                     e.preventDefault();
  3364.                 }
  3365.             }
  3366.         }
  3367.     },
  3368.     
  3369.     insertAtCursor : function(text){
  3370.         if(!this.activated){
  3371.             return;
  3372.         }
  3373.         if(Ext.isIE){
  3374.             this.win.focus();
  3375.             var doc = this.getDoc(),
  3376.                 r = doc.selection.createRange();
  3377.             if(r){
  3378.                 r.pasteHTML(text);
  3379.                 this.syncValue();
  3380.                 this.deferFocus();
  3381.             }
  3382.         }else{
  3383.             this.win.focus();
  3384.             this.execCmd('InsertHTML', text);
  3385.             this.deferFocus();
  3386.         }
  3387.     },
  3388.     
  3389.     fixKeys : function(){ 
  3390.         if(Ext.isIE){
  3391.             return function(e){
  3392.                 var k = e.getKey(), 
  3393.                     doc = this.getDoc(),
  3394.                         r;
  3395.                 if(k == e.TAB){
  3396.                     e.stopEvent();
  3397.                     r = doc.selection.createRange();
  3398.                     if(r){
  3399.                         r.collapse(true);
  3400.                         r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
  3401.                         this.deferFocus();
  3402.                     }
  3403.                 }else if(k == e.ENTER){
  3404.                     r = doc.selection.createRange();
  3405.                     if(r){
  3406.                         var target = r.parentElement();
  3407.                         if(!target || target.tagName.toLowerCase() != 'li'){
  3408.                             e.stopEvent();
  3409.                             r.pasteHTML('<br />');
  3410.                             r.collapse(false);
  3411.                             r.select();
  3412.                         }
  3413.                     }
  3414.                 }
  3415.             };
  3416.         }else if(Ext.isOpera){
  3417.             return function(e){
  3418.                 var k = e.getKey();
  3419.                 if(k == e.TAB){
  3420.                     e.stopEvent();
  3421.                     this.win.focus();
  3422.                     this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');
  3423.                     this.deferFocus();
  3424.                 }
  3425.             };
  3426.         }else if(Ext.isWebKit){
  3427.             return function(e){
  3428.                 var k = e.getKey();
  3429.                 if(k == e.TAB){
  3430.                     e.stopEvent();
  3431.                     this.execCmd('InsertText','t');
  3432.                     this.deferFocus();
  3433.                 }else if(k == e.ENTER){
  3434.                     e.stopEvent();
  3435.                     this.execCmd('InsertHtml','<br /><br />');
  3436.                     this.deferFocus();
  3437.                 }
  3438.              };
  3439.         }
  3440.     }(),
  3441.     
  3442.     getToolbar : function(){
  3443.         return this.tb;
  3444.     },
  3445.     
  3446.     buttonTips : {
  3447.         bold : {
  3448.             title: 'Bold (Ctrl+B)',
  3449.             text: 'Make the selected text bold.',
  3450.             cls: 'x-html-editor-tip'
  3451.         },
  3452.         italic : {
  3453.             title: 'Italic (Ctrl+I)',
  3454.             text: 'Make the selected text italic.',
  3455.             cls: 'x-html-editor-tip'
  3456.         },
  3457.         underline : {
  3458.             title: 'Underline (Ctrl+U)',
  3459.             text: 'Underline the selected text.',
  3460.             cls: 'x-html-editor-tip'
  3461.         },
  3462.         increasefontsize : {
  3463.             title: 'Grow Text',
  3464.             text: 'Increase the font size.',
  3465.             cls: 'x-html-editor-tip'
  3466.         },
  3467.         decreasefontsize : {
  3468.             title: 'Shrink Text',
  3469.             text: 'Decrease the font size.',
  3470.             cls: 'x-html-editor-tip'
  3471.         },
  3472.         backcolor : {
  3473.             title: 'Text Highlight Color',
  3474.             text: 'Change the background color of the selected text.',
  3475.             cls: 'x-html-editor-tip'
  3476.         },
  3477.         forecolor : {
  3478.             title: 'Font Color',
  3479.             text: 'Change the color of the selected text.',
  3480.             cls: 'x-html-editor-tip'
  3481.         },
  3482.         justifyleft : {
  3483.             title: 'Align Text Left',
  3484.             text: 'Align text to the left.',
  3485.             cls: 'x-html-editor-tip'
  3486.         },
  3487.         justifycenter : {
  3488.             title: 'Center Text',
  3489.             text: 'Center text in the editor.',
  3490.             cls: 'x-html-editor-tip'
  3491.         },
  3492.         justifyright : {
  3493.             title: 'Align Text Right',
  3494.             text: 'Align text to the right.',
  3495.             cls: 'x-html-editor-tip'
  3496.         },
  3497.         insertunorderedlist : {
  3498.             title: 'Bullet List',
  3499.             text: 'Start a bulleted list.',
  3500.             cls: 'x-html-editor-tip'
  3501.         },
  3502.         insertorderedlist : {
  3503.             title: 'Numbered List',
  3504.             text: 'Start a numbered list.',
  3505.             cls: 'x-html-editor-tip'
  3506.         },
  3507.         createlink : {
  3508.             title: 'Hyperlink',
  3509.             text: 'Make the selected text a hyperlink.',
  3510.             cls: 'x-html-editor-tip'
  3511.         },
  3512.         sourceedit : {
  3513.             title: 'Source Edit',
  3514.             text: 'Switch to source editing mode.',
  3515.             cls: 'x-html-editor-tip'
  3516.         }
  3517.     }
  3518.     
  3519.     
  3520.     
  3521.     
  3522.     
  3523.     
  3524.     
  3525.     
  3526.     
  3527.     
  3528.     
  3529.     
  3530.     
  3531.     
  3532.     
  3533.     
  3534.     
  3535.     
  3536.     
  3537.     
  3538.     
  3539.     
  3540.     
  3541.     
  3542.     
  3543.     
  3544.     
  3545.     
  3546.     
  3547.     
  3548.     
  3549.     
  3550.     
  3551.     
  3552. });
  3553. Ext.reg('htmleditor', Ext.form.HtmlEditor);
  3554. Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
  3555.     
  3556.     minValue : undefined,
  3557.     
  3558.     maxValue : undefined,
  3559.     
  3560.     minText : "The time in this field must be equal to or after {0}",
  3561.     
  3562.     maxText : "The time in this field must be equal to or before {0}",
  3563.     
  3564.     invalidText : "{0} is not a valid time",
  3565.     
  3566.     format : "g:i A",
  3567.     
  3568.     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",
  3569.     
  3570.     increment: 15,
  3571.     
  3572.     mode: 'local',
  3573.     
  3574.     triggerAction: 'all',
  3575.     
  3576.     typeAhead: false,
  3577.     
  3578.     
  3579.     
  3580.     
  3581.     initDate: '1/1/2008',
  3582.     
  3583.     initComponent : function(){
  3584.         if(Ext.isDefined(this.minValue)){
  3585.             this.setMinValue(this.minValue, true);
  3586.         }
  3587.         if(Ext.isDefined(this.maxValue)){
  3588.             this.setMaxValue(this.maxValue, true);
  3589.         }
  3590.         if(!this.store){
  3591.             this.generateStore(true);
  3592.         }
  3593.         Ext.form.TimeField.superclass.initComponent.call(this);
  3594.     },
  3595.     
  3596.     
  3597.     setMinValue: function(value,  initial){
  3598.         this.setLimit(value, true, initial);
  3599.         return this;
  3600.     },
  3601.     
  3602.     setMaxValue: function(value,  initial){
  3603.         this.setLimit(value, false, initial);
  3604.         return this;
  3605.     },
  3606.     
  3607.     
  3608.     generateStore: function(initial){
  3609.         var min = this.minValue || new Date(this.initDate).clearTime(),
  3610.             max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
  3611.             times = [];
  3612.             
  3613.         while(min <= max){
  3614.             times.push(min.dateFormat(this.format));
  3615.             min = min.add('mi', this.increment);
  3616.         }
  3617.         this.bindStore(times, initial);
  3618.     },
  3619.     
  3620.     setLimit: function(value, isMin, initial){
  3621.         var d;
  3622.         if(Ext.isString(value)){
  3623.             d = this.parseDate(value);
  3624.         }else if(Ext.isDate(value)){
  3625.             d = value;
  3626.         }
  3627.         if(d){
  3628.             var val = new Date(this.initDate).clearTime();
  3629.             val.setHours(d.getHours(), d.getMinutes(), isMin ? 0 : 59, 0);
  3630.             this[isMin ? 'minValue' : 'maxValue'] = val;
  3631.             if(!initial){
  3632.                 this.generateStore();
  3633.             }
  3634.         }
  3635.     },
  3636.     
  3637.     
  3638.     getValue : function(){
  3639.         var v = Ext.form.TimeField.superclass.getValue.call(this);
  3640.         return this.formatDate(this.parseDate(v)) || '';
  3641.     },
  3642.     
  3643.     setValue : function(value){
  3644.         return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
  3645.     },
  3646.     
  3647.     validateValue : Ext.form.DateField.prototype.validateValue,
  3648.     parseDate : Ext.form.DateField.prototype.parseDate,
  3649.     formatDate : Ext.form.DateField.prototype.formatDate,
  3650.     
  3651.     beforeBlur : function(){
  3652.         var v = this.parseDate(this.getRawValue());
  3653.         if(v){
  3654.             this.setValue(v.dateFormat(this.format));
  3655.         }
  3656.         Ext.form.TimeField.superclass.beforeBlur.call(this);
  3657.     }
  3658.     
  3659.     
  3660.     
  3661.     
  3662. });
  3663. Ext.reg('timefield', Ext.form.TimeField);
  3664. Ext.form.Label = Ext.extend(Ext.BoxComponent, {
  3665.     
  3666.     
  3667.     
  3668.     
  3669.     onRender : function(ct, position){
  3670.         if(!this.el){
  3671.             this.el = document.createElement('label');
  3672.             this.el.id = this.getId();
  3673.             this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
  3674.             if(this.forId){
  3675.                 this.el.setAttribute('for', this.forId);
  3676.             }
  3677.         }
  3678.         Ext.form.Label.superclass.onRender.call(this, ct, position);
  3679.     },
  3680.     
  3681.     setText : function(t, encode){
  3682.         var e = encode === false;
  3683.         this[!e ? 'text' : 'html'] = t;
  3684.         delete this[e ? 'text' : 'html'];
  3685.         if(this.rendered){
  3686.             this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
  3687.         }
  3688.         return this;
  3689.     }
  3690. });
  3691. Ext.reg('label', Ext.form.Label);
  3692. Ext.form.Action = function(form, options){
  3693.     this.form = form;
  3694.     this.options = options || {};
  3695. };
  3696. Ext.form.Action.CLIENT_INVALID = 'client';
  3697. Ext.form.Action.SERVER_INVALID = 'server';
  3698. Ext.form.Action.CONNECT_FAILURE = 'connect';
  3699. Ext.form.Action.LOAD_FAILURE = 'load';
  3700. Ext.form.Action.prototype = {
  3701.     type : 'default',
  3702.  
  3703.  
  3704.     
  3705.     run : function(options){
  3706.     },
  3707.     
  3708.     success : function(response){
  3709.     },
  3710.     
  3711.     handleResponse : function(response){
  3712.     },
  3713.     
  3714.     failure : function(response){
  3715.         this.response = response;
  3716.         this.failureType = Ext.form.Action.CONNECT_FAILURE;
  3717.         this.form.afterAction(this, false);
  3718.     },
  3719.     
  3720.     
  3721.     
  3722.     processResponse : function(response){
  3723.         this.response = response;
  3724.         if(!response.responseText && !response.responseXML){
  3725.             return true;
  3726.         }
  3727.         this.result = this.handleResponse(response);
  3728.         return this.result;
  3729.     },
  3730.     
  3731.     getUrl : function(appendParams){
  3732.         var url = this.options.url || this.form.url || this.form.el.dom.action;
  3733.         if(appendParams){
  3734.             var p = this.getParams();
  3735.             if(p){
  3736.                 url = Ext.urlAppend(url, p);
  3737.             }
  3738.         }
  3739.         return url;
  3740.     },
  3741.     
  3742.     getMethod : function(){
  3743.         return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
  3744.     },
  3745.     
  3746.     getParams : function(){
  3747.         var bp = this.form.baseParams;
  3748.         var p = this.options.params;
  3749.         if(p){
  3750.             if(typeof p == "object"){
  3751.                 p = Ext.urlEncode(Ext.applyIf(p, bp));
  3752.             }else if(typeof p == 'string' && bp){
  3753.                 p += '&' + Ext.urlEncode(bp);
  3754.             }
  3755.         }else if(bp){
  3756.             p = Ext.urlEncode(bp);
  3757.         }
  3758.         return p;
  3759.     },
  3760.     
  3761.     createCallback : function(opts){
  3762.         var opts = opts || {};
  3763.         return {
  3764.             success: this.success,
  3765.             failure: this.failure,
  3766.             scope: this,
  3767.             timeout: (opts.timeout*1000) || (this.form.timeout*1000),
  3768.             upload: this.form.fileUpload ? this.success : undefined
  3769.         };
  3770.     }
  3771. };
  3772. Ext.form.Action.Submit = function(form, options){
  3773.     Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
  3774. };
  3775. Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
  3776.     
  3777.     
  3778.     type : 'submit',
  3779.     
  3780.     run : function(){
  3781.         var o = this.options;
  3782.         var method = this.getMethod();
  3783.         var isGet = method == 'GET';
  3784.         if(o.clientValidation === false || this.form.isValid()){
  3785.             Ext.Ajax.request(Ext.apply(this.createCallback(o), {
  3786.                 form:this.form.el.dom,
  3787.                 url:this.getUrl(isGet),
  3788.                 method: method,
  3789.                 headers: o.headers,
  3790.                 params:!isGet ? this.getParams() : null,
  3791.                 isUpload: this.form.fileUpload
  3792.             }));
  3793.         }else if (o.clientValidation !== false){ 
  3794.             this.failureType = Ext.form.Action.CLIENT_INVALID;
  3795.             this.form.afterAction(this, false);
  3796.         }
  3797.     },
  3798.     
  3799.     success : function(response){
  3800.         var result = this.processResponse(response);
  3801.         if(result === true || result.success){
  3802.             this.form.afterAction(this, true);
  3803.             return;
  3804.         }
  3805.         if(result.errors){
  3806.             this.form.markInvalid(result.errors);
  3807.         }
  3808.         this.failureType = Ext.form.Action.SERVER_INVALID;
  3809.         this.form.afterAction(this, false);
  3810.     },
  3811.     
  3812.     handleResponse : function(response){
  3813.         if(this.form.errorReader){
  3814.             var rs = this.form.errorReader.read(response);
  3815.             var errors = [];
  3816.             if(rs.records){
  3817.                 for(var i = 0, len = rs.records.length; i < len; i++) {
  3818.                     var r = rs.records[i];
  3819.                     errors[i] = r.data;
  3820.                 }
  3821.             }
  3822.             if(errors.length < 1){
  3823.                 errors = null;
  3824.             }
  3825.             return {
  3826.                 success : rs.success,
  3827.                 errors : errors
  3828.             };
  3829.         }
  3830.         return Ext.decode(response.responseText);
  3831.     }
  3832. });
  3833. Ext.form.Action.Load = function(form, options){
  3834.     Ext.form.Action.Load.superclass.constructor.call(this, form, options);
  3835.     this.reader = this.form.reader;
  3836. };
  3837. Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
  3838.     
  3839.     type : 'load',
  3840.     
  3841.     run : function(){
  3842.         Ext.Ajax.request(Ext.apply(
  3843.                 this.createCallback(this.options), {
  3844.                     method:this.getMethod(),
  3845.                     url:this.getUrl(false),
  3846.                     headers: this.options.headers,
  3847.                     params:this.getParams()
  3848.         }));
  3849.     },
  3850.     
  3851.     success : function(response){
  3852.         var result = this.processResponse(response);
  3853.         if(result === true || !result.success || !result.data){
  3854.             this.failureType = Ext.form.Action.LOAD_FAILURE;
  3855.             this.form.afterAction(this, false);
  3856.             return;
  3857.         }
  3858.         this.form.clearInvalid();
  3859.         this.form.setValues(result.data);
  3860.         this.form.afterAction(this, true);
  3861.     },
  3862.     
  3863.     handleResponse : function(response){
  3864.         if(this.form.reader){
  3865.             var rs = this.form.reader.read(response);
  3866.             var data = rs.records && rs.records[0] ? rs.records[0].data : null;
  3867.             return {
  3868.                 success : rs.success,
  3869.                 data : data
  3870.             };
  3871.         }
  3872.         return Ext.decode(response.responseText);
  3873.     }
  3874. });
  3875. Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
  3876.     constructor: function(form, opts) {
  3877.         Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
  3878.     },
  3879.     type : 'directload',
  3880.     run : function(){
  3881.         var args = this.getParams();
  3882.         args.push(this.success, this);
  3883.         this.form.api.load.apply(window, args);
  3884.     },
  3885.     getParams : function() {
  3886.         var buf = [], o = {};
  3887.         var bp = this.form.baseParams;
  3888.         var p = this.options.params;
  3889.         Ext.apply(o, p, bp);
  3890.         var paramOrder = this.form.paramOrder;
  3891.         if(paramOrder){
  3892.             for(var i = 0, len = paramOrder.length; i < len; i++){
  3893.                 buf.push(o[paramOrder[i]]);
  3894.             }
  3895.         }else if(this.form.paramsAsHash){
  3896.             buf.push(o);
  3897.         }
  3898.         return buf;
  3899.     },
  3900.     
  3901.     
  3902.     
  3903.     processResponse : function(result) {
  3904.         this.result = result;
  3905.         return result;
  3906.     },
  3907.     
  3908.     success : function(response, trans){
  3909.         if(trans.type == Ext.Direct.exceptions.SERVER){
  3910.             response = {};
  3911.         }
  3912.         Ext.form.Action.DirectLoad.superclass.success.call(this, response);
  3913.     }
  3914. });
  3915. Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
  3916.     constructor : function(form, opts) {
  3917.         Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
  3918.     },
  3919.     type : 'directsubmit',
  3920.     
  3921.     run : function(){
  3922.         var o = this.options;
  3923.         if(o.clientValidation === false || this.form.isValid()){
  3924.             
  3925.             
  3926.             this.success.params = this.getParams();
  3927.             this.form.api.submit(this.form.el.dom, this.success, this);
  3928.         }else if (o.clientValidation !== false){ 
  3929.             this.failureType = Ext.form.Action.CLIENT_INVALID;
  3930.             this.form.afterAction(this, false);
  3931.         }
  3932.     },
  3933.     getParams : function() {
  3934.         var o = {};
  3935.         var bp = this.form.baseParams;
  3936.         var p = this.options.params;
  3937.         Ext.apply(o, p, bp);
  3938.         return o;
  3939.     },
  3940.     
  3941.     
  3942.     
  3943.     processResponse : function(result) {
  3944.         this.result = result;
  3945.         return result;
  3946.     },
  3947.     
  3948.     success : function(response, trans){
  3949.         if(trans.type == Ext.Direct.exceptions.SERVER){
  3950.             response = {};
  3951.         }
  3952.         Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
  3953.     }
  3954. });
  3955. Ext.form.Action.ACTION_TYPES = {
  3956.     'load' : Ext.form.Action.Load,
  3957.     'submit' : Ext.form.Action.Submit,
  3958.     'directload' : Ext.form.Action.DirectLoad,
  3959.     'directsubmit' : Ext.form.Action.DirectSubmit
  3960. };
  3961. Ext.form.VTypes = function(){
  3962.     
  3963.     var alpha = /^[a-zA-Z_]+$/,
  3964.         alphanum = /^[a-zA-Z0-9_]+$/,
  3965.         email = /^(w+)([-+.][w]+)*@(w[-w]*.){1,5}([A-Za-z]){2,6}$/,
  3966.         url = /(((^https?)|(^ftp))://([-w]+.)+w{2,3}(/[%-w]+(.w{2,})?)*(([w-.?\/+@&#;`~=%!]*)(.w{2,})?)*/?)/i;
  3967.     
  3968.     return {
  3969.         
  3970.         'email' : function(v){
  3971.             return email.test(v);
  3972.         },
  3973.         
  3974.         'emailText' : 'This field should be an e-mail address in the format "user@example.com"',
  3975.         
  3976.         'emailMask' : /[a-z0-9_.-@]/i,
  3977.         
  3978.         'url' : function(v){
  3979.             return url.test(v);
  3980.         },
  3981.         
  3982.         'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
  3983.         
  3984.         
  3985.         'alpha' : function(v){
  3986.             return alpha.test(v);
  3987.         },
  3988.         
  3989.         'alphaText' : 'This field should only contain letters and _',
  3990.         
  3991.         'alphaMask' : /[a-z_]/i,
  3992.         
  3993.         'alphanum' : function(v){
  3994.             return alphanum.test(v);
  3995.         },
  3996.         
  3997.         'alphanumText' : 'This field should only contain letters, numbers and _',
  3998.         
  3999.         'alphanumMask' : /[a-z0-9_]/i
  4000.     };
  4001. }();
  4002. Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
  4003.     
  4004.     autoExpandColumn : false,
  4005.     
  4006.     autoExpandMax : 1000,
  4007.     
  4008.     autoExpandMin : 50,
  4009.     
  4010.     columnLines : false,
  4011.     
  4012.     
  4013.     
  4014.     
  4015.     
  4016.     ddText : '{0} selected row{1}',
  4017.     
  4018.     deferRowRender : true,
  4019.     
  4020.     
  4021.     
  4022.     enableColumnHide : true,
  4023.     
  4024.     enableColumnMove : true,
  4025.     
  4026.     enableDragDrop : false,
  4027.     
  4028.     enableHdMenu : true,
  4029.     
  4030.     
  4031.     loadMask : false,
  4032.     
  4033.     
  4034.     minColumnWidth : 25,
  4035.     
  4036.     
  4037.     
  4038.