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

JavaScript

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.1.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. /**
  8.  * @class Ext.Editor
  9.  * @extends Ext.Component
  10.  * A base editor field that handles displaying/hiding on demand and has some built-in sizing and event handling logic.
  11.  * @constructor
  12.  * Create a new Editor
  13.  * @param {Object} config The config object
  14.  * @xtype editor
  15.  */
  16. Ext.Editor = function(field, config){
  17.     if(field.field){
  18.         this.field = Ext.create(field.field, 'textfield');
  19.         config = Ext.apply({}, field); // copy so we don't disturb original config
  20.         delete config.field;
  21.     }else{
  22.         this.field = field;
  23.     }
  24.     Ext.Editor.superclass.constructor.call(this, config);
  25. };
  26. Ext.extend(Ext.Editor, Ext.Component, {
  27.     /**
  28.     * @cfg {Ext.form.Field} field
  29.     * The Field object (or descendant) or config object for field
  30.     */
  31.     /**
  32.      * @cfg {Boolean} allowBlur
  33.      * True to {@link #completeEdit complete the editing process} if in edit mode when the
  34.      * field is blurred. Defaults to <tt>false</tt>.
  35.      */
  36.     /**
  37.      * @cfg {Boolean/String} autoSize
  38.      * True for the editor to automatically adopt the size of the underlying field, "width" to adopt the width only,
  39.      * or "height" to adopt the height only, "none" to always use the field dimensions. (defaults to false)
  40.      */
  41.     /**
  42.      * @cfg {Boolean} revertInvalid
  43.      * True to automatically revert the field value and cancel the edit when the user completes an edit and the field
  44.      * validation fails (defaults to true)
  45.      */
  46.     /**
  47.      * @cfg {Boolean} ignoreNoChange
  48.      * True to skip the edit completion process (no save, no events fired) if the user completes an edit and
  49.      * the value has not changed (defaults to false).  Applies only to string values - edits for other data types
  50.      * will never be ignored.
  51.      */
  52.     /**
  53.      * @cfg {Boolean} hideEl
  54.      * False to keep the bound element visible while the editor is displayed (defaults to true)
  55.      */
  56.     /**
  57.      * @cfg {Mixed} value
  58.      * The data value of the underlying field (defaults to "")
  59.      */
  60.     value : "",
  61.     /**
  62.      * @cfg {String} alignment
  63.      * The position to align to (see {@link Ext.Element#alignTo} for more details, defaults to "c-c?").
  64.      */
  65.     alignment: "c-c?",
  66.     /**
  67.      * @cfg {Array} offsets
  68.      * The offsets to use when aligning (see {@link Ext.Element#alignTo} for more details. Defaults to <tt>[0, 0]</tt>.
  69.      */
  70.     offsets: [0, 0],
  71.     /**
  72.      * @cfg {Boolean/String} shadow "sides" for sides/bottom only, "frame" for 4-way shadow, and "drop"
  73.      * for bottom-right shadow (defaults to "frame")
  74.      */
  75.     shadow : "frame",
  76.     /**
  77.      * @cfg {Boolean} constrain True to constrain the editor to the viewport
  78.      */
  79.     constrain : false,
  80.     /**
  81.      * @cfg {Boolean} swallowKeys Handle the keydown/keypress events so they don't propagate (defaults to true)
  82.      */
  83.     swallowKeys : true,
  84.     /**
  85.      * @cfg {Boolean} completeOnEnter True to complete the edit when the enter key is pressed. Defaults to <tt>true</tt>.
  86.      */
  87.     completeOnEnter : true,
  88.     /**
  89.      * @cfg {Boolean} cancelOnEsc True to cancel the edit when the escape key is pressed. Defaults to <tt>true</tt>.
  90.      */
  91.     cancelOnEsc : true,
  92.     /**
  93.      * @cfg {Boolean} updateEl True to update the innerHTML of the bound element when the update completes (defaults to false)
  94.      */
  95.     updateEl : false,
  96.     initComponent : function(){
  97.         Ext.Editor.superclass.initComponent.call(this);
  98.         this.addEvents(
  99.             /**
  100.              * @event beforestartedit
  101.              * Fires when editing is initiated, but before the value changes.  Editing can be canceled by returning
  102.              * false from the handler of this event.
  103.              * @param {Editor} this
  104.              * @param {Ext.Element} boundEl The underlying element bound to this editor
  105.              * @param {Mixed} value The field value being set
  106.              */
  107.             "beforestartedit",
  108.             /**
  109.              * @event startedit
  110.              * Fires when this editor is displayed
  111.              * @param {Ext.Element} boundEl The underlying element bound to this editor
  112.              * @param {Mixed} value The starting field value
  113.              */
  114.             "startedit",
  115.             /**
  116.              * @event beforecomplete
  117.              * Fires after a change has been made to the field, but before the change is reflected in the underlying
  118.              * field.  Saving the change to the field can be canceled by returning false from the handler of this event.
  119.              * Note that if the value has not changed and ignoreNoChange = true, the editing will still end but this
  120.              * event will not fire since no edit actually occurred.
  121.              * @param {Editor} this
  122.              * @param {Mixed} value The current field value
  123.              * @param {Mixed} startValue The original field value
  124.              */
  125.             "beforecomplete",
  126.             /**
  127.              * @event complete
  128.              * Fires after editing is complete and any changed value has been written to the underlying field.
  129.              * @param {Editor} this
  130.              * @param {Mixed} value The current field value
  131.              * @param {Mixed} startValue The original field value
  132.              */
  133.             "complete",
  134.             /**
  135.              * @event canceledit
  136.              * Fires after editing has been canceled and the editor's value has been reset.
  137.              * @param {Editor} this
  138.              * @param {Mixed} value The user-entered field value that was discarded
  139.              * @param {Mixed} startValue The original field value that was set back into the editor after cancel
  140.              */
  141.             "canceledit",
  142.             /**
  143.              * @event specialkey
  144.              * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed.  You can check
  145.              * {@link Ext.EventObject#getKey} to determine which key was pressed.
  146.              * @param {Ext.form.Field} this
  147.              * @param {Ext.EventObject} e The event object
  148.              */
  149.             "specialkey"
  150.         );
  151.     },
  152.     // private
  153.     onRender : function(ct, position){
  154.         this.el = new Ext.Layer({
  155.             shadow: this.shadow,
  156.             cls: "x-editor",
  157.             parentEl : ct,
  158.             shim : this.shim,
  159.             shadowOffset: this.shadowOffset || 4,
  160.             id: this.id,
  161.             constrain: this.constrain
  162.         });
  163.         if(this.zIndex){
  164.             this.el.setZIndex(this.zIndex);
  165.         }
  166.         this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
  167.         if(this.field.msgTarget != 'title'){
  168.             this.field.msgTarget = 'qtip';
  169.         }
  170.         this.field.inEditor = true;
  171.         this.mon(this.field, {
  172.             scope: this,
  173.             blur: this.onBlur,
  174.             specialkey: this.onSpecialKey
  175.         });
  176.         if(this.field.grow){
  177.             this.mon(this.field, "autosize", this.el.sync,  this.el, {delay:1});
  178.         }
  179.         this.field.render(this.el).show();
  180.         this.field.getEl().dom.name = '';
  181.         if(this.swallowKeys){
  182.             this.field.el.swallowEvent([
  183.                 'keypress', // *** Opera
  184.                 'keydown'   // *** all other browsers
  185.             ]);
  186.         }
  187.     },
  188.     // private
  189.     onSpecialKey : function(field, e){
  190.         var key = e.getKey(),
  191.             complete = this.completeOnEnter && key == e.ENTER,
  192.             cancel = this.cancelOnEsc && key == e.ESC;
  193.         if(complete || cancel){
  194.             e.stopEvent();
  195.             if(complete){
  196.                 this.completeEdit();
  197.             }else{
  198.                 this.cancelEdit();
  199.             }
  200.             if(field.triggerBlur){
  201.                 field.triggerBlur(); 
  202.             }
  203.         }
  204.         this.fireEvent('specialkey', field, e);
  205.     },
  206.     /**
  207.      * Starts the editing process and shows the editor.
  208.      * @param {Mixed} el The element to edit
  209.      * @param {String} value (optional) A value to initialize the editor with. If a value is not provided, it defaults
  210.       * to the innerHTML of el.
  211.      */
  212.     startEdit : function(el, value){
  213.         if(this.editing){
  214.             this.completeEdit();
  215.         }
  216.         this.boundEl = Ext.get(el);
  217.         var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
  218.         if(!this.rendered){
  219.             this.render(this.parentEl || document.body);
  220.         }
  221.         if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
  222.             this.startValue = v;
  223.             this.field.reset();
  224.             this.field.setValue(v);
  225.             this.realign(true);
  226.             this.editing = true;
  227.             this.show();
  228.         }
  229.     },
  230.     // private
  231.     doAutoSize : function(){
  232.         if(this.autoSize){
  233.             var sz = this.boundEl.getSize(),
  234.                 fs = this.field.getSize();
  235.             switch(this.autoSize){
  236.                 case "width":
  237.                     this.setSize(sz.width, fs.height);
  238.                     break;
  239.                 case "height":
  240.                     this.setSize(fs.width, sz.height);
  241.                     break;
  242.                 case "none":
  243.                     this.setSize(fs.width, fs.height);
  244.                     break;
  245.                 default:
  246.                     this.setSize(sz.width, sz.height);
  247.             }
  248.         }
  249.     },
  250.     /**
  251.      * Sets the height and width of this editor.
  252.      * @param {Number} width The new width
  253.      * @param {Number} height The new height
  254.      */
  255.     setSize : function(w, h){
  256.         delete this.field.lastSize;
  257.         this.field.setSize(w, h);
  258.         if(this.el){
  259.             if(Ext.isGecko2 || Ext.isOpera){
  260.                 // prevent layer scrollbars
  261.                 this.el.setSize(w, h);
  262.             }
  263.             this.el.sync();
  264.         }
  265.     },
  266.     /**
  267.      * Realigns the editor to the bound field based on the current alignment config value.
  268.      * @param {Boolean} autoSize (optional) True to size the field to the dimensions of the bound element.
  269.      */
  270.     realign : function(autoSize){
  271.         if(autoSize === true){
  272.             this.doAutoSize();
  273.         }
  274.         this.el.alignTo(this.boundEl, this.alignment, this.offsets);
  275.     },
  276.     /**
  277.      * Ends the editing process, persists the changed value to the underlying field, and hides the editor.
  278.      * @param {Boolean} remainVisible Override the default behavior and keep the editor visible after edit (defaults to false)
  279.      */
  280.     completeEdit : function(remainVisible){
  281.         if(!this.editing){
  282.             return;
  283.         }
  284.         var v = this.getValue();
  285.         if(!this.field.isValid()){
  286.             if(this.revertInvalid !== false){
  287.                 this.cancelEdit(remainVisible);
  288.             }
  289.             return;
  290.         }
  291.         if(String(v) === String(this.startValue) && this.ignoreNoChange){
  292.             this.hideEdit(remainVisible);
  293.             return;
  294.         }
  295.         if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
  296.             v = this.getValue();
  297.             if(this.updateEl && this.boundEl){
  298.                 this.boundEl.update(v);
  299.             }
  300.             this.hideEdit(remainVisible);
  301.             this.fireEvent("complete", this, v, this.startValue);
  302.         }
  303.     },
  304.     // private
  305.     onShow : function(){
  306.         this.el.show();
  307.         if(this.hideEl !== false){
  308.             this.boundEl.hide();
  309.         }
  310.         this.field.show().focus(false, true);
  311.         this.fireEvent("startedit", this.boundEl, this.startValue);
  312.     },
  313.     /**
  314.      * Cancels the editing process and hides the editor without persisting any changes.  The field value will be
  315.      * reverted to the original starting value.
  316.      * @param {Boolean} remainVisible Override the default behavior and keep the editor visible after
  317.      * cancel (defaults to false)
  318.      */
  319.     cancelEdit : function(remainVisible){
  320.         if(this.editing){
  321.             var v = this.getValue();
  322.             this.setValue(this.startValue);
  323.             this.hideEdit(remainVisible);
  324.             this.fireEvent("canceledit", this, v, this.startValue);
  325.         }
  326.     },
  327.     
  328.     // private
  329.     hideEdit: function(remainVisible){
  330.         if(remainVisible !== true){
  331.             this.editing = false;
  332.             this.hide();
  333.         }
  334.     },
  335.     // private
  336.     onBlur : function(){
  337.         if(this.allowBlur !== true && this.editing){
  338.             this.completeEdit();
  339.         }
  340.     },
  341.     // private
  342.     onHide : function(){
  343.         if(this.editing){
  344.             this.completeEdit();
  345.             return;
  346.         }
  347.         this.field.blur();
  348.         if(this.field.collapse){
  349.             this.field.collapse();
  350.         }
  351.         this.el.hide();
  352.         if(this.hideEl !== false){
  353.             this.boundEl.show();
  354.         }
  355.     },
  356.     /**
  357.      * Sets the data value of the editor
  358.      * @param {Mixed} value Any valid value supported by the underlying field
  359.      */
  360.     setValue : function(v){
  361.         this.field.setValue(v);
  362.     },
  363.     /**
  364.      * Gets the data value of the editor
  365.      * @return {Mixed} The data value
  366.      */
  367.     getValue : function(){
  368.         return this.field.getValue();
  369.     },
  370.     beforeDestroy : function(){
  371.         Ext.destroyMembers(this, 'field');
  372.         
  373.         delete this.parentEl;
  374.         delete this.boundEl;
  375.     }
  376. });
  377. Ext.reg('editor', Ext.Editor);