ext-all-debug.js
上传用户:zaktkj
上传日期:2022-08-08
资源大小:5770k
文件大小:910k
源码类别:

JavaScript

开发平台:

JavaScript

  1. Ext.menu.Adapter = function(component, config){
  2.     Ext.menu.Adapter.superclass.constructor.call(this, config);
  3.     this.component = component;
  4. };
  5. Ext.extend(Ext.menu.Adapter, Ext.menu.BaseItem, {
  6.         canActivate : true,
  7.         onRender : function(container, position){
  8.         this.component.render(container);
  9.         this.el = this.component.getEl();
  10.     },
  11.         activate : function(){
  12.         if(this.disabled){
  13.             return false;
  14.         }
  15.         this.component.focus();
  16.         this.fireEvent("activate", this);
  17.         return true;
  18.     },
  19.         deactivate : function(){
  20.         this.fireEvent("deactivate", this);
  21.     },
  22.         disable : function(){
  23.         this.component.disable();
  24.         Ext.menu.Adapter.superclass.disable.call(this);
  25.     },
  26.         enable : function(){
  27.         this.component.enable();
  28.         Ext.menu.Adapter.superclass.enable.call(this);
  29.     }
  30. });
  31. Ext.menu.DateItem = function(config){
  32.     Ext.menu.DateItem.superclass.constructor.call(this, new Ext.DatePicker(config), config);
  33.     this.picker = this.component;
  34.     this.addEvents('select');
  35.     this.picker.on("render", function(picker){
  36.         picker.getEl().swallowEvent("click");
  37.         picker.container.addClass("x-menu-date-item");
  38.     });
  39.     this.picker.on("select", this.onSelect, this);
  40. };
  41. Ext.extend(Ext.menu.DateItem, Ext.menu.Adapter, {
  42.         onSelect : function(picker, date){
  43.         this.fireEvent("select", this, date, picker);
  44.         Ext.menu.DateItem.superclass.handleClick.call(this);
  45.     }
  46. });
  47. Ext.menu.ColorItem = function(config){
  48.     Ext.menu.ColorItem.superclass.constructor.call(this, new Ext.ColorPalette(config), config);
  49.     this.palette = this.component;
  50.     this.relayEvents(this.palette, ["select"]);
  51.     if(this.selectHandler){
  52.         this.on('select', this.selectHandler, this.scope);
  53.     }
  54. };
  55. Ext.extend(Ext.menu.ColorItem, Ext.menu.Adapter);
  56. Ext.menu.DateMenu = function(config){
  57.     Ext.menu.DateMenu.superclass.constructor.call(this, config);
  58.     this.plain = true;
  59.     var di = new Ext.menu.DateItem(config);
  60.     this.add(di);
  61.     this.picker = di.picker;
  62.     this.relayEvents(di, ["select"]);
  63.     this.on('beforeshow', function(){
  64.         if(this.picker){
  65.             this.picker.hideMonthPicker(true);
  66.         }
  67.     }, this);
  68. };
  69. Ext.extend(Ext.menu.DateMenu, Ext.menu.Menu, {
  70.     cls:'x-date-menu',
  71.         beforeDestroy : function() {
  72.         this.picker.destroy();
  73.     }
  74. });
  75. Ext.menu.ColorMenu = function(config){
  76.     Ext.menu.ColorMenu.superclass.constructor.call(this, config);
  77.     this.plain = true;
  78.     var ci = new Ext.menu.ColorItem(config);
  79.     this.add(ci);
  80.     this.palette = ci.palette;
  81.     this.relayEvents(ci, ["select"]);
  82. };
  83. Ext.extend(Ext.menu.ColorMenu, Ext.menu.Menu);
  84. Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
  85.     invalidClass : "x-form-invalid",
  86.     invalidText : "The value in this field is invalid",
  87.     focusClass : "x-form-focus",
  88.     validationEvent : "keyup",
  89.     validateOnBlur : true,
  90.     validationDelay : 250,
  91.     defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
  92.     fieldClass : "x-form-field",
  93.     msgTarget : 'qtip',
  94.     msgFx : 'normal',
  95.     readOnly : false,
  96.     disabled : false,
  97.         isFormField : true,
  98.         hasFocus : false,
  99.         initComponent : function(){
  100.         Ext.form.Field.superclass.initComponent.call(this);
  101.         this.addEvents(
  102.             'focus',
  103.             'blur',
  104.             'specialkey',
  105.             'change',
  106.             'invalid',
  107.             'valid'
  108.         );
  109.     },
  110.     getName: function(){
  111.          return this.rendered && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
  112.     },
  113.         onRender : function(ct, position){
  114.         Ext.form.Field.superclass.onRender.call(this, ct, position);
  115.         if(!this.el){
  116.             var cfg = this.getAutoCreate();
  117.             if(!cfg.name){
  118.                 cfg.name = this.name || this.id;
  119.             }
  120.             if(this.inputType){
  121.                 cfg.type = this.inputType;
  122.             }
  123.             this.el = ct.createChild(cfg, position);
  124.         }
  125.         var type = this.el.dom.type;
  126.         if(type){
  127.             if(type == 'password'){
  128.                 type = 'text';
  129.             }
  130.             this.el.addClass('x-form-'+type);
  131.         }
  132.         if(this.readOnly){
  133.             this.el.dom.readOnly = true;
  134.         }
  135.         if(this.tabIndex !== undefined){
  136.             this.el.dom.setAttribute('tabIndex', this.tabIndex);
  137.         }
  138.         this.el.addClass([this.fieldClass, this.cls]);
  139.         this.initValue();
  140.     },
  141.         initValue : function(){
  142.         if(this.value !== undefined){
  143.             this.setValue(this.value);
  144.         }else if(this.el.dom.value.length > 0){
  145.             this.setValue(this.el.dom.value);
  146.         }
  147.     },
  148.     isDirty : function() {
  149.         if(this.disabled) {
  150.             return false;
  151.         }
  152.         return String(this.getValue()) !== String(this.originalValue);
  153.     },
  154.         afterRender : function(){
  155.         Ext.form.Field.superclass.afterRender.call(this);
  156.         this.initEvents();
  157.     },
  158.         fireKey : function(e){
  159.         if(e.isSpecialKey()){
  160.             this.fireEvent("specialkey", this, e);
  161.         }
  162.     },
  163.     reset : function(){
  164.         this.setValue(this.originalValue);
  165.         this.clearInvalid();
  166.     },
  167.         initEvents : function(){
  168.         this.el.on(Ext.isIE ? "keydown" : "keypress", this.fireKey,  this);
  169.         this.el.on("focus", this.onFocus,  this);
  170.         this.el.on("blur", this.onBlur,  this);
  171.                 this.originalValue = this.getValue();
  172.     },
  173.         onFocus : function(){
  174.         if(!Ext.isOpera && this.focusClass){             this.el.addClass(this.focusClass);
  175.         }
  176.         if(!this.hasFocus){
  177.             this.hasFocus = true;
  178.             this.startValue = this.getValue();
  179.             this.fireEvent("focus", this);
  180.         }
  181.     },
  182.     beforeBlur : Ext.emptyFn,
  183.         onBlur : function(){
  184.         this.beforeBlur();
  185.         if(!Ext.isOpera && this.focusClass){             this.el.removeClass(this.focusClass);
  186.         }
  187.         this.hasFocus = false;
  188.         if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
  189.             this.validate();
  190.         }
  191.         var v = this.getValue();
  192.         if(String(v) !== String(this.startValue)){
  193.             this.fireEvent('change', this, v, this.startValue);
  194.         }
  195.         this.fireEvent("blur", this);
  196.     },
  197.     isValid : function(preventMark){
  198.         if(this.disabled){
  199.             return true;
  200.         }
  201.         var restore = this.preventMark;
  202.         this.preventMark = preventMark === true;
  203.         var v = this.validateValue(this.processValue(this.getRawValue()));
  204.         this.preventMark = restore;
  205.         return v;
  206.     },
  207.     validate : function(){
  208.         if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
  209.             this.clearInvalid();
  210.             return true;
  211.         }
  212.         return false;
  213.     },
  214.     processValue : function(value){
  215.         return value;
  216.     },
  217.             validateValue : function(value){
  218.         return true;
  219.     },
  220.     markInvalid : function(msg){
  221.         if(!this.rendered || this.preventMark){             return;
  222.         }
  223.         this.el.addClass(this.invalidClass);
  224.         msg = msg || this.invalidText;
  225.         switch(this.msgTarget){
  226.             case 'qtip':
  227.                 this.el.dom.qtip = msg;
  228.                 this.el.dom.qclass = 'x-form-invalid-tip';
  229.                 if(Ext.QuickTips){                     Ext.QuickTips.enable();
  230.                 }
  231.                 break;
  232.             case 'title':
  233.                 this.el.dom.title = msg;
  234.                 break;
  235.             case 'under':
  236.                 if(!this.errorEl){
  237.                     var elp = this.el.findParent('.x-form-element', 5, true);
  238.                     this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
  239.                     this.errorEl.setWidth(elp.getWidth(true)-20);
  240.                 }
  241.                 this.errorEl.update(msg);
  242.                 Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
  243.                 break;
  244.             case 'side':
  245.                 if(!this.errorIcon){
  246.                     var elp = this.el.findParent('.x-form-element', 5, true);
  247.                     this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
  248.                 }
  249.                 this.alignErrorIcon();
  250.                 this.errorIcon.dom.qtip = msg;
  251.                 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
  252.                 this.errorIcon.show();
  253.                 this.on('resize', this.alignErrorIcon, this);
  254.                 break;
  255.             default:
  256.                 var t = Ext.getDom(this.msgTarget);
  257.                 t.innerHTML = msg;
  258.                 t.style.display = this.msgDisplay;
  259.                 break;
  260.         }
  261.         this.fireEvent('invalid', this, msg);
  262.     },
  263.         alignErrorIcon : function(){
  264.         this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
  265.     },
  266.     clearInvalid : function(){
  267.         if(!this.rendered || this.preventMark){             return;
  268.         }
  269.         this.el.removeClass(this.invalidClass);
  270.         switch(this.msgTarget){
  271.             case 'qtip':
  272.                 this.el.dom.qtip = '';
  273.                 break;
  274.             case 'title':
  275.                 this.el.dom.title = '';
  276.                 break;
  277.             case 'under':
  278.                 if(this.errorEl){
  279.                     Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
  280.                 }
  281.                 break;
  282.             case 'side':
  283.                 if(this.errorIcon){
  284.                     this.errorIcon.dom.qtip = '';
  285.                     this.errorIcon.hide();
  286.                     this.un('resize', this.alignErrorIcon, this);
  287.                 }
  288.                 break;
  289.             default:
  290.                 var t = Ext.getDom(this.msgTarget);
  291.                 t.innerHTML = '';
  292.                 t.style.display = 'none';
  293.                 break;
  294.         }
  295.         this.fireEvent('valid', this);
  296.     },
  297.     getRawValue : function(){
  298.         var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
  299.         if(v === this.emptyText){
  300.             v = '';
  301.         }
  302.         return v;
  303.     },
  304.     getValue : function(){
  305.         if(!this.rendered) {
  306.             return this.value;
  307.         }
  308.         var v = this.el.getValue();
  309.         if(v === this.emptyText || v === undefined){
  310.             v = '';
  311.         }
  312.         return v;
  313.     },
  314.     setRawValue : function(v){
  315.         return this.el.dom.value = (v === null || v === undefined ? '' : v);
  316.     },
  317.     setValue : function(v){
  318.         this.value = v;
  319.         if(this.rendered){
  320.             this.el.dom.value = (v === null || v === undefined ? '' : v);
  321.             this.validate();
  322.         }
  323.     },
  324.     adjustSize : function(w, h){
  325.         var s = Ext.form.Field.superclass.adjustSize.call(this, w, h);
  326.         s.width = this.adjustWidth(this.el.dom.tagName, s.width);
  327.         return s;
  328.     },
  329.     adjustWidth : function(tag, w){
  330.         tag = tag.toLowerCase();
  331.         if(typeof w == 'number' && !Ext.isSafari){
  332.             if(Ext.isIE && (tag == 'input' || tag == 'textarea')){
  333.                 if(tag == 'input' && !Ext.isStrict){
  334.                     return this.inEditor ? w : w - 3;
  335.                 }
  336.                 if(tag == 'input' && Ext.isStrict){
  337.                     return w - (Ext.isIE6 ? 4 : 1);
  338.                 }
  339.                 if(tag = 'textarea' && Ext.isStrict){
  340.                     return w-2;
  341.                 }
  342.             }else if(Ext.isOpera && Ext.isStrict){
  343.                 if(tag == 'input'){
  344.                     return w + 2;
  345.                 }
  346.                 if(tag = 'textarea'){
  347.                     return w-2;
  348.                 }
  349.             }
  350.         }
  351.         return w;
  352.     }
  353. });
  354. Ext.form.Field.msgFx = {
  355.     normal : {
  356.         show: function(msgEl, f){
  357.             msgEl.setDisplayed('block');
  358.         },
  359.         hide : function(msgEl, f){
  360.             msgEl.setDisplayed(false).update('');
  361.         }
  362.     },
  363.     slide : {
  364.         show: function(msgEl, f){
  365.             msgEl.slideIn('t', {stopFx:true});
  366.         },
  367.         hide : function(msgEl, f){
  368.             msgEl.slideOut('t', {stopFx:true,useDisplay:true});
  369.         }
  370.     },
  371.     slideRight : {
  372.         show: function(msgEl, f){
  373.             msgEl.fixDisplay();
  374.             msgEl.alignTo(f.el, 'tl-tr');
  375.             msgEl.slideIn('l', {stopFx:true});
  376.         },
  377.         hide : function(msgEl, f){
  378.             msgEl.slideOut('l', {stopFx:true,useDisplay:true});
  379.         }
  380.     }
  381. };
  382. Ext.reg('field', Ext.form.Field);
  383. Ext.form.TextField = Ext.extend(Ext.form.Field,  {
  384.     grow : false,
  385.     growMin : 30,
  386.     growMax : 800,
  387.     vtype : null,
  388.     maskRe : null,
  389.     disableKeyFilter : false,
  390.     allowBlank : true,
  391.     minLength : 0,
  392.     maxLength : Number.MAX_VALUE,
  393.     minLengthText : "The minimum length for this field is {0}",
  394.     maxLengthText : "The maximum length for this field is {0}",
  395.     selectOnFocus : false,
  396.     blankText : "This field is required",
  397.     validator : null,
  398.     regex : null,
  399.     regexText : "",
  400.     emptyText : null,
  401.     emptyClass : 'x-form-empty-field',
  402.     initComponent : function(){
  403.         Ext.form.TextField.superclass.initComponent.call(this);
  404.         this.addEvents(
  405.             'autosize'
  406.         );
  407.     },
  408.         initEvents : function(){
  409.         Ext.form.TextField.superclass.initEvents.call(this);
  410.         if(this.validationEvent == 'keyup'){
  411.             this.validationTask = new Ext.util.DelayedTask(this.validate, this);
  412.             this.el.on('keyup', this.filterValidation, this);
  413.         }
  414.         else if(this.validationEvent !== false){
  415.             this.el.on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
  416.         }
  417.         if(this.selectOnFocus || this.emptyText){
  418.             this.on("focus", this.preFocus, this);
  419.             if(this.emptyText){
  420.                 this.on('blur', this.postBlur, this);
  421.                 this.applyEmptyText();
  422.             }
  423.         }
  424.         if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
  425.             this.el.on("keypress", this.filterKeys, this);
  426.         }
  427.         if(this.grow){
  428.             this.el.on("keyup", this.onKeyUp,  this, {buffer:50});
  429.             this.el.on("click", this.autoSize,  this);
  430.         }
  431.     },
  432.     processValue : function(value){
  433.         if(this.stripCharsRe){
  434.             var newValue = value.replace(this.stripCharsRe, '');
  435.             if(newValue !== value){
  436.                 this.setRawValue(newValue);
  437.                 return newValue;
  438.             }
  439.         }
  440.         return value;
  441.     },
  442.     filterValidation : function(e){
  443.         if(!e.isNavKeyPress()){
  444.             this.validationTask.delay(this.validationDelay);
  445.         }
  446.     },
  447.         onKeyUp : function(e){
  448.         if(!e.isNavKeyPress()){
  449.             this.autoSize();
  450.         }
  451.     },
  452.     reset : function(){
  453.         Ext.form.TextField.superclass.reset.call(this);
  454.         this.applyEmptyText();
  455.     },
  456.     applyEmptyText : function(){
  457.         if(this.rendered && this.emptyText && this.getRawValue().length < 1){
  458.             this.setRawValue(this.emptyText);
  459.             this.el.addClass(this.emptyClass);
  460.         }
  461.     },
  462.         preFocus : function(){
  463.         if(this.emptyText){
  464.             if(this.el.dom.value == this.emptyText){
  465.                 this.setRawValue('');
  466.             }
  467.             this.el.removeClass(this.emptyClass);
  468.         }
  469.         if(this.selectOnFocus){
  470.             this.el.dom.select();
  471.         }
  472.     },
  473.         postBlur : function(){
  474.         this.applyEmptyText();
  475.     },
  476.         filterKeys : function(e){
  477.         var k = e.getKey();
  478.         if(!Ext.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
  479.             return;
  480.         }
  481.         var c = e.getCharCode(), cc = String.fromCharCode(c);
  482.         if(Ext.isIE && (e.isSpecialKey() || !cc)){
  483.             return;
  484.         }
  485.         if(!this.maskRe.test(cc)){
  486.             e.stopEvent();
  487.         }
  488.     },
  489.     setValue : function(v){
  490.         if(this.emptyText && this.el && v !== undefined && v !== null && v !== ''){
  491.             this.el.removeClass(this.emptyClass);
  492.         }
  493.         Ext.form.TextField.superclass.setValue.apply(this, arguments);
  494.         this.applyEmptyText();
  495.         this.autoSize();
  496.     },
  497.     validateValue : function(value){
  498.         if(value.length < 1 || value === this.emptyText){              if(this.allowBlank){
  499.                  this.clearInvalid();
  500.                  return true;
  501.              }else{
  502.                  this.markInvalid(this.blankText);
  503.                  return false;
  504.              }
  505.         }
  506.         if(value.length < this.minLength){
  507.             this.markInvalid(String.format(this.minLengthText, this.minLength));
  508.             return false;
  509.         }
  510.         if(value.length > this.maxLength){
  511.             this.markInvalid(String.format(this.maxLengthText, this.maxLength));
  512.             return false;
  513.         }
  514.         if(this.vtype){
  515.             var vt = Ext.form.VTypes;
  516.             if(!vt[this.vtype](value, this)){
  517.                 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
  518.                 return false;
  519.             }
  520.         }
  521.         if(typeof this.validator == "function"){
  522.             var msg = this.validator(value);
  523.             if(msg !== true){
  524.                 this.markInvalid(msg);
  525.                 return false;
  526.             }
  527.         }
  528.         if(this.regex && !this.regex.test(value)){
  529.             this.markInvalid(this.regexText);
  530.             return false;
  531.         }
  532.         return true;
  533.     },
  534.     selectText : function(start, end){
  535.         var v = this.getRawValue();
  536.         if(v.length > 0){
  537.             start = start === undefined ? 0 : start;
  538.             end = end === undefined ? v.length : end;
  539.             var d = this.el.dom;
  540.             if(d.setSelectionRange){
  541.                 d.setSelectionRange(start, end);
  542.             }else if(d.createTextRange){
  543.                 var range = d.createTextRange();
  544.                 range.moveStart("character", start);
  545.                 range.moveEnd("character", end-v.length);
  546.                 range.select();
  547.             }
  548.         }
  549.     },
  550.     autoSize : function(){
  551.         if(!this.grow || !this.rendered){
  552.             return;
  553.         }
  554.         if(!this.metrics){
  555.             this.metrics = Ext.util.TextMetrics.createInstance(this.el);
  556.         }
  557.         var el = this.el;
  558.         var v = el.dom.value;
  559.         var d = document.createElement('div');
  560.         d.appendChild(document.createTextNode(v));
  561.         v = d.innerHTML;
  562.         d = null;
  563.         v += "&#160;";
  564.         var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) +  10, this.growMin));
  565.         this.el.setWidth(w);
  566.         this.fireEvent("autosize", this, w);
  567.     }
  568. });
  569. Ext.reg('textfield', Ext.form.TextField);
  570. Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
  571.     defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
  572.     hideTrigger:false,
  573.     autoSize: Ext.emptyFn,
  574.         monitorTab : true,
  575.         deferHeight : true,
  576.         mimicing : false,
  577.         onResize : function(w, h){
  578.         Ext.form.TriggerField.superclass.onResize.call(this, w, h);
  579.         if(typeof w == 'number'){
  580.             this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
  581.         }
  582.         this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
  583.     },
  584.         adjustSize : Ext.BoxComponent.prototype.adjustSize,
  585.         getResizeEl : function(){
  586.         return this.wrap;
  587.     },
  588.         getPositionEl : function(){
  589.         return this.wrap;
  590.     },
  591.         alignErrorIcon : function(){
  592.         this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
  593.     },
  594.         onRender : function(ct, position){
  595.         Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
  596.         this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
  597.         this.trigger = this.wrap.createChild(this.triggerConfig ||
  598.                 {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
  599.         if(this.hideTrigger){
  600.             this.trigger.setDisplayed(false);
  601.         }
  602.         this.initTrigger();
  603.         if(!this.width){
  604.             this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
  605.         }
  606.     },
  607.         initTrigger : function(){
  608.         this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
  609.         this.trigger.addClassOnOver('x-form-trigger-over');
  610.         this.trigger.addClassOnClick('x-form-trigger-click');
  611.     },
  612.         onDestroy : function(){
  613.         if(this.trigger){
  614.             this.trigger.removeAllListeners();
  615.             this.trigger.remove();
  616.         }
  617.         if(this.wrap){
  618.             this.wrap.remove();
  619.         }
  620.         Ext.form.TriggerField.superclass.onDestroy.call(this);
  621.     },
  622.         onFocus : function(){
  623.         Ext.form.TriggerField.superclass.onFocus.call(this);
  624.         if(!this.mimicing){
  625.             this.wrap.addClass('x-trigger-wrap-focus');
  626.             this.mimicing = true;
  627.             Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
  628.             if(this.monitorTab){
  629.                 this.el.on("keydown", this.checkTab, this);
  630.             }
  631.         }
  632.     },
  633.         checkTab : function(e){
  634.         if(e.getKey() == e.TAB){
  635.             this.triggerBlur();
  636.         }
  637.     },
  638.         onBlur : function(){
  639.             },
  640.         mimicBlur : function(e){
  641.         if(!this.wrap.contains(e.target) && this.validateBlur(e)){
  642.             this.triggerBlur();
  643.         }
  644.     },
  645.         triggerBlur : function(){
  646.         this.mimicing = false;
  647.         Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur);
  648.         if(this.monitorTab){
  649.             this.el.un("keydown", this.checkTab, this);
  650.         }
  651.         this.beforeBlur();
  652.         this.wrap.removeClass('x-trigger-wrap-focus');
  653.         Ext.form.TriggerField.superclass.onBlur.call(this);
  654.     },
  655.     beforeBlur : Ext.emptyFn,
  656.             validateBlur : function(e){
  657.         return true;
  658.     },
  659.         onDisable : function(){
  660.         Ext.form.TriggerField.superclass.onDisable.call(this);
  661.         if(this.wrap){
  662.             this.wrap.addClass('x-item-disabled');
  663.         }
  664.     },
  665.         onEnable : function(){
  666.         Ext.form.TriggerField.superclass.onEnable.call(this);
  667.         if(this.wrap){
  668.             this.wrap.removeClass('x-item-disabled');
  669.         }
  670.     },
  671.         onShow : function(){
  672.         if(this.wrap){
  673.             this.wrap.dom.style.display = '';
  674.             this.wrap.dom.style.visibility = 'visible';
  675.         }
  676.     },
  677.         onHide : function(){
  678.         this.wrap.dom.style.display = 'none';
  679.     },
  680.     onTriggerClick : Ext.emptyFn
  681. });
  682. Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
  683.     initComponent : function(){
  684.         Ext.form.TwinTriggerField.superclass.initComponent.call(this);
  685.         this.triggerConfig = {
  686.             tag:'span', cls:'x-form-twin-triggers', cn:[
  687.             {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
  688.             {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
  689.         ]};
  690.     },
  691.     getTrigger : function(index){
  692.         return this.triggers[index];
  693.     },
  694.     initTrigger : function(){
  695.         var ts = this.trigger.select('.x-form-trigger', true);
  696.         this.wrap.setStyle('overflow', 'hidden');
  697.         var triggerField = this;
  698.         ts.each(function(t, all, index){
  699.             t.hide = function(){
  700.                 var w = triggerField.wrap.getWidth();
  701.                 this.dom.style.display = 'none';
  702.                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
  703.             };
  704.             t.show = function(){
  705.                 var w = triggerField.wrap.getWidth();
  706.                 this.dom.style.display = '';
  707.                 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
  708.             };
  709.             var triggerIndex = 'Trigger'+(index+1);
  710.             if(this['hide'+triggerIndex]){
  711.                 t.dom.style.display = 'none';
  712.             }
  713.             t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
  714.             t.addClassOnOver('x-form-trigger-over');
  715.             t.addClassOnClick('x-form-trigger-click');
  716.         }, this);
  717.         this.triggers = ts.elements;
  718.     },
  719.     onTrigger1Click : Ext.emptyFn,
  720.     onTrigger2Click : Ext.emptyFn
  721. });
  722. Ext.reg('trigger', Ext.form.TriggerField);
  723. Ext.form.TextArea = Ext.extend(Ext.form.TextField,  {
  724.     growMin : 60,
  725.     growMax: 1000,
  726.     growAppend : '&#160;n&#160;',
  727.     growPad : 0,
  728.     enterIsSpecial : false,
  729.     preventScrollbars: false,
  730.         onRender : function(ct, position){
  731.         if(!this.el){
  732.             this.defaultAutoCreate = {
  733.                 tag: "textarea",
  734.                 style:"width:100px;height:60px;",
  735.                 autocomplete: "off"
  736.             };
  737.         }
  738.         Ext.form.TextArea.superclass.onRender.call(this, ct, position);
  739.         if(this.grow){
  740.             this.textSizeEl = Ext.DomHelper.append(document.body, {
  741.                 tag: "pre", cls: "x-form-grow-sizer"
  742.             });
  743.             if(this.preventScrollbars){
  744.                 this.el.setStyle("overflow", "hidden");
  745.             }
  746.             this.el.setHeight(this.growMin);
  747.         }
  748.     },
  749.     onDestroy : function(){
  750.         if(this.textSizeEl){
  751.             Ext.removeNode(this.textSizeEl);
  752.         }
  753.         Ext.form.TextArea.superclass.onDestroy.call(this);
  754.     },
  755.     fireKey : function(e){
  756.         if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
  757.             this.fireEvent("specialkey", this, e);
  758.         }
  759.     },
  760.         onKeyUp : function(e){
  761.         if(!e.isNavKeyPress() || e.getKey() == e.ENTER){
  762.             this.autoSize();
  763.         }
  764.     },
  765.     autoSize : function(){
  766.         if(!this.grow || !this.textSizeEl){
  767.             return;
  768.         }
  769.         var el = this.el;
  770.         var v = el.dom.value;
  771.         var ts = this.textSizeEl;
  772.         ts.innerHTML = '';
  773.         ts.appendChild(document.createTextNode(v));
  774.         v = ts.innerHTML;
  775.         Ext.fly(ts).setWidth(this.el.getWidth());
  776.         if(v.length < 1){
  777.             v = "&#160;&#160;";
  778.         }else{
  779.             if(Ext.isIE){
  780.                 v = v.replace(/n/g, '<p>&#160;</p>');
  781.             }
  782.             v += this.growAppend;
  783.         }
  784.         ts.innerHTML = v;
  785.         var h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin)+this.growPad);
  786.         if(h != this.lastHeight){
  787.             this.lastHeight = h;
  788.             this.el.setHeight(h);
  789.             this.fireEvent("autosize", this, h);
  790.         }
  791.     }
  792. });
  793. Ext.reg('textarea', Ext.form.TextArea);
  794. Ext.form.NumberField = Ext.extend(Ext.form.TextField,  {
  795.     fieldClass: "x-form-field x-form-num-field",
  796.     allowDecimals : true,
  797.     decimalSeparator : ".",
  798.     decimalPrecision : 2,
  799.     allowNegative : true,
  800.     minValue : Number.NEGATIVE_INFINITY,
  801.     maxValue : Number.MAX_VALUE,
  802.     minText : "The minimum value for this field is {0}",
  803.     maxText : "The maximum value for this field is {0}",
  804.     nanText : "{0} is not a valid number",
  805.     baseChars : "0123456789",
  806.         initEvents : function(){
  807.         Ext.form.NumberField.superclass.initEvents.call(this);
  808.         var allowed = this.baseChars+'';
  809.         if(this.allowDecimals){
  810.             allowed += this.decimalSeparator;
  811.         }
  812.         if(this.allowNegative){
  813.             allowed += "-";
  814.         }
  815.         this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
  816.         var keyPress = function(e){
  817.             var k = e.getKey();
  818.             if(!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
  819.                 return;
  820.             }
  821.             var c = e.getCharCode();
  822.             if(allowed.indexOf(String.fromCharCode(c)) === -1){
  823.                 e.stopEvent();
  824.             }
  825.         };
  826.         this.el.on("keypress", keyPress, this);
  827.     },
  828.         validateValue : function(value){
  829.         if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
  830.             return false;
  831.         }
  832.         if(value.length < 1){              return true;
  833.         }
  834.         value = String(value).replace(this.decimalSeparator, ".");
  835.         if(isNaN(value)){
  836.             this.markInvalid(String.format(this.nanText, value));
  837.             return false;
  838.         }
  839.         var num = this.parseValue(value);
  840.         if(num < this.minValue){
  841.             this.markInvalid(String.format(this.minText, this.minValue));
  842.             return false;
  843.         }
  844.         if(num > this.maxValue){
  845.             this.markInvalid(String.format(this.maxText, this.maxValue));
  846.             return false;
  847.         }
  848.         return true;
  849.     },
  850.     getValue : function(){
  851.         return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
  852.     },
  853.     setValue : function(v){
  854.         v = parseFloat(v);
  855.         v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
  856.         Ext.form.NumberField.superclass.setValue.call(this, v);
  857.     },
  858.         parseValue : function(value){
  859.         value = parseFloat(String(value).replace(this.decimalSeparator, "."));
  860.         return isNaN(value) ? '' : value;
  861.     },
  862.         fixPrecision : function(value){
  863.         var nan = isNaN(value);
  864.         if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
  865.            return nan ? '' : value;
  866.         }
  867.         return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
  868.     },
  869.     beforeBlur : function(){
  870.         var v = this.parseValue(this.getRawValue());
  871.         if(v){
  872.             this.setValue(this.fixPrecision(v));
  873.         }
  874.     }
  875. });
  876. Ext.reg('numberfield', Ext.form.NumberField);
  877. Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {
  878.     format : "m/d/y",
  879.     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",
  880.     disabledDays : null,
  881.     disabledDaysText : "Disabled",
  882.     disabledDates : null,
  883.     disabledDatesText : "Disabled",
  884.     minValue : null,
  885.     maxValue : null,
  886.     minText : "The date in this field must be equal to or after {0}",
  887.     maxText : "The date in this field must be equal to or before {0}",
  888.     invalidText : "{0} is not a valid date - it must be in the format {1}",
  889.     triggerClass : 'x-form-date-trigger',
  890.         defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
  891.     initComponent : function(){
  892.         Ext.form.DateField.superclass.initComponent.call(this);
  893.         if(typeof this.minValue == "string"){
  894.             this.minValue = this.parseDate(this.minValue);
  895.         }
  896.         if(typeof this.maxValue == "string"){
  897.             this.maxValue = this.parseDate(this.maxValue);
  898.         }
  899.         this.ddMatch = null;
  900.         if(this.disabledDates){
  901.             var dd = this.disabledDates;
  902.             var re = "(?:";
  903.             for(var i = 0; i < dd.length; i++){
  904.                 re += dd[i];
  905.                 if(i != dd.length-1) re += "|";
  906.             }
  907.             this.ddMatch = new RegExp(re + ")");
  908.         }
  909.     },
  910.         validateValue : function(value){
  911.         value = this.formatDate(value);
  912.         if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
  913.             return false;
  914.         }
  915.         if(value.length < 1){              return true;
  916.         }
  917.         var svalue = value;
  918.         value = this.parseDate(value);
  919.         if(!value){
  920.             this.markInvalid(String.format(this.invalidText, svalue, this.format));
  921.             return false;
  922.         }
  923.         var time = value.getTime();
  924.         if(this.minValue && time < this.minValue.getTime()){
  925.             this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
  926.             return false;
  927.         }
  928.         if(this.maxValue && time > this.maxValue.getTime()){
  929.             this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
  930.             return false;
  931.         }
  932.         if(this.disabledDays){
  933.             var day = value.getDay();
  934.             for(var i = 0; i < this.disabledDays.length; i++) {
  935.                 if(day === this.disabledDays[i]){
  936.                     this.markInvalid(this.disabledDaysText);
  937.                     return false;
  938.                 }
  939.             }
  940.         }
  941.         var fvalue = this.formatDate(value);
  942.         if(this.ddMatch && this.ddMatch.test(fvalue)){
  943.             this.markInvalid(String.format(this.disabledDatesText, fvalue));
  944.             return false;
  945.         }
  946.         return true;
  947.     },
  948.             validateBlur : function(){
  949.         return !this.menu || !this.menu.isVisible();
  950.     },
  951.     getValue : function(){
  952.         return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
  953.     },
  954.     setValue : function(date){
  955.         Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
  956.     },
  957.         parseDate : function(value){
  958.         if(!value || Ext.isDate(value)){
  959.             return value;
  960.         }
  961.         var v = Date.parseDate(value, this.format);
  962.         if(!v && this.altFormats){
  963.             if(!this.altFormatsArray){
  964.                 this.altFormatsArray = this.altFormats.split("|");
  965.             }
  966.             for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
  967.                 v = Date.parseDate(value, this.altFormatsArray[i]);
  968.             }
  969.         }
  970.         return v;
  971.     },
  972.         onDestroy : function(){
  973.         if(this.menu) {
  974.             this.menu.destroy();
  975.         }
  976.         if(this.wrap){
  977.             this.wrap.remove();
  978.         }
  979.         Ext.form.DateField.superclass.onDestroy.call(this);
  980.     },
  981.         formatDate : function(date){
  982.         return Ext.isDate(date) ? date.dateFormat(this.format) : date;
  983.     },
  984.         menuListeners : {
  985.         select: function(m, d){
  986.             this.setValue(d);
  987.         },
  988.         show : function(){             this.onFocus();
  989.         },
  990.         hide : function(){
  991.             this.focus.defer(10, this);
  992.             var ml = this.menuListeners;
  993.             this.menu.un("select", ml.select,  this);
  994.             this.menu.un("show", ml.show,  this);
  995.             this.menu.un("hide", ml.hide,  this);
  996.         }
  997.     },
  998.             onTriggerClick : function(){
  999.         if(this.disabled){
  1000.             return;
  1001.         }
  1002.         if(this.menu == null){
  1003.             this.menu = new Ext.menu.DateMenu();
  1004.         }
  1005.         Ext.apply(this.menu.picker,  {
  1006.             minDate : this.minValue,
  1007.             maxDate : this.maxValue,
  1008.             disabledDatesRE : this.ddMatch,
  1009.             disabledDatesText : this.disabledDatesText,
  1010.             disabledDays : this.disabledDays,
  1011.             disabledDaysText : this.disabledDaysText,
  1012.             format : this.format,
  1013.             minText : String.format(this.minText, this.formatDate(this.minValue)),
  1014.             maxText : String.format(this.maxText, this.formatDate(this.maxValue))
  1015.         });
  1016.         this.menu.on(Ext.apply({}, this.menuListeners, {
  1017.             scope:this
  1018.         }));
  1019.         this.menu.picker.setValue(this.getValue() || new Date());
  1020.         this.menu.show(this.el, "tl-bl?");
  1021.     },
  1022.     beforeBlur : function(){
  1023.         var v = this.parseDate(this.getRawValue());
  1024.         if(v){
  1025.             this.setValue(v);
  1026.         }
  1027.     }
  1028. });
  1029. Ext.reg('datefield', Ext.form.DateField);
  1030. Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
  1031.         defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
  1032.     listClass: '',
  1033.     selectedClass: 'x-combo-selected',
  1034.     triggerClass : 'x-form-arrow-trigger',
  1035.     shadow:'sides',
  1036.     listAlign: 'tl-bl?',
  1037.     maxHeight: 300,
  1038.     minHeight: 90,
  1039.     triggerAction: 'query',
  1040.     minChars : 4,
  1041.     typeAhead: false,
  1042.     queryDelay: 500,
  1043.     pageSize: 0,
  1044.     selectOnFocus:false,
  1045.     queryParam: 'query',
  1046.     loadingText: 'Loading...',
  1047.     resizable: false,
  1048.     handleHeight : 8,
  1049.     editable: true,
  1050.     allQuery: '',
  1051.     mode: 'remote',
  1052.     minListWidth : 70,
  1053.     forceSelection:false,
  1054.     typeAheadDelay : 250,
  1055.     lazyInit : true,
  1056.     initComponent : function(){
  1057.         Ext.form.ComboBox.superclass.initComponent.call(this);
  1058.         this.addEvents(
  1059.             'expand',
  1060.             'collapse',
  1061.             'beforeselect',
  1062.             'select',
  1063.             'beforequery'
  1064.         );
  1065.         if(this.transform){
  1066.             this.allowDomMove = false;
  1067.             var s = Ext.getDom(this.transform);
  1068.             if(!this.hiddenName){
  1069.                 this.hiddenName = s.name;
  1070.             }
  1071.             if(!this.store){
  1072.                 this.mode = 'local';
  1073.                 var d = [], opts = s.options;
  1074.                 for(var i = 0, len = opts.length;i < len; i++){
  1075.                     var o = opts[i];
  1076.                     var value = (Ext.isIE ? o.getAttributeNode('value').specified : o.hasAttribute('value')) ? o.value : o.text;
  1077.                     if(o.selected) {
  1078.                         this.value = value;
  1079.                     }
  1080.                     d.push([value, o.text]);
  1081.                 }
  1082.                 this.store = new Ext.data.SimpleStore({
  1083.                     'id': 0,
  1084.                     fields: ['value', 'text'],
  1085.                     data : d
  1086.                 });
  1087.                 this.valueField = 'value';
  1088.                 this.displayField = 'text';
  1089.             }
  1090.             s.name = Ext.id();             if(!this.lazyRender){
  1091.                 this.target = true;
  1092.                 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
  1093.                 Ext.removeNode(s);                 this.render(this.el.parentNode);
  1094.             }else{
  1095.                 Ext.removeNode(s);             }
  1096.         }
  1097.         this.selectedIndex = -1;
  1098.         if(this.mode == 'local'){
  1099.             if(this.initialConfig.queryDelay === undefined){
  1100.                 this.queryDelay = 10;
  1101.             }
  1102.             if(this.initialConfig.minChars === undefined){
  1103.                 this.minChars = 0;
  1104.             }
  1105.         }
  1106.     },
  1107.         onRender : function(ct, position){
  1108.         Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
  1109.         if(this.hiddenName){
  1110.             this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, id: (this.hiddenId||this.hiddenName)},
  1111.                     'before', true);
  1112.             this.hiddenField.value =
  1113.                 this.hiddenValue !== undefined ? this.hiddenValue :
  1114.                 this.value !== undefined ? this.value : '';
  1115.                         this.el.dom.removeAttribute('name');
  1116.         }
  1117.         if(Ext.isGecko){
  1118.             this.el.dom.setAttribute('autocomplete', 'off');
  1119.         }
  1120.         if(!this.lazyInit){
  1121.             this.initList();
  1122.         }else{
  1123.             this.on('focus', this.initList, this, {single: true});
  1124.         }
  1125.         if(!this.editable){
  1126.             this.editable = true;
  1127.             this.setEditable(false);
  1128.         }
  1129.     },
  1130.     initList : function(){
  1131.         if(!this.list){
  1132.             var cls = 'x-combo-list';
  1133.             this.list = new Ext.Layer({
  1134.                 shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
  1135.             });
  1136.             var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
  1137.             this.list.setWidth(lw);
  1138.             this.list.swallowEvent('mousewheel');
  1139.             this.assetHeight = 0;
  1140.             if(this.title){
  1141.                 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
  1142.                 this.assetHeight += this.header.getHeight();
  1143.             }
  1144.             this.innerList = this.list.createChild({cls:cls+'-inner'});
  1145.             this.innerList.on('mouseover', this.onViewOver, this);
  1146.             this.innerList.on('mousemove', this.onViewMove, this);
  1147.             this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
  1148.             if(this.pageSize){
  1149.                 this.footer = this.list.createChild({cls:cls+'-ft'});
  1150.                 this.pageTb = new Ext.PagingToolbar({
  1151.                     store:this.store,
  1152.                     pageSize: this.pageSize,
  1153.                     renderTo:this.footer
  1154.                 });
  1155.                 this.assetHeight += this.footer.getHeight();
  1156.             }
  1157.             if(!this.tpl){
  1158.                 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
  1159.             }
  1160.             this.view = new Ext.DataView({
  1161.                 applyTo: this.innerList,
  1162.                 tpl: this.tpl,
  1163.                 singleSelect: true,
  1164.                 selectedClass: this.selectedClass,
  1165.                 itemSelector: this.itemSelector || '.' + cls + '-item'
  1166.             });
  1167.             this.view.on('click', this.onViewClick, this);
  1168.             this.bindStore(this.store, true);
  1169.             if(this.resizable){
  1170.                 this.resizer = new Ext.Resizable(this.list,  {
  1171.                    pinned:true, handles:'se'
  1172.                 });
  1173.                 this.resizer.on('resize', function(r, w, h){
  1174.                     this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
  1175.                     this.listWidth = w;
  1176.                     this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
  1177.                     this.restrictHeight();
  1178.                 }, this);
  1179.                 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
  1180.             }
  1181.         }
  1182.     },
  1183.         bindStore : function(store, initial){
  1184.         if(this.store && !initial){
  1185.             this.store.un('beforeload', this.onBeforeLoad, this);
  1186.             this.store.un('load', this.onLoad, this);
  1187.             this.store.un('loadexception', this.collapse, this);
  1188.             if(!store){
  1189.                 this.store = null;
  1190.                 if(this.view){
  1191.                     this.view.setStore(null);
  1192.                 }
  1193.             }
  1194.         }
  1195.         if(store){
  1196.             this.store = Ext.StoreMgr.lookup(store);
  1197.             this.store.on('beforeload', this.onBeforeLoad, this);
  1198.             this.store.on('load', this.onLoad, this);
  1199.             this.store.on('loadexception', this.collapse, this);
  1200.             if(this.view){
  1201.                 this.view.setStore(store);
  1202.             }
  1203.         }
  1204.     },
  1205.         initEvents : function(){
  1206.         Ext.form.ComboBox.superclass.initEvents.call(this);
  1207.         this.keyNav = new Ext.KeyNav(this.el, {
  1208.             "up" : function(e){
  1209.                 this.inKeyMode = true;
  1210.                 this.selectPrev();
  1211.             },
  1212.             "down" : function(e){
  1213.                 if(!this.isExpanded()){
  1214.                     this.onTriggerClick();
  1215.                 }else{
  1216.                     this.inKeyMode = true;
  1217.                     this.selectNext();
  1218.                 }
  1219.             },
  1220.             "enter" : function(e){
  1221.                 this.onViewClick();
  1222.                 this.delayedCheck = true;
  1223.                 this.unsetDelayCheck.defer(10, this);
  1224.             },
  1225.             "esc" : function(e){
  1226.                 this.collapse();
  1227.             },
  1228.             "tab" : function(e){
  1229.                 this.onViewClick(false);
  1230.                 return true;
  1231.             },
  1232.             scope : this,
  1233.             doRelay : function(foo, bar, hname){
  1234.                 if(hname == 'down' || this.scope.isExpanded()){
  1235.                    return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
  1236.                 }
  1237.                 return true;
  1238.             },
  1239.             forceKeyDown : true
  1240.         });
  1241.         this.queryDelay = Math.max(this.queryDelay || 10,
  1242.                 this.mode == 'local' ? 10 : 250);
  1243.         this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
  1244.         if(this.typeAhead){
  1245.             this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
  1246.         }
  1247.         if(this.editable !== false){
  1248.             this.el.on("keyup", this.onKeyUp, this);
  1249.         }
  1250.         if(this.forceSelection){
  1251.             this.on('blur', this.doForce, this);
  1252.         }
  1253.     },
  1254.     onDestroy : function(){
  1255.         if(this.view){
  1256.             this.view.el.removeAllListeners();
  1257.             this.view.el.remove();
  1258.             this.view.purgeListeners();
  1259.         }
  1260.         if(this.list){
  1261.             this.list.destroy();
  1262.         }
  1263.         this.bindStore(null);
  1264.         Ext.form.ComboBox.superclass.onDestroy.call(this);
  1265.     },
  1266.     unsetDelayCheck : function(){
  1267.         delete this.delayedCheck;
  1268.     },
  1269.         fireKey : function(e){
  1270.         if(e.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck){
  1271.             this.fireEvent("specialkey", this, e);
  1272.         }
  1273.     },
  1274.         onResize: function(w, h){
  1275.         Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
  1276.         if(this.list && this.listWidth === undefined){
  1277.             var lw = Math.max(w, this.minListWidth);
  1278.             this.list.setWidth(lw);
  1279.             this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
  1280.         }
  1281.     },
  1282.         onEnable: function(){
  1283.         Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
  1284.         if(this.hiddenField){
  1285.             this.hiddenField.disabled = false;
  1286.         }
  1287.     },
  1288.         onDisable: function(){
  1289.         Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
  1290.         if(this.hiddenField){
  1291.             this.hiddenField.disabled = true;
  1292.         }
  1293.     },
  1294.     setEditable : function(value){
  1295.         if(value == this.editable){
  1296.             return;
  1297.         }
  1298.         this.editable = value;
  1299.         if(!value){
  1300.             this.el.dom.setAttribute('readOnly', true);
  1301.             this.el.on('mousedown', this.onTriggerClick,  this);
  1302.             this.el.addClass('x-combo-noedit');
  1303.         }else{
  1304.             this.el.dom.setAttribute('readOnly', false);
  1305.             this.el.un('mousedown', this.onTriggerClick,  this);
  1306.             this.el.removeClass('x-combo-noedit');
  1307.         }
  1308.     },
  1309.         onBeforeLoad : function(){
  1310.         if(!this.hasFocus){
  1311.             return;
  1312.         }
  1313.         this.innerList.update(this.loadingText ?
  1314.                '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
  1315.         this.restrictHeight();
  1316.         this.selectedIndex = -1;
  1317.     },
  1318.         onLoad : function(){
  1319.         if(!this.hasFocus){
  1320.             return;
  1321.         }
  1322.         if(this.store.getCount() > 0){
  1323.             this.expand();
  1324.             this.restrictHeight();
  1325.             if(this.lastQuery == this.allQuery){
  1326.                 if(this.editable){
  1327.                     this.el.dom.select();
  1328.                 }
  1329.                 if(!this.selectByValue(this.value, true)){
  1330.                     this.select(0, true);
  1331.                 }
  1332.             }else{
  1333.                 this.selectNext();
  1334.                 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
  1335.                     this.taTask.delay(this.typeAheadDelay);
  1336.                 }
  1337.             }
  1338.         }else{
  1339.             this.onEmptyResults();
  1340.         }
  1341.             },
  1342.         onTypeAhead : function(){
  1343.         if(this.store.getCount() > 0){
  1344.             var r = this.store.getAt(0);
  1345.             var newValue = r.data[this.displayField];
  1346.             var len = newValue.length;
  1347.             var selStart = this.getRawValue().length;
  1348.             if(selStart != len){
  1349.                 this.setRawValue(newValue);
  1350.                 this.selectText(selStart, newValue.length);
  1351.             }
  1352.         }
  1353.     },
  1354.         onSelect : function(record, index){
  1355.         if(this.fireEvent('beforeselect', this, record, index) !== false){
  1356.             this.setValue(record.data[this.valueField || this.displayField]);
  1357.             this.collapse();
  1358.             this.fireEvent('select', this, record, index);
  1359.         }
  1360.     },
  1361.     getValue : function(){
  1362.         if(this.valueField){
  1363.             return typeof this.value != 'undefined' ? this.value : '';
  1364.         }else{
  1365.             return Ext.form.ComboBox.superclass.getValue.call(this);
  1366.         }
  1367.     },
  1368.     clearValue : function(){
  1369.         if(this.hiddenField){
  1370.             this.hiddenField.value = '';
  1371.         }
  1372.         this.setRawValue('');
  1373.         this.lastSelectionText = '';
  1374.         this.applyEmptyText();
  1375.         this.value = '';
  1376.     },
  1377.     setValue : function(v){
  1378.         var text = v;
  1379.         if(this.valueField){
  1380.             var r = this.findRecord(this.valueField, v);
  1381.             if(r){
  1382.                 text = r.data[this.displayField];
  1383.             }else if(this.valueNotFoundText !== undefined){
  1384.                 text = this.valueNotFoundText;
  1385.             }
  1386.         }
  1387.         this.lastSelectionText = text;
  1388.         if(this.hiddenField){
  1389.             this.hiddenField.value = v;
  1390.         }
  1391.         Ext.form.ComboBox.superclass.setValue.call(this, text);
  1392.         this.value = v;
  1393.     },
  1394.         findRecord : function(prop, value){
  1395.         var record;
  1396.         if(this.store.getCount() > 0){
  1397.             this.store.each(function(r){
  1398.                 if(r.data[prop] == value){
  1399.                     record = r;
  1400.                     return false;
  1401.                 }
  1402.             });
  1403.         }
  1404.         return record;
  1405.     },
  1406.         onViewMove : function(e, t){
  1407.         this.inKeyMode = false;
  1408.     },
  1409.         onViewOver : function(e, t){
  1410.         if(this.inKeyMode){             return;
  1411.         }
  1412.         var item = this.view.findItemFromChild(t);
  1413.         if(item){
  1414.             var index = this.view.indexOf(item);
  1415.             this.select(index, false);
  1416.         }
  1417.     },
  1418.         onViewClick : function(doFocus){
  1419.         var index = this.view.getSelectedIndexes()[0];
  1420.         var r = this.store.getAt(index);
  1421.         if(r){
  1422.             this.onSelect(r, index);
  1423.         }
  1424.         if(doFocus !== false){
  1425.             this.el.focus();
  1426.         }
  1427.     },
  1428.         restrictHeight : function(){
  1429.         this.innerList.dom.style.height = '';
  1430.         var inner = this.innerList.dom;
  1431.         var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
  1432.         var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
  1433.         var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
  1434.         var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
  1435.         var space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadow.offset-pad-2;
  1436.         h = Math.min(h, space, this.maxHeight);
  1437.         this.innerList.setHeight(h);
  1438.         this.list.beginUpdate();
  1439.         this.list.setHeight(h+pad);
  1440.         this.list.alignTo(this.el, this.listAlign);
  1441.         this.list.endUpdate();
  1442.     },
  1443.         onEmptyResults : function(){
  1444.         this.collapse();
  1445.     },
  1446.     isExpanded : function(){
  1447.         return this.list && this.list.isVisible();
  1448.     },
  1449.     selectByValue : function(v, scrollIntoView){
  1450.         if(v !== undefined && v !== null){
  1451.             var r = this.findRecord(this.valueField || this.displayField, v);
  1452.             if(r){
  1453.                 this.select(this.store.indexOf(r), scrollIntoView);
  1454.                 return true;
  1455.             }
  1456.         }
  1457.         return false;
  1458.     },
  1459.     select : function(index, scrollIntoView){
  1460.         this.selectedIndex = index;
  1461.         this.view.select(index);
  1462.         if(scrollIntoView !== false){
  1463.             var el = this.view.getNode(index);
  1464.             if(el){
  1465.                 this.innerList.scrollChildIntoView(el, false);
  1466.             }
  1467.         }
  1468.     },
  1469.         selectNext : function(){
  1470.         var ct = this.store.getCount();
  1471.         if(ct > 0){
  1472.             if(this.selectedIndex == -1){
  1473.                 this.select(0);
  1474.             }else if(this.selectedIndex < ct-1){
  1475.                 this.select(this.selectedIndex+1);
  1476.             }
  1477.         }
  1478.     },
  1479.         selectPrev : function(){
  1480.         var ct = this.store.getCount();
  1481.         if(ct > 0){
  1482.             if(this.selectedIndex == -1){
  1483.                 this.select(0);
  1484.             }else if(this.selectedIndex != 0){
  1485.                 this.select(this.selectedIndex-1);
  1486.             }
  1487.         }
  1488.     },
  1489.         onKeyUp : function(e){
  1490.         if(this.editable !== false && !e.isSpecialKey()){
  1491.             this.lastKey = e.getKey();
  1492.             this.dqTask.delay(this.queryDelay);
  1493.         }
  1494.     },
  1495.         validateBlur : function(){
  1496.         return !this.list || !this.list.isVisible();
  1497.     },
  1498.         initQuery : function(){
  1499.         this.doQuery(this.getRawValue());
  1500.     },
  1501.         doForce : function(){
  1502.         if(this.el.dom.value.length > 0){
  1503.             this.el.dom.value =
  1504.                 this.lastSelectionText === undefined ? '' : this.lastSelectionText;
  1505.             this.applyEmptyText();
  1506.         }
  1507.     },
  1508.     doQuery : function(q, forceAll){
  1509.         if(q === undefined || q === null){
  1510.             q = '';
  1511.         }
  1512.         var qe = {
  1513.             query: q,
  1514.             forceAll: forceAll,
  1515.             combo: this,
  1516.             cancel:false
  1517.         };
  1518.         if(this.fireEvent('beforequery', qe)===false || qe.cancel){
  1519.             return false;
  1520.         }
  1521.         q = qe.query;
  1522.         forceAll = qe.forceAll;
  1523.         if(forceAll === true || (q.length >= this.minChars)){
  1524.             if(this.lastQuery !== q){
  1525.                 this.lastQuery = q;
  1526.                 if(this.mode == 'local'){
  1527.                     this.selectedIndex = -1;
  1528.                     if(forceAll){
  1529.                         this.store.clearFilter();
  1530.                     }else{
  1531.                         this.store.filter(this.displayField, q);
  1532.                     }
  1533.                     this.onLoad();
  1534.                 }else{
  1535.                     this.store.baseParams[this.queryParam] = q;
  1536.                     this.store.load({
  1537.                         params: this.getParams(q)
  1538.                     });
  1539.                     this.expand();
  1540.                 }
  1541.             }else{
  1542.                 this.selectedIndex = -1;
  1543.                 this.onLoad();
  1544.             }
  1545.         }
  1546.     },
  1547.         getParams : function(q){
  1548.         var p = {};
  1549.                 if(this.pageSize){
  1550.             p.start = 0;
  1551.             p.limit = this.pageSize;
  1552.         }
  1553.         return p;
  1554.     },
  1555.     collapse : function(){
  1556.         if(!this.isExpanded()){
  1557.             return;
  1558.         }
  1559.         this.list.hide();
  1560.         Ext.getDoc().un('mousewheel', this.collapseIf, this);
  1561.         Ext.getDoc().un('mousedown', this.collapseIf, this);
  1562.         this.fireEvent('collapse', this);
  1563.     },
  1564.         collapseIf : function(e){
  1565.         if(!e.within(this.wrap) && !e.within(this.list)){
  1566.             this.collapse();
  1567.         }
  1568.     },
  1569.     expand : function(){
  1570.         if(this.isExpanded() || !this.hasFocus){
  1571.             return;
  1572.         }
  1573.         this.list.alignTo(this.wrap, this.listAlign);
  1574.         this.list.show();
  1575.         this.innerList.setOverflow('auto');         Ext.getDoc().on('mousewheel', this.collapseIf, this);
  1576.         Ext.getDoc().on('mousedown', this.collapseIf, this);
  1577.         this.fireEvent('expand', this);
  1578.     },
  1579.             onTriggerClick : function(){
  1580.         if(this.disabled){
  1581.             return;
  1582.         }
  1583.         if(this.isExpanded()){
  1584.             this.collapse();
  1585.             this.el.focus();
  1586.         }else {
  1587.             this.onFocus({});
  1588.             if(this.triggerAction == 'all') {
  1589.                 this.doQuery(this.allQuery, true);
  1590.             } else {
  1591.                 this.doQuery(this.getRawValue());
  1592.             }
  1593.             this.el.focus();
  1594.         }
  1595.     }
  1596. });
  1597. Ext.reg('combo', Ext.form.ComboBox);
  1598. Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
  1599.     focusClass : undefined,
  1600.     fieldClass: "x-form-field",
  1601.     checked: false,
  1602.     defaultAutoCreate : { tag: "input", type: 'checkbox', autocomplete: "off"},
  1603.         initComponent : function(){
  1604.         Ext.form.Checkbox.superclass.initComponent.call(this);
  1605.         this.addEvents(
  1606.             'check'
  1607.         );
  1608.     },
  1609.         onResize : function(){
  1610.         Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
  1611.         if(!this.boxLabel){
  1612.             this.el.alignTo(this.wrap, 'c-c');
  1613.         }
  1614.     },
  1615.         initEvents : function(){
  1616.         Ext.form.Checkbox.superclass.initEvents.call(this);
  1617.         this.el.on("click", this.onClick,  this);
  1618.         this.el.on("change", this.onClick,  this);
  1619.     },
  1620.         getResizeEl : function(){
  1621.         return this.wrap;
  1622.     },
  1623.         getPositionEl : function(){
  1624.         return this.wrap;
  1625.     },
  1626.     markInvalid : Ext.emptyFn,
  1627.     clearInvalid : Ext.emptyFn,
  1628.         onRender : function(ct, position){
  1629.         Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
  1630.         if(this.inputValue !== undefined){
  1631.             this.el.dom.value = this.inputValue;
  1632.         }
  1633.         this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
  1634.         if(this.boxLabel){
  1635.             this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
  1636.         }
  1637.         if(this.checked){
  1638.             this.setValue(true);
  1639.         }else{
  1640.             this.checked = this.el.dom.checked;
  1641.         }
  1642.     },
  1643.         onDestroy : function(){
  1644.         if(this.wrap){
  1645.             this.wrap.remove();
  1646.         }
  1647.         Ext.form.Checkbox.superclass.onDestroy.call(this);
  1648.     },
  1649.         initValue : Ext.emptyFn,
  1650.     getValue : function(){
  1651.         if(this.rendered){
  1652.             return this.el.dom.checked;
  1653.         }
  1654.         return false;
  1655.     },
  1656.         onClick : function(){
  1657.         if(this.el.dom.checked != this.checked){
  1658.             this.setValue(this.el.dom.checked);
  1659.         }
  1660.     },
  1661.     setValue : function(v){
  1662.         this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
  1663.         if(this.el && this.el.dom){
  1664.             this.el.dom.checked = this.checked;
  1665.             this.el.dom.defaultChecked = this.checked;
  1666.         }
  1667.         this.fireEvent("check", this, this.checked);
  1668.     }
  1669. });
  1670. Ext.reg('checkbox', Ext.form.Checkbox);
  1671. Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
  1672.     inputType: 'radio',
  1673.     markInvalid : Ext.emptyFn,
  1674.     clearInvalid : Ext.emptyFn,
  1675.     getGroupValue : function(){
  1676.         var p = this.el.up('form') || Ext.getBody();
  1677.         var c = p.child('input[name='+this.el.dom.name+']:checked', true);
  1678.         return c ? c.value : null;
  1679.     },
  1680.         onClick : function(){
  1681.         if(this.el.dom.checked != this.checked){
  1682.             var p = this.el.up('form') || Ext.getBody();
  1683.             var els = p.select('input[name='+this.el.dom.name+']');
  1684.             els.each(function(el){
  1685.                 if(el.dom.id == this.id){
  1686.                     this.setValue(true);
  1687.                 }else{
  1688.                     Ext.getCmp(el.dom.id).setValue(false);
  1689.                 }
  1690.             }, this);
  1691.         }
  1692.     },
  1693.     setValue : function(v){
  1694.         if (typeof v == 'boolean') {
  1695.             Ext.form.Radio.superclass.setValue.call(this, v);
  1696.         } else {
  1697.             var r = this.el.up('form').child('input[name='+this.el.dom.name+'][value='+v+']', true);
  1698.             if (r){
  1699.                 r.checked = true;
  1700.             };
  1701.         }
  1702.     }
  1703. });
  1704. Ext.reg('radio', Ext.form.Radio);
  1705. Ext.form.Hidden = Ext.extend(Ext.form.Field, {
  1706.     inputType : 'hidden',
  1707.     onRender : function(){
  1708.         Ext.form.Hidden.superclass.onRender.apply(this, arguments);
  1709.     },
  1710.     initEvents : function(){
  1711.         this.originalValue = this.getValue();
  1712.     },
  1713.     setSize : Ext.emptyFn,
  1714.     setWidth : Ext.emptyFn,
  1715.     setHeight : Ext.emptyFn,
  1716.     setPosition : Ext.emptyFn,
  1717.     setPagePosition : Ext.emptyFn,
  1718.     markInvalid : Ext.emptyFn,
  1719.     clearInvalid : Ext.emptyFn
  1720. });
  1721. Ext.reg('hidden', Ext.form.Hidden);
  1722. Ext.form.BasicForm = function(el, config){
  1723.     Ext.apply(this, config);
  1724.     this.items = new Ext.util.MixedCollection(false, function(o){
  1725.         return o.id || (o.id = Ext.id());
  1726.     });
  1727.     this.addEvents(
  1728.         'beforeaction',
  1729.         'actionfailed',
  1730.         'actioncomplete'
  1731.     );
  1732.     if(el){
  1733.         this.initEl(el);
  1734.     }
  1735.     Ext.form.BasicForm.superclass.constructor.call(this);
  1736. };
  1737. Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
  1738.     timeout: 30,
  1739.         activeAction : null,
  1740.     trackResetOnLoad : false,
  1741.         initEl : function(el){
  1742.         this.el = Ext.get(el);
  1743.         this.id = this.el.id || Ext.id();
  1744.         if(!this.standardSubmit){
  1745.             this.el.on('submit', this.onSubmit, this);
  1746.         }
  1747.         this.el.addClass('x-form');
  1748.     },
  1749.     getEl: function(){
  1750.         return this.el;
  1751.     },
  1752.         onSubmit : function(e){
  1753.         e.stopEvent();
  1754.     },
  1755.         destroy: function() {
  1756.         this.items.each(function(f){
  1757.             Ext.destroy(f);
  1758.         });
  1759.         if(this.el){
  1760.             this.el.removeAllListeners();
  1761.             this.el.remove();
  1762.         }
  1763.         this.purgeListeners();
  1764.     },
  1765.     isValid : function(){
  1766.         var valid = true;
  1767.         this.items.each(function(f){
  1768.            if(!f.validate()){
  1769.                valid = false;
  1770.            }
  1771.         });
  1772.         return valid;
  1773.     },
  1774.     isDirty : function(){
  1775.         var dirty = false;
  1776.         this.items.each(function(f){
  1777.            if(f.isDirty()){
  1778.                dirty = true;
  1779.                return false;
  1780.            }
  1781.         });
  1782.         return dirty;
  1783.     },
  1784.     doAction : function(action, options){
  1785.         if(typeof action == 'string'){
  1786.             action = new Ext.form.Action.ACTION_TYPES[action](this, options);
  1787.         }
  1788.         if(this.fireEvent('beforeaction', this, action) !== false){
  1789.             this.beforeAction(action);
  1790.             action.run.defer(100, action);
  1791.         }
  1792.         return this;
  1793.     },
  1794.     submit : function(options){
  1795.         if(this.standardSubmit){
  1796.             var v = this.isValid();
  1797.             if(v){
  1798.                 this.el.dom.submit();
  1799.             }
  1800.             return v;
  1801.         }
  1802.         this.doAction('submit', options);
  1803.         return this;
  1804.     },
  1805.     load : function(options){
  1806.         this.doAction('load', options);
  1807.         return this;
  1808.     },
  1809.     updateRecord : function(record){
  1810.         record.beginEdit();
  1811.         var fs = record.fields;
  1812.         fs.each(function(f){
  1813.             var field = this.findField(f.name);
  1814.             if(field){
  1815.                 record.set(f.name, field.getValue());
  1816.             }
  1817.         }, this);
  1818.         record.endEdit();
  1819.         return this;
  1820.     },
  1821.     loadRecord : function(record){
  1822.         this.setValues(record.data);
  1823.         return this;
  1824.     },
  1825.         beforeAction : function(action){
  1826.         var o = action.options;
  1827.         if(o.waitMsg){
  1828.             if(this.waitMsgTarget === true){
  1829.                 this.el.mask(o.waitMsg, 'x-mask-loading');
  1830.             }else if(this.waitMsgTarget){
  1831.                 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
  1832.                 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
  1833.             }else{
  1834.                 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
  1835.             }
  1836.         }
  1837.     },
  1838.         afterAction : function(action, success){
  1839.         this.activeAction = null;
  1840.         var o = action.options;
  1841.         if(o.waitMsg){
  1842.             if(this.waitMsgTarget === true){
  1843.                 this.el.unmask();
  1844.             }else if(this.waitMsgTarget){
  1845.                 this.waitMsgTarget.unmask();
  1846.             }else{
  1847.                 Ext.MessageBox.updateProgress(1);
  1848.                 Ext.MessageBox.hide();
  1849.             }
  1850.         }
  1851.         if(success){
  1852.             if(o.reset){
  1853.                 this.reset();
  1854.             }
  1855.             Ext.callback(o.success, o.scope, [this, action]);
  1856.             this.fireEvent('actioncomplete', this, action);
  1857.         }else{
  1858.             Ext.callback(o.failure, o.scope, [this, action]);
  1859.             this.fireEvent('actionfailed', this, action);
  1860.         }
  1861.     },
  1862.     findField : function(id){
  1863.         var field = this.items.get(id);
  1864.         if(!field){
  1865.             this.items.each(function(f){
  1866.                 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
  1867.                     field = f;
  1868.                     return false;
  1869.                 }
  1870.             });
  1871.         }
  1872.         return field || null;
  1873.     },
  1874.     markInvalid : function(errors){
  1875.         if(Ext.isArray(errors)){
  1876.             for(var i = 0, len = errors.length; i < len; i++){
  1877.                 var fieldError = errors[i];
  1878.                 var f = this.findField(fieldError.id);
  1879.                 if(f){
  1880.                     f.markInvalid(fieldError.msg);
  1881.                 }
  1882.             }
  1883.         }else{
  1884.             var field, id;
  1885.             for(id in errors){
  1886.                 if(typeof errors[id] != 'function' && (field = this.findField(id))){
  1887.                     field.markInvalid(errors[id]);
  1888.                 }
  1889.             }
  1890.         }
  1891.         return this;
  1892.     },
  1893.     setValues : function(values){
  1894.         if(Ext.isArray(values)){             for(var i = 0, len = values.length; i < len; i++){
  1895.                 var v = values[i];
  1896.                 var f = this.findField(v.id);
  1897.                 if(f){
  1898.                     f.setValue(v.value);
  1899.                     if(this.trackResetOnLoad){
  1900.                         f.originalValue = f.getValue();
  1901.                     }
  1902.                 }
  1903.             }
  1904.         }else{             var field, id;
  1905.             for(id in values){
  1906.                 if(typeof values[id] != 'function' && (field = this.findField(id))){
  1907.                     field.setValue(values[id]);
  1908.                     if(this.trackResetOnLoad){
  1909.                         field.originalValue = field.getValue();
  1910.                     }
  1911.                 }
  1912.             }
  1913.         }
  1914.         return this;
  1915.     },
  1916.     getValues : function(asString){
  1917.         var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
  1918.         if(asString === true){
  1919.             return fs;
  1920.         }
  1921.         return Ext.urlDecode(fs);
  1922.     },
  1923.     clearInvalid : function(){
  1924.         this.items.each(function(f){
  1925.            f.clearInvalid();
  1926.         });
  1927.         return this;
  1928.     },
  1929.     reset : function(){
  1930.         this.items.each(function(f){
  1931.             f.reset();
  1932.         });
  1933.         return this;
  1934.     },
  1935.     add : function(){
  1936.         this.items.addAll(Array.prototype.slice.call(arguments, 0));
  1937.         return this;
  1938.     },
  1939.     remove : function(field){
  1940.         this.items.remove(field);
  1941.         return this;
  1942.     },
  1943.     render : function(){
  1944.         this.items.each(function(f){
  1945.             if(f.isFormField && !f.rendered && document.getElementById(f.id)){                 f.applyToMarkup(f.id);
  1946.             }
  1947.         });
  1948.         return this;
  1949.     },
  1950.     applyToFields : function(o){
  1951.         this.items.each(function(f){
  1952.            Ext.apply(f, o);
  1953.         });
  1954.         return this;
  1955.     },
  1956.     applyIfToFields : function(o){
  1957.         this.items.each(function(f){
  1958.            Ext.applyIf(f, o);
  1959.         });
  1960.         return this;
  1961.     }
  1962. });
  1963. Ext.BasicForm = Ext.form.BasicForm;
  1964. Ext.FormPanel = Ext.extend(Ext.Panel, {
  1965.     buttonAlign:'center',
  1966.     minButtonWidth:75,
  1967.     labelAlign:'left',
  1968.     monitorValid : false,
  1969.     monitorPoll : 200,
  1970.     layout: 'form',
  1971.         initComponent :function(){
  1972.         this.form = this.createForm();
  1973.         Ext.FormPanel.superclass.initComponent.call(this);
  1974.         this.addEvents(
  1975.             'clientvalidation'
  1976.         );
  1977.         this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
  1978.     },
  1979.         createForm: function(){
  1980.         delete this.initialConfig.listeners;
  1981.         return new Ext.form.BasicForm(null, this.initialConfig);
  1982.     },
  1983.         initFields : function(){
  1984.         var f = this.form;
  1985.         var formPanel = this;
  1986.         var fn = function(c){
  1987.             if(c.doLayout && c != formPanel){
  1988.                 Ext.applyIf(c, {
  1989.                     labelAlign: c.ownerCt.labelAlign,
  1990.                     labelWidth: c.ownerCt.labelWidth,
  1991.                     itemCls: c.ownerCt.itemCls
  1992.                 });
  1993.                 if(c.items){
  1994.                     c.items.each(fn);
  1995.                 }
  1996.             }else if(c.isFormField){
  1997.                 f.add(c);
  1998.             }
  1999.         }
  2000.         this.items.each(fn);
  2001.     },
  2002.         getLayoutTarget : function(){
  2003.         return this.form.el;
  2004.     },
  2005.     getForm : function(){
  2006.         return this.form;
  2007.     },
  2008.         onRender : function(ct, position){
  2009.         this.initFields();
  2010.         Ext.FormPanel.superclass.onRender.call(this, ct, position);
  2011.         var o = {
  2012.             tag: 'form',
  2013.             method : this.method || 'POST',
  2014.             id : this.formId || Ext.id()
  2015.         };
  2016.         if(this.fileUpload) {
  2017.             o.enctype = 'multipart/form-data';
  2018.         }
  2019.         this.form.initEl(this.body.createChild(o));
  2020.     },
  2021.         beforeDestroy: function(){
  2022.         Ext.FormPanel.superclass.beforeDestroy.call(this);
  2023.         Ext.destroy(this.form);
  2024.     },
  2025.         initEvents : function(){
  2026.         Ext.FormPanel.superclass.initEvents.call(this);
  2027.         this.items.on('remove', this.onRemove, this);
  2028.         this.items.on('add', this.onAdd, this);
  2029.         if(this.monitorValid){             this.startMonitoring();
  2030.         }
  2031.     },
  2032.         onAdd : function(ct, c) {
  2033.         if (c.isFormField) {
  2034.             this.form.add(c);
  2035.         }
  2036.     },
  2037.         onRemove : function(c) {
  2038.         if (c.isFormField) {
  2039.             Ext.destroy(c.container.up('.x-form-item'));
  2040.             this.form.remove(c);
  2041.         }
  2042.     },
  2043.     startMonitoring : function(){
  2044.         if(!this.bound){
  2045.             this.bound = true;
  2046.             Ext.TaskMgr.start({
  2047.                 run : this.bindHandler,
  2048.                 interval : this.monitorPoll || 200,
  2049.                 scope: this
  2050.             });
  2051.         }
  2052.     },
  2053.     stopMonitoring : function(){
  2054.         this.bound = false;
  2055.     },
  2056.     load : function(){
  2057.         this.form.load.apply(this.form, arguments);
  2058.     },
  2059.         onDisable : function(){
  2060.         Ext.FormPanel.superclass.onDisable.call(this);
  2061.         if(this.form){
  2062.             this.form.items.each(function(){
  2063.                  this.disable();
  2064.             });
  2065.         }
  2066.     },
  2067.         onEnable : function(){
  2068.         Ext.FormPanel.superclass.onEnable.call(this);
  2069.         if(this.form){
  2070.             this.form.items.each(function(){
  2071.                  this.enable();
  2072.             });
  2073.         }
  2074.     },
  2075.         bindHandler : function(){
  2076.         if(!this.bound){
  2077.             return false;         }
  2078.         var valid = true;
  2079.         this.form.items.each(function(f){
  2080.             if(!f.isValid(true)){
  2081.                 valid = false;
  2082.                 return false;
  2083.             }
  2084.         });
  2085.         if(this.buttons){
  2086.             for(var i = 0, len = this.buttons.length; i < len; i++){
  2087.                 var btn = this.buttons[i];
  2088.                 if(btn.formBind === true && btn.disabled === valid){
  2089.                     btn.setDisabled(!valid);
  2090.                 }
  2091.             }
  2092.         }
  2093.         this.fireEvent('clientvalidation', this, valid);
  2094.     }
  2095. });
  2096. Ext.reg('form', Ext.FormPanel);
  2097. Ext.form.FormPanel = Ext.FormPanel;
  2098. Ext.form.FieldSet = Ext.extend(Ext.Panel, {
  2099.     baseCls:'x-fieldset',
  2100.     layout: 'form',
  2101.     onRender : function(ct, position){
  2102.         if(!this.el){
  2103.             this.el = document.createElement('fieldset');
  2104.             this.el.id = this.id;
  2105.             if (this.title || this.header || this.checkboxToggle) {
  2106.                 this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
  2107.             }
  2108.         }
  2109.         Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
  2110.         if(this.checkboxToggle){
  2111.             var o = typeof this.checkboxToggle == 'object' ?
  2112.                     this.checkboxToggle :
  2113.                     {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
  2114.             this.checkbox = this.header.insertFirst(o);
  2115.             this.checkbox.dom.checked = !this.collapsed;
  2116.             this.checkbox.on('click', this.onCheckClick, this);
  2117.         }
  2118.     },
  2119.     onCollapse : function(doAnim, animArg){
  2120.         if(this.checkbox){
  2121.             this.checkbox.dom.checked = false;
  2122.         }
  2123.         this.afterCollapse();
  2124.     },
  2125.     onExpand : function(doAnim, animArg){
  2126.         if(this.checkbox){
  2127.             this.checkbox.dom.checked = true;
  2128.         }
  2129.         this.afterExpand();
  2130.     },
  2131.     onCheckClick : function(){
  2132.         this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
  2133.     }
  2134. });
  2135. Ext.reg('fieldset', Ext.form.FieldSet);
  2136. Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
  2137.     enableFormat : true,
  2138.     enableFontSize : true,
  2139.     enableColors : true,
  2140.     enableAlignments : true,
  2141.     enableLists : true,
  2142.     enableSourceEdit : true,
  2143.     enableLinks : true,
  2144.     enableFont : true,
  2145.     createLinkText : 'Please enter the URL for the link:',
  2146.     defaultLinkValue : 'http:/'+'/',
  2147.     fontFamilies : [
  2148.         'Arial',
  2149.         'Courier New',
  2150.         'Tahoma',
  2151.         'Times New Roman',
  2152.         'Verdana'
  2153.     ],
  2154.     defaultFont: 'tahoma',
  2155.     validationEvent : false,
  2156.     deferHeight: true,
  2157.     initialized : false,
  2158.     activated : false,
  2159.     sourceEditMode : false,
  2160.     onFocus : Ext.emptyFn,
  2161.     iframePad:3,
  2162.     hideMode:'offsets',
  2163.     defaultAutoCreate : {
  2164.         tag: "textarea",
  2165.         style:"width:500px;height:300px;",
  2166.         autocomplete: "off"
  2167.     },
  2168.     initComponent : function(){
  2169.         this.addEvents(
  2170.             'initialize',
  2171.             'activate',
  2172.             'beforesync',
  2173.             'beforepush',
  2174.             'sync',
  2175.             'push',
  2176.             'editmodechange'
  2177.         )
  2178.     },
  2179.     createFontOptions : function(){
  2180.         var buf = [], fs = this.fontFamilies, ff, lc;
  2181.         for(var i = 0, len = fs.length; i< len; i++){
  2182.             ff = fs[i];
  2183.             lc = ff.toLowerCase();
  2184.             buf.push(
  2185.                 '<option value="',lc,'" style="font-family:',ff,';"',
  2186.                     (this.defaultFont == lc ? ' selected="true">' : '>'),
  2187.                     ff,
  2188.                 '</option>'
  2189.             );
  2190.         }
  2191.         return buf.join('');
  2192.     },
  2193.     createToolbar : function(editor){
  2194.         function btn(id, toggle, handler){
  2195.             return {
  2196.                 itemId : id,
  2197.                 cls : 'x-btn-icon x-edit-'+id,
  2198.                 enableToggle:toggle !== false,
  2199.                 scope: editor,
  2200.                 handler:handler||editor.relayBtnCmd,
  2201.                 clickEvent:'mousedown',
  2202.                 tooltip: editor.buttonTips[id] || undefined,
  2203.                 tabIndex:-1
  2204.             };
  2205.         }
  2206.         var tb = new Ext.Toolbar({
  2207.             renderTo:this.wrap.dom.firstChild
  2208.         });
  2209.         tb.el.on('click', function(e){
  2210.             e.preventDefault();
  2211.         });
  2212.         if(this.enableFont && !Ext.isSafari){
  2213.             this.fontSelect = tb.el.createChild({
  2214.                 tag:'select',
  2215.                 cls:'x-font-select',
  2216.                 html: this.createFontOptions()
  2217.             });
  2218.             this.fontSelect.on('change', function(){
  2219.                 var font = this.fontSelect.dom.value;
  2220.                 this.relayCmd('fontname', font);
  2221.                 this.deferFocus();
  2222.             }, this);
  2223.             tb.add(
  2224.                 this.fontSelect.dom,
  2225.                 '-'
  2226.             );
  2227.         };
  2228.         if(this.enableFormat){
  2229.             tb.add(
  2230.                 btn('bold'),
  2231.                 btn('italic'),
  2232.                 btn('underline')
  2233.             );
  2234.         };
  2235.         if(this.enableFontSize){
  2236.             tb.add(
  2237.                 '-',
  2238.                 btn('increasefontsize', false, this.adjustFont),
  2239.                 btn('decreasefontsize', false, this.adjustFont)
  2240.             );
  2241.         };
  2242.         if(this.enableColors){
  2243.             tb.add(
  2244.                 '-', {
  2245.                     itemId:'forecolor',
  2246.                     cls:'x-btn-icon x-edit-forecolor',
  2247.                     clickEvent:'mousedown',
  2248.                     tooltip: editor.buttonTips['forecolor'] || undefined,
  2249.                     tabIndex:-1,
  2250.                     menu : new Ext.menu.ColorMenu({
  2251.                         allowReselect: true,
  2252.                         focus: Ext.emptyFn,
  2253.                         value:'000000',
  2254.                         plain:true,
  2255.                         selectHandler: function(cp, color){
  2256.                             this.execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
  2257.                             this.deferFocus();
  2258.                         },
  2259.                         scope: this,
  2260.                         clickEvent:'mousedown'
  2261.                     })
  2262.                 }, {
  2263.                     itemId:'backcolor',
  2264.                     cls:'x-btn-icon x-edit-backcolor',
  2265.                     clickEvent:'mousedown',
  2266.                     tooltip: editor.buttonTips['backcolor'] || undefined,
  2267.                     tabIndex:-1,
  2268.                     menu : new Ext.menu.ColorMenu({
  2269.                         focus: Ext.emptyFn,
  2270.                         value:'FFFFFF',
  2271.                         plain:true,
  2272.                         allowReselect: true,
  2273.                         selectHandler: function(cp, color){
  2274.                             if(Ext.isGecko){
  2275.                                 this.execCmd('useCSS', false);
  2276.                                 this.execCmd('hilitecolor', color);
  2277.                                 this.execCmd('useCSS', true);
  2278.                                 this.deferFocus();
  2279.                             }else{
  2280.                                 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isSafari || Ext.isIE ? '#'+color : color);
  2281.                                 this.deferFocus();
  2282.                             }
  2283.                         },
  2284.                         scope:this,
  2285.                         clickEvent:'mousedown'
  2286.                     })
  2287.                 }
  2288.             );
  2289.         };
  2290.         if(this.enableAlignments){
  2291.             tb.add(
  2292.                 '-',
  2293.                 btn('justifyleft'),
  2294.                 btn('justifycenter'),
  2295.                 btn('justifyright')
  2296.             );
  2297.         };
  2298.         if(!Ext.isSafari){
  2299.             if(this.enableLinks){
  2300.                 tb.add(
  2301.                     '-',
  2302.                     btn('createlink', false, this.createLink)
  2303.                 );
  2304.             };
  2305.             if(this.enableLists){
  2306.                 tb.add(
  2307.                     '-',
  2308.                     btn('insertorderedlist'),
  2309.                     btn('insertunorderedlist')
  2310.                 );
  2311.             }
  2312.             if(this.enableSourceEdit){
  2313.                 tb.add(
  2314.                     '-',
  2315.                     btn('sourceedit', true, function(btn){
  2316.                         this.toggleSourceEdit(btn.pressed);
  2317.                     })
  2318.                 );
  2319.             }
  2320.         }
  2321.         this.tb = tb;
  2322.     },
  2323.     getDocMarkup : function(){
  2324.         return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
  2325.     },
  2326.     getEditorBody : function(){
  2327.         return this.doc.body || this.doc.documentElement;
  2328.     },
  2329.     onRender : function(ct, position){
  2330.         Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
  2331.         this.el.dom.style.border = '0 none';
  2332.         this.el.dom.setAttribute('tabIndex', -1);
  2333.         this.el.addClass('x-hidden');
  2334.         if(Ext.isIE){
  2335.             this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
  2336.         }
  2337.         this.wrap = this.el.wrap({
  2338.             cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
  2339.         });
  2340.         this.createToolbar(this);
  2341.         this.tb.items.each(function(item){
  2342.            if(item.itemId != 'sourceedit'){
  2343.                 item.disable();
  2344.             }
  2345.         });
  2346.         var iframe = document.createElement('iframe');
  2347.         iframe.name = Ext.id();
  2348.         iframe.frameBorder = 'no';
  2349.         iframe.src=(Ext.SSL_SECURE_URL || "javascript:false");
  2350.         this.wrap.dom.appendChild(iframe);
  2351.         this.iframe = iframe;
  2352.         if(Ext.isIE){
  2353.             iframe.contentWindow.document.designMode = 'on';
  2354.             this.doc = iframe.contentWindow.document;
  2355.             this.win = iframe.contentWindow;
  2356.         } else {
  2357.             this.doc = (iframe.contentDocument || window.frames[iframe.name].document);
  2358.             this.win = window.frames[iframe.name];
  2359.             this.doc.designMode = 'on';
  2360.         }
  2361.         this.doc.open();
  2362.         this.doc.write(this.getDocMarkup())
  2363.         this.doc.close();
  2364.         var task = {
  2365.             run : function(){
  2366.                 if(this.doc.body || this.doc.readyState == 'complete'){
  2367.                     Ext.TaskMgr.stop(task);
  2368.                     this.doc.designMode="on";
  2369.                     this.initEditor.defer(10, this);
  2370.                 }
  2371.             },
  2372.             interval : 10,
  2373.             duration:10000,
  2374.             scope: this
  2375.         };
  2376.         Ext.TaskMgr.start(task);
  2377.         if(!this.width){
  2378.             this.setSize(this.el.getSize());
  2379.         }
  2380.     },
  2381.     onResize : function(w, h){
  2382.         Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
  2383.         if(this.el && this.iframe){
  2384.             if(typeof w == 'number'){
  2385.                 var aw = w - this.wrap.getFrameWidth('lr');
  2386.                 this.el.setWidth(this.adjustWidth('textarea', aw));
  2387.                 this.iframe.style.width = aw + 'px';
  2388.             }
  2389.             if(typeof h == 'number'){
  2390.                 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
  2391.                 this.el.setHeight(this.adjustWidth('textarea', ah));
  2392.                 this.iframe.style.height = ah + 'px';
  2393.                 if(this.doc){
  2394.                     this.getEditorBody().style.height = (ah - (this.iframePad*2)) + 'px';
  2395.                 }
  2396.             }
  2397.         }
  2398.     },
  2399.     toggleSourceEdit : function(sourceEditMode){
  2400.         if(sourceEditMode === undefined){
  2401.             sourceEditMode = !this.sourceEditMode;
  2402.         }
  2403.         this.sourceEditMode = sourceEditMode === true;
  2404.         var btn = this.tb.items.get('sourceedit');
  2405.         if(btn.pressed !== this.sourceEditMode){
  2406.             btn.toggle(this.sourceEditMode);
  2407.             return;
  2408.         }
  2409.         if(this.sourceEditMode){
  2410.             this.tb.items.each(function(item){
  2411.                 if(item.itemId != 'sourceedit'){
  2412.                     item.disable();
  2413.                 }
  2414.             });
  2415.             this.syncValue();
  2416.             this.iframe.className = 'x-hidden';
  2417.             this.el.removeClass('x-hidden');
  2418.             this.el.dom.removeAttribute('tabIndex');
  2419.             this.el.focus();
  2420.         }else{
  2421.             if(this.initialized){
  2422.                 this.tb.items.each(function(item){
  2423.                     item.enable();
  2424.                 });
  2425.             }
  2426.             this.pushValue();
  2427.             this.iframe.className = '';
  2428.             this.el.addClass('x-hidden');
  2429.             this.el.dom.setAttribute('tabIndex', -1);
  2430.             this.deferFocus();
  2431.         }
  2432.         var lastSize = this.lastSize;
  2433.         if(lastSize){
  2434.             delete this.lastSize;
  2435.             this.setSize(lastSize);
  2436.         }
  2437.         this.fireEvent('editmodechange', this, this.sourceEditMode);
  2438.     },
  2439.     createLink : function(){
  2440.         var url = prompt(this.createLinkText, this.defaultLinkValue);
  2441.         if(url && url != 'http:/'+'/'){
  2442.             this.relayCmd('createlink', url);
  2443.         }
  2444.     },
  2445.     adjustSize : Ext.BoxComponent.prototype.adjustSize,
  2446.     getResizeEl : function(){
  2447.         return this.wrap;
  2448.     },
  2449.     getPositionEl : function(){
  2450.         return this.wrap;
  2451.     },
  2452.     initEvents : function(){
  2453.         this.originalValue = this.getValue();
  2454.     },
  2455.     markInvalid : Ext.emptyFn,
  2456.     clearInvalid : Ext.emptyFn,
  2457.     setValue : function(v){
  2458.         Ext.form.HtmlEditor.superclass.setValue.call(this, v);
  2459.         this.pushValue();
  2460.     },
  2461.     cleanHtml : function(html){
  2462.         html = String(html);
  2463.         if(html.length > 5){
  2464.             if(Ext.isSafari){
  2465.                 html = html.replace(/sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
  2466.             }
  2467.         }
  2468.         if(html == '&nbsp;'){
  2469.             html = '';
  2470.         }
  2471.         return html;
  2472.     },
  2473.     syncValue : function(){
  2474.         if(this.initialized){
  2475.             var bd = this.getEditorBody();
  2476.             var html = bd.innerHTML;
  2477.             if(Ext.isSafari){
  2478.                 var bs = bd.getAttribute('style');
  2479.                 var m = bs.match(/text-align:(.*?);/i);
  2480.                 if(m && m[1]){
  2481.                     html = '<div style="'+m[0]+'">' + html + '</div>';
  2482.                 }
  2483.             }
  2484.             html = this.cleanHtml(html);
  2485.             if(this.fireEvent('beforesync', this, html) !== false){
  2486.                 this.el.dom.value = html;
  2487.                 this.fireEvent('sync', this, html);
  2488.             }
  2489.         }
  2490.     },
  2491.     pushValue : function(){
  2492.         if(this.initialized){
  2493.             var v = this.el.dom.value;
  2494.             if(!this.activated && v.length < 1){
  2495.                 v = '&nbsp;';
  2496.             }
  2497.             if(this.fireEvent('beforepush', this, v) !== false){
  2498.                 this.getEditorBody().innerHTML = v;
  2499.                 this.fireEvent('push', this, v);
  2500.             }
  2501.         }
  2502.     },
  2503.     deferFocus : function(){
  2504.         this.focus.defer(10, this);
  2505.     },
  2506.     focus : function(){
  2507.         if(this.win && !this.sourceEditMode){
  2508.             this.win.focus();
  2509.         }else{
  2510.             this.el.focus();
  2511.         }
  2512.     },
  2513.     initEditor : function(){
  2514.         var dbody = this.getEditorBody();
  2515.         var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
  2516.         ss['background-attachment'] = 'fixed';
  2517.         dbody.bgProperties = 'fixed';
  2518.         Ext.DomHelper.applyStyles(dbody, ss);
  2519.         Ext.EventManager.on(this.doc, {
  2520.             'mousedown': this.onEditorEvent,
  2521.             'dblclick': this.onEditorEvent,
  2522.             'click': this.onEditorEvent,
  2523.             'keyup': this.onEditorEvent,
  2524.             buffer:100,
  2525.             scope: this
  2526.         });
  2527.         if(Ext.isGecko){
  2528.             Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
  2529.         }
  2530.         if(Ext.isIE || Ext.isSafari || Ext.isOpera){
  2531.             Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
  2532.         }
  2533.         this.initialized = true;
  2534.         this.fireEvent('initialize', this);
  2535.         this.pushValue();
  2536.     },
  2537.     onDestroy : function(){
  2538.         if(this.rendered){
  2539.             this.tb.items.each(function(item){
  2540.                 if(item.menu){
  2541.                     item.menu.removeAll();
  2542.                     if(item.menu.el){
  2543.                         item.menu.el.destroy();
  2544.                     }
  2545.                 }
  2546.                 item.destroy();
  2547.             });
  2548.             this.wrap.dom.innerHTML = '';
  2549.             this.wrap.remove();
  2550.         }
  2551.     },
  2552.     onFirstFocus : function(){
  2553.         this.activated = true;
  2554.         this.tb.items.each(function(item){
  2555.            item.enable();
  2556.         });
  2557.         if(Ext.isGecko){
  2558.             this.win.focus();
  2559.             var s = this.win.getSelection();
  2560.             if(!s.focusNode || s.focusNode.nodeType != 3){
  2561.                 var r = s.getRangeAt(0);
  2562.                 r.selectNodeContents(this.getEditorBody());
  2563.                 r.collapse(true);
  2564.                 this.deferFocus();
  2565.             }
  2566.             try{
  2567.                 this.execCmd('useCSS', true);
  2568.                 this.execCmd('styleWithCSS', false);
  2569.             }catch(e){}
  2570.         }
  2571.         this.fireEvent('activate', this);
  2572.     },
  2573.     adjustFont: function(btn){
  2574.         var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;
  2575.         var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);
  2576.         if(Ext.isSafari3 || Ext.isAir){
  2577.             if(v <= 10){
  2578.                 v = 1 + adjust;
  2579.             }else if(v <= 13){
  2580.                 v = 2 + adjust;
  2581.             }else if(v <= 16){
  2582.                 v = 3 + adjust;
  2583.             }else if(v <= 18){
  2584.                 v = 4 + adjust;
  2585.             }else if(v <= 24){
  2586.                 v = 5 + adjust;
  2587.             }else {
  2588.                 v = 6 + adjust;
  2589.             }
  2590.             v = v.constrain(1, 6);
  2591.         }else{
  2592.             if(Ext.isSafari){
  2593.                 adjust *= 2;
  2594.             }
  2595.             v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
  2596.         }
  2597.         this.execCmd('FontSize', v);
  2598.     },
  2599.     onEditorEvent : function(e){
  2600.         this.updateToolbar();
  2601.     },
  2602.     updateToolbar: function(){
  2603.         if(!this.activated){
  2604.             this.onFirstFocus();
  2605.             return;
  2606.         }
  2607.         var btns = this.tb.items.map, doc = this.doc;
  2608.         if(this.enableFont && !Ext.isSafari){
  2609.             var name = (this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
  2610.             if(name != this.fontSelect.dom.value){
  2611.                 this.fontSelect.dom.value = name;
  2612.             }
  2613.         }
  2614.         if(this.enableFormat){
  2615.             btns.bold.toggle(doc.queryCommandState('bold'));
  2616.             btns.italic.toggle(doc.queryCommandState('italic'));
  2617.             btns.underline.toggle(doc.queryCommandState('underline'));
  2618.         }
  2619.         if(this.enableAlignments){
  2620.             btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
  2621.             btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
  2622.             btns.justifyright.toggle(doc.queryCommandState('justifyright'));
  2623.         }
  2624.         if(!Ext.isSafari && this.enableLists){
  2625.             btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
  2626.             btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
  2627.         }
  2628.         Ext.menu.MenuMgr.hideAll();
  2629.         this.syncValue();
  2630.     },
  2631.     relayBtnCmd : function(btn){
  2632.         this.relayCmd(btn.itemId);
  2633.     },
  2634.     relayCmd : function(cmd, value){
  2635.         this.win.focus();
  2636.         this.execCmd(cmd, value);
  2637.         this.updateToolbar();
  2638.         this.deferFocus();
  2639.     },
  2640.     execCmd : function(cmd, value){
  2641.         this.doc.execCommand(cmd, false, value === undefined ? null : value);
  2642.         this.syncValue();
  2643.     },
  2644.     applyCommand : function(e){
  2645.         if(e.ctrlKey){
  2646.             var c = e.getCharCode(), cmd;
  2647.             if(c > 0){
  2648.                 c = String.fromCharCode(c);
  2649.                 switch(c){
  2650.                     case 'b':
  2651.                         cmd = 'bold';
  2652.                     break;
  2653.                     case 'i':
  2654.                         cmd = 'italic';
  2655.                     break;
  2656.                     case 'u':
  2657.                         cmd = 'underline';
  2658.                     break;
  2659.                 }
  2660.                 if(cmd){
  2661.                     this.win.focus();
  2662.                     this.execCmd(cmd);
  2663.                     this.deferFocus();
  2664.                     e.preventDefault();
  2665.                 }
  2666.             }
  2667.         }
  2668.     },
  2669.     insertAtCursor : function(text){
  2670.         if(!this.activated){
  2671.             return;
  2672.         }
  2673.         if(Ext.isIE){
  2674.             this.win.focus();
  2675.             var r = this.doc.selection.createRange();
  2676.             if(r){
  2677.                 r.collapse(true);
  2678.                 r.pasteHTML(text);
  2679.                 this.syncValue();
  2680.                 this.deferFocus();
  2681.             }
  2682.         }else if(Ext.isGecko || Ext.isOpera){
  2683.             this.win.focus();
  2684.             this.execCmd('InsertHTML', text);
  2685.             this.deferFocus();
  2686.         }else if(Ext.isSafari){
  2687.             this.execCmd('InsertText', text);
  2688.             this.deferFocus();
  2689.         }
  2690.     },
  2691.     fixKeys : function(){
  2692.         if(Ext.isIE){
  2693.             return function(e){
  2694.                 var k = e.getKey(), r;
  2695.                 if(k == e.TAB){
  2696.                     e.stopEvent();
  2697.                     r = this.doc.selection.createRange();
  2698.                     if(r){
  2699.                         r.collapse(true);
  2700.                         r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
  2701.                         this.deferFocus();
  2702.                     }
  2703.                 }else if(k == e.ENTER){
  2704.                     r = this.doc.selection.createRange();
  2705.                     if(r){
  2706.                         var target = r.parentElement();
  2707.                         if(!target || target.tagName.toLowerCase() != 'li'){
  2708.                             e.stopEvent();
  2709.                             r.pasteHTML('<br />');
  2710.                             r.collapse(false);
  2711.                             r.select();
  2712.                         }
  2713.                     }
  2714.                 }
  2715.             };
  2716.         }else if(Ext.isOpera){
  2717.             return function(e){
  2718.                 var k = e.getKey();
  2719.                 if(k == e.TAB){
  2720.                     e.stopEvent();
  2721.                     this.win.focus();
  2722.                     this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');
  2723.                     this.deferFocus();
  2724.                 }
  2725.             };
  2726.         }else if(Ext.isSafari){
  2727.             return function(e){
  2728.                 var k = e.getKey();
  2729.                 if(k == e.TAB){
  2730.                     e.stopEvent();
  2731.                     this.execCmd('InsertText','t');
  2732.                     this.deferFocus();
  2733.                 }
  2734.              };
  2735.         }
  2736.     }(),
  2737.     getToolbar : function(){
  2738.         return this.tb;
  2739.     },
  2740.     buttonTips : {
  2741.         bold : {
  2742.             title: 'Bold (Ctrl+B)',
  2743.             text: 'Make the selected text bold.',
  2744.             cls: 'x-html-editor-tip'
  2745.         },
  2746.         italic : {
  2747.             title: 'Italic (Ctrl+I)',
  2748.             text: 'Make the selected text italic.',
  2749.             cls: 'x-html-editor-tip'
  2750.         },
  2751.         underline : {
  2752.             title: 'Underline (Ctrl+U)',
  2753.             text: 'Underline the selected text.',
  2754.             cls: 'x-html-editor-tip'
  2755.         },
  2756.         increasefontsize : {
  2757.             title: 'Grow Text',
  2758.             text: 'Increase the font size.',
  2759.             cls: 'x-html-editor-tip'
  2760.         },
  2761.         decreasefontsize : {
  2762.             title: 'Shrink Text',
  2763.             text: 'Decrease the font size.',
  2764.             cls: 'x-html-editor-tip'
  2765.         },
  2766.         backcolor : {
  2767.             title: 'Text Highlight Color',
  2768.             text: 'Change the background color of the selected text.',
  2769.             cls: 'x-html-editor-tip'
  2770.         },
  2771.         forecolor : {
  2772.             title: 'Font Color',
  2773.             text: 'Change the color of the selected text.',
  2774.             cls: 'x-html-editor-tip'
  2775.         },
  2776.         justifyleft : {
  2777.             title: 'Align Text Left',
  2778.             text: 'Align text to the left.',
  2779.             cls: 'x-html-editor-tip'
  2780.         },
  2781.         justifycenter : {
  2782.             title: 'Center Text',
  2783.             text: 'Center text in the editor.',
  2784.             cls: 'x-html-editor-tip'
  2785.         },
  2786.         justifyright : {
  2787.             title: 'Align Text Right',
  2788.             text: 'Align text to the right.',
  2789.             cls: 'x-html-editor-tip'
  2790.         },
  2791.         insertunorderedlist : {
  2792.             title: 'Bullet List',
  2793.             text: 'Start a bulleted list.',
  2794.             cls: 'x-html-editor-tip'
  2795.         },
  2796.         insertorderedlist : {
  2797.             title: 'Numbered List',
  2798.             text: 'Start a numbered list.',
  2799.             cls: 'x-html-editor-tip'
  2800.         },
  2801.         createlink : {
  2802.             title: 'Hyperlink',
  2803.             text: 'Make the selected text a hyperlink.',
  2804.             cls: 'x-html-editor-tip'
  2805.         },
  2806.         sourceedit : {
  2807.             title: 'Source Edit',
  2808.             text: 'Switch to source editing mode.',
  2809.             cls: 'x-html-editor-tip'
  2810.         }
  2811.     }
  2812. });
  2813. Ext.reg('htmleditor', Ext.form.HtmlEditor);
  2814. Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
  2815.     minValue : null,
  2816.     maxValue : null,
  2817.     minText : "The time in this field must be equal to or after {0}",
  2818.     maxText : "The time in this field must be equal to or before {0}",
  2819.     invalidText : "{0} is not a valid time",
  2820.     format : "g:i A",
  2821.     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",
  2822.     increment: 15,
  2823.     mode: 'local',
  2824.     triggerAction: 'all',
  2825.     typeAhead: false,
  2826.     initComponent : function(){
  2827.         Ext.form.TimeField.superclass.initComponent.call(this);
  2828.         if(typeof this.minValue == "string"){
  2829.             this.minValue = this.parseDate(this.minValue);
  2830.         }
  2831.         if(typeof this.maxValue == "string"){
  2832.             this.maxValue = this.parseDate(this.maxValue);
  2833.         }
  2834.         if(!this.store){
  2835.             var min = this.parseDate(this.minValue);
  2836.             if(!min){
  2837.                 min = new Date().clearTime();
  2838.             }
  2839.             var max = this.parseDate(this.maxValue);
  2840.             if(!max){
  2841.                 max = new Date().clearTime().add('mi', (24 * 60) - 1);
  2842.             }
  2843.             var times = [];
  2844.             while(min <= max){
  2845.                 times.push([min.dateFormat(this.format)]);
  2846.                 min = min.add('mi', this.increment);
  2847.             }
  2848.             this.store = new Ext.data.SimpleStore({
  2849.                 fields: ['text'],
  2850.                 data : times
  2851.             });
  2852.             this.displayField = 'text';
  2853.         }
  2854.     },
  2855.     getValue : function(){
  2856.         var v = Ext.form.TimeField.superclass.getValue.call(this);
  2857.         return this.formatDate(this.parseDate(v)) || '';
  2858.     },
  2859.     setValue : function(value){
  2860.         Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
  2861.     },
  2862.     validateValue : Ext.form.DateField.prototype.validateValue,
  2863.     parseDate : Ext.form.DateField.prototype.parseDate,
  2864.     formatDate : Ext.form.DateField.prototype.formatDate,
  2865.     beforeBlur : function(){
  2866.         var v = this.parseDate(this.getRawValue());
  2867.         if(v){
  2868.             this.setValue(v.dateFormat(this.format));
  2869.         }
  2870.     }
  2871. });
  2872. Ext.reg('timefield', Ext.form.TimeField);
  2873. Ext.form.Label = Ext.extend(Ext.BoxComponent, {
  2874.     onRender : function(ct, position){
  2875.         if(!this.el){
  2876.             this.el = document.createElement('label');
  2877.             this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
  2878.             if(this.forId){
  2879.                 this.el.setAttribute('htmlFor', this.forId);
  2880.             }
  2881.         }
  2882.         Ext.form.Label.superclass.onRender.call(this, ct, position);
  2883.     }
  2884. });
  2885. Ext.reg('label', Ext.form.Label);
  2886. Ext.form.Action = function(form, options){
  2887.     this.form = form;
  2888.     this.options = options || {};
  2889. };
  2890. Ext.form.Action.CLIENT_INVALID = 'client';
  2891. Ext.form.Action.SERVER_INVALID = 'server';
  2892. Ext.form.Action.CONNECT_FAILURE = 'connect';
  2893. Ext.form.Action.LOAD_FAILURE = 'load';
  2894. Ext.form.Action.prototype = {
  2895.     type : 'default',
  2896.         run : function(options){
  2897.     },
  2898.         success : function(response){
  2899.     },
  2900.         handleResponse : function(response){
  2901.     },
  2902.         failure : function(response){
  2903.         this.response = response;
  2904.         this.failureType = Ext.form.Action.CONNECT_FAILURE;
  2905.         this.form.afterAction(this, false);
  2906.     },
  2907.         processResponse : function(response){
  2908.         this.response = response;
  2909.         if(!response.responseText){
  2910.             return true;
  2911.         }
  2912.         this.result = this.handleResponse(response);
  2913.         return this.result;
  2914.     },
  2915.         getUrl : function(appendParams){
  2916.         var url = this.options.url || this.form.url || this.form.el.dom.action;
  2917.         if(appendParams){
  2918.             var p = this.getParams();
  2919.             if(p){
  2920.                 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
  2921.             }
  2922.         }
  2923.         return url;
  2924.     },
  2925.         getMethod : function(){
  2926.         return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
  2927.     },
  2928.         getParams : function(){
  2929.         var bp = this.form.baseParams;
  2930.         var p = this.options.params;
  2931.         if(p){
  2932.             if(typeof p == "object"){
  2933.                 p = Ext.urlEncode(Ext.applyIf(p, bp));
  2934.             }else if(typeof p == 'string' && bp){
  2935.                 p += '&' + Ext.urlEncode(bp);
  2936.             }
  2937.         }else if(bp){
  2938.             p = Ext.urlEncode(bp);
  2939.         }
  2940.         return p;
  2941.     },
  2942.         createCallback : function(opts){
  2943.         var opts = opts || {};
  2944.         return {
  2945.             success: this.success,
  2946.             failure: this.failure,
  2947.             scope: this,
  2948.             timeout: (opts.timeout*1000) || (this.form.timeout*1000),
  2949.             upload: this.form.fileUpload ? this.success : undefined
  2950.         };
  2951.     }
  2952. };
  2953. Ext.form.Action.Submit = function(form, options){
  2954.     Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
  2955. };
  2956. Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
  2957.     type : 'submit',
  2958.         run : function(){
  2959.         var o = this.options;
  2960.         var method = this.getMethod();
  2961.         var isPost = method == 'POST';
  2962.         if(o.clientValidation === false || this.form.isValid()){
  2963.             Ext.Ajax.request(Ext.apply(this.createCallback(o), {
  2964.                 form:this.form.el.dom,
  2965.                 url:this.getUrl(!isPost),
  2966.                 method: method,
  2967.                 params:isPost ? this.getParams() : null,
  2968.                 isUpload: this.form.fileUpload
  2969.             }));
  2970.         }else if (o.clientValidation !== false){             this.failureType = Ext.form.Action.CLIENT_INVALID;
  2971.             this.form.afterAction(this, false);
  2972.         }
  2973.     },
  2974.         success : function(response){
  2975.         var result = this.processResponse(response);
  2976.         if(result === true || result.success){
  2977.             this.form.afterAction(this, true);
  2978.             return;
  2979.         }
  2980.         if(result.errors){
  2981.             this.form.markInvalid(result.errors);
  2982.             this.failureType = Ext.form.Action.SERVER_INVALID;
  2983.         }
  2984.         this.form.afterAction(this, false);
  2985.     },
  2986.         handleResponse : function(response){
  2987.         if(this.form.errorReader){
  2988.             var rs = this.form.errorReader.read(response);
  2989.             var errors = [];
  2990.             if(rs.records){
  2991.                 for(var i = 0, len = rs.records.length; i < len; i++) {
  2992.                     var r = rs.records[i];
  2993.                     errors[i] = r.data;
  2994.                 }
  2995.             }
  2996.             if(errors.length < 1){
  2997.                 errors = null;
  2998.             }
  2999.             return {
  3000.                 success : rs.success,
  3001.                 errors : errors
  3002.             };
  3003.         }
  3004.         return Ext.decode(response.responseText);
  3005.     }
  3006. });
  3007. Ext.form.Action.Load = function(form, options){
  3008.     Ext.form.Action.Load.superclass.constructor.call(this, form, options);
  3009.     this.reader = this.form.reader;
  3010. };
  3011. Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
  3012.         type : 'load',
  3013.         run : function(){
  3014.         Ext.Ajax.request(Ext.apply(
  3015.                 this.createCallback(this.options), {
  3016.                     method:this.getMethod(),
  3017.                     url:this.getUrl(false),
  3018.                     params:this.getParams()
  3019.         }));
  3020.     },
  3021.         success : function(response){
  3022.         var result = this.processResponse(response);
  3023.         if(result === true || !result.success || !result.data){
  3024.             this.failureType = Ext.form.Action.LOAD_FAILURE;
  3025.             this.form.afterAction(this, false);
  3026.             return;
  3027.         }
  3028.         this.form.clearInvalid();
  3029.         this.form.setValues(result.data);
  3030.         this.form.afterAction(this, true);
  3031.     },
  3032.         handleResponse : function(response){
  3033.         if(this.form.reader){
  3034.             var rs = this.form.reader.read(response);
  3035.             var data = rs.records && rs.records[0] ? rs.records[0].data : null;
  3036.             return {
  3037.                 success : rs.success,
  3038.                 data : data
  3039.             };
  3040.         }
  3041.         return Ext.decode(response.responseText);
  3042.     }
  3043. });
  3044. Ext.form.Action.ACTION_TYPES = {
  3045.     'load' : Ext.form.Action.Load,
  3046.     'submit' : Ext.form.Action.Submit
  3047. };
  3048. Ext.form.VTypes = function(){
  3049.         var alpha = /^[a-zA-Z_]+$/;
  3050.     var alphanum = /^[a-zA-Z0-9_]+$/;
  3051.     var email = /^([w]+)(.[w]+)*@([w-]+.){1,5}([A-Za-z]){2,4}$/;
  3052.     var url = /(((https?)|(ftp))://([-w]+.)+w{2,3}(/[%-w]+(.w{2,})?)*(([w-.?\/+@&#;`~=%!]*)(.w{2,})?)*/?)/i;
  3053.         return {
  3054.         'email' : function(v){
  3055.             return email.test(v);
  3056.         },
  3057.         'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
  3058.         'emailMask' : /[a-z0-9_.-@]/i,
  3059.         'url' : function(v){
  3060.             return url.test(v);
  3061.         },
  3062.         'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
  3063.         'alpha' : function(v){
  3064.             return alpha.test(v);
  3065.         },
  3066.         'alphaText' : 'This field should only contain letters and _',
  3067.         'alphaMask' : /[a-z_]/i,
  3068.         'alphanum' : function(v){
  3069.             return alphanum.test(v);
  3070.         },
  3071.         'alphanumText' : 'This field should only contain letters, numbers and _',
  3072.         'alphanumMask' : /[a-z0-9_]/i
  3073.     };
  3074. }();
  3075. Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
  3076.     ddText : "{0} selected row{1}",
  3077.     minColumnWidth : 25,
  3078.     trackMouseOver : true,
  3079.     enableDragDrop : false,
  3080.     enableColumnMove : true,
  3081.     enableColumnHide : true,
  3082.     enableHdMenu : true,
  3083.     stripeRows : false,
  3084.     autoExpandColumn : false,
  3085.     autoExpandMin : 50,
  3086.     autoExpandMax : 1000,
  3087.     view : null,
  3088.     loadMask : false,
  3089.     rendered : false,
  3090.     viewReady: false,
  3091.     stateEvents: ["columnmove", "columnresize", "sortchange"],
  3092.     initComponent : function(){
  3093.         Ext.grid.GridPanel.superclass.initComponent.call(this);
  3094.         this.autoScroll = false;
  3095.         this.autoWidth = false;
  3096.         if(Ext.isArray(this.columns)){
  3097.             this.colModel = new Ext.grid.ColumnModel(this.columns);
  3098.             delete this.columns;
  3099.         }
  3100.         if(this.ds){
  3101.             this.store = this.ds;
  3102.             delete this.ds;
  3103.         }
  3104.         if(this.cm){
  3105.             this.colModel = this.cm;
  3106.             delete this.cm;
  3107.         }
  3108.         if(this.sm){
  3109.             this.selModel = this.sm;
  3110.             delete this.sm;
  3111.         }
  3112.         this.store = Ext.StoreMgr.lookup(this.store);
  3113.         this.addEvents(
  3114.             "click",
  3115.             "dblclick",
  3116.             "contextmenu",
  3117.             "mousedown",
  3118.             "mouseup",
  3119.             "mouseover",
  3120.             "mouseout",
  3121.             "keypress",
  3122.             "keydown",
  3123.             "cellmousedown",
  3124.             "rowmousedown",
  3125.             "headermousedown",
  3126.             "cellclick",
  3127.             "celldblclick",
  3128.             "rowclick",
  3129.             "rowdblclick",
  3130.             "headerclick",
  3131.             "headerdblclick",
  3132.             "rowcontextmenu",
  3133.             "cellcontextmenu",
  3134.             "headercontextmenu",
  3135.             "bodyscroll",
  3136.             "columnresize",
  3137.             "columnmove",
  3138.             "sortchange"
  3139.         );
  3140.     },
  3141.     onRender : function(ct, position){
  3142.         Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
  3143.         var c = this.body;
  3144.         this.el.addClass('x-grid-panel');
  3145.         var view = this.getView();
  3146.         view.init(this);
  3147.         c.on("mousedown", this.onMouseDown, this);
  3148.         c.on("click", this.onClick, this);
  3149.         c.on("dblclick", this.onDblClick, this);
  3150.         c.on("contextmenu", this.onContextMenu, this);
  3151.         c.on("keydown", this.onKeyDown, this);
  3152.         this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
  3153.         this.getSelectionModel().init(this);
  3154.         this.view.render();
  3155.     },
  3156.     initEvents : function(){
  3157.         Ext.grid.GridPanel.superclass.initEvents.call(this);
  3158.         if(this.loadMask){
  3159.             this.loadMask = new Ext.LoadMask(this.bwrap,
  3160.                     Ext.apply({store:this.store}, this.loadMask));
  3161.         }
  3162.     },
  3163.     initStateEvents : function(){
  3164.         Ext.grid.GridPanel.superclass.initStateEvents.call(this);
  3165.         this.colModel.on('hiddenchange', this.saveState, this, {delay: 100});
  3166.     },
  3167.     applyState : function(state){
  3168.         var cm = this.colModel;
  3169.         var cs = state.columns;
  3170.         if(cs){
  3171.             for(var i = 0, len = cs.length; i < len; i++){
  3172.                 var s = cs[i];
  3173.                 var c = cm.getColumnById(s.id);
  3174.                 if(c){
  3175.                     c.hidden = s.hidden;
  3176.                     c.width = s.width;
  3177.                     var oldIndex = cm.getIndexById(s.id);
  3178.                     if(oldIndex != i){
  3179.                         cm.moveColumn(oldIndex, i);
  3180.                     }
  3181.                 }
  3182.             }
  3183.         }
  3184.         if(state.sort){
  3185.             this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
  3186.         }
  3187.     },
  3188.     getState : function(){
  3189.         var o = {columns: []};
  3190.         for(var i = 0, c; c = this.colModel.config[i]; i++){
  3191.             o.columns[i] = {
  3192.                 id: c.id,
  3193.                 width: c.width
  3194.             };
  3195.             if(c.hidden){
  3196.                 o.columns[i].hidden = true;
  3197.             }
  3198.         }
  3199.         var ss = this.store.getSortState();
  3200.         if(ss){
  3201.             o.sort = ss;
  3202.         }
  3203.         return o;
  3204.     },
  3205.     afterRender : function(){
  3206.         Ext.grid.GridPanel.superclass.afterRender.call(this);
  3207.         this.view.layout();
  3208.         this.viewReady = true;
  3209.     },
  3210.     reconfigure : function(store, colModel){
  3211.         if(this.loadMask){
  3212.             this.loadMask.destroy();
  3213.             this.loadMask = new Ext.LoadMask(this.bwrap,
  3214.                     Ext.apply({store:store}, this.initialConfig.loadMask));
  3215.         }
  3216.         this.view.bind(store, colModel);
  3217.         this.store = store;
  3218.         this.colModel = colModel;
  3219.         if(this.rendered){
  3220.             this.view.refresh(true);
  3221.         }
  3222.     },
  3223.     onKeyDown : function(e){
  3224.         this.fireEvent("keydown", e);
  3225.     },
  3226.     onDestroy : function(){
  3227.         if(this.rendered){
  3228.             if(this.loadMask){
  3229.                 this.loadMask.destroy();
  3230.             }
  3231.             var c = this.body;
  3232.             c.removeAllListeners();
  3233.             this.view.destroy();
  3234.             c.update("");
  3235.         }
  3236.         this.colModel.purgeListeners();
  3237.         Ext.grid.GridPanel.superclass.onDestroy.call(this);
  3238.     },
  3239.     processEvent : function(name, e){
  3240.         this.fireEvent(name, e);
  3241.         var t = e.getTarget();
  3242.         var v = this.view;
  3243.         var header = v.findHeaderIndex(t);
  3244.         if(header !== false){
  3245.             this.fireEvent("header" + name, this, header, e);
  3246.         }else{
  3247.             var row = v.findRowIndex(t);
  3248.             var cell = v.findCellIndex(t);
  3249.             if(row !== false){
  3250.                 this.fireEvent("row" + name, this, row, e);
  3251.                 if(cell !== false){
  3252.                     this.fireEvent("cell" + name, this, row, cell, e);
  3253.                 }
  3254.             }
  3255.         }
  3256.     },
  3257.     onClick : function(e){
  3258.         this.processEvent("click", e);
  3259.     },
  3260.     onMouseDown : function(e){
  3261.         this.processEvent("mousedown", e);
  3262.     },
  3263.     onContextMenu : function(e, t){
  3264.         this.processEvent("contextmenu", e);
  3265.     },
  3266.     onDblClick : function(e){
  3267.         this.processEvent("dblclick", e);
  3268.     },
  3269.     walkCells : function(row, col, step, fn, scope){
  3270.         var cm = this.colModel, clen = cm.getColumnCount();
  3271.         var ds = this.store, rlen = ds.getCount(), first = true;
  3272.         if(step < 0){
  3273.             if(col < 0){
  3274.                 row--;
  3275.                 first = false;
  3276.             }
  3277.             while(row >= 0){
  3278.                 if(!first){
  3279.                     col = clen-1;
  3280.                 }
  3281.                 first = false;
  3282.                 while(col >= 0){
  3283.                     if(fn.call(scope || this, row, col, cm) === true){
  3284.                         return [row, col];
  3285.                     }
  3286.                     col--;
  3287.                 }
  3288.                 row--;