4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
14 * @extends Roo.Component
15 * A base editor field that handles displaying/hiding on demand and has some built-in sizing and event handling logic.
18 * @param {Roo.form.Field} field The Field object (or descendant)
19 * @param {Object} config The config object
21 Roo.Editor = function(field, config){
22 Roo.Editor.superclass.constructor.call(this, config);
26 * @event beforestartedit
27 * Fires when editing is initiated, but before the value changes. Editing can be canceled by returning
28 * false from the handler of this event.
29 * @param {Editor} this
30 * @param {Roo.Element} boundEl The underlying element bound to this editor
31 * @param {Mixed} value The field value being set
33 "beforestartedit" : true,
36 * Fires when this editor is displayed
37 * @param {Roo.Element} boundEl The underlying element bound to this editor
38 * @param {Mixed} value The starting field value
42 * @event beforecomplete
43 * Fires after a change has been made to the field, but before the change is reflected in the underlying
44 * field. Saving the change to the field can be canceled by returning false from the handler of this event.
45 * Note that if the value has not changed and ignoreNoChange = true, the editing will still end but this
46 * event will not fire since no edit actually occurred.
47 * @param {Editor} this
48 * @param {Mixed} value The current field value
49 * @param {Mixed} startValue The original field value
51 "beforecomplete" : true,
54 * Fires after editing is complete and any changed value has been written to the underlying field.
55 * @param {Editor} this
56 * @param {Mixed} value The current field value
57 * @param {Mixed} startValue The original field value
62 * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed. You can check
63 * {@link Roo.EventObject#getKey} to determine which key was pressed.
64 * @param {Roo.form.Field} this
65 * @param {Roo.EventObject} e The event object
71 Roo.extend(Roo.Editor, Roo.Component, {
73 * @cfg {Boolean/String} autosize
74 * True for the editor to automatically adopt the size of the underlying field, "width" to adopt the width only,
75 * or "height" to adopt the height only (defaults to false)
78 * @cfg {Boolean} revertInvalid
79 * True to automatically revert the field value and cancel the edit when the user completes an edit and the field
80 * validation fails (defaults to true)
83 * @cfg {Boolean} ignoreNoChange
84 * True to skip the the edit completion process (no save, no events fired) if the user completes an edit and
85 * the value has not changed (defaults to false). Applies only to string values - edits for other data types
86 * will never be ignored.
89 * @cfg {Boolean} hideEl
90 * False to keep the bound element visible while the editor is displayed (defaults to true)
94 * The data value of the underlying field (defaults to "")
98 * @cfg {String} alignment
99 * The position to align to (see {@link Roo.Element#alignTo} for more details, defaults to "c-c?").
103 * @cfg {Boolean/String} shadow "sides" for sides/bottom only, "frame" for 4-way shadow, and "drop"
104 * for bottom-right shadow (defaults to "frame")
108 * @cfg {Boolean} constrain True to constrain the editor to the viewport
112 * @cfg {Boolean} completeOnEnter True to complete the edit when the enter key is pressed (defaults to false)
114 completeOnEnter : false,
116 * @cfg {Boolean} cancelOnEsc True to cancel the edit when the escape key is pressed (defaults to false)
120 * @cfg {Boolean} updateEl True to update the innerHTML of the bound element when the update completes (defaults to false)
125 onRender : function(ct, position){
126 this.el = new Roo.Layer({
133 constrain: this.constrain
135 this.el.setStyle("overflow", Roo.isGecko ? "auto" : "hidden");
136 if(this.field.msgTarget != 'title'){
137 this.field.msgTarget = 'qtip';
139 this.field.render(this.el);
141 this.field.el.dom.setAttribute('autocomplete', 'off');
143 this.field.on("specialkey", this.onSpecialKey, this);
144 if(this.swallowKeys){
145 this.field.el.swallowEvent(['keydown','keypress']);
148 this.field.on("blur", this.onBlur, this);
150 this.field.on("autosize", this.el.sync, this.el, {delay:1});
154 onSpecialKey : function(field, e)
156 //Roo.log('editor onSpecialKey');
157 if(this.completeOnEnter && e.getKey() == e.ENTER){
162 // do not fire special key otherwise it might hide close the editor...
163 if(e.getKey() == e.ENTER){
166 if(this.cancelOnEsc && e.getKey() == e.ESC){
170 this.fireEvent('specialkey', field, e);
175 * Starts the editing process and shows the editor.
176 * @param {String/HTMLElement/Element} el The element to edit
177 * @param {String} value (optional) A value to initialize the editor with. If a value is not provided, it defaults
178 * to the innerHTML of el.
180 startEdit : function(el, value){
184 this.boundEl = Roo.get(el);
185 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
187 this.render(this.parentEl || document.body);
189 if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){
193 this.field.setValue(v);
195 var sz = this.boundEl.getSize();
196 switch(this.autoSize){
198 this.setSize(sz.width, "");
201 this.setSize("", sz.height);
204 this.setSize(sz.width, sz.height);
207 this.el.alignTo(this.boundEl, this.alignment);
210 Roo.QuickTips.disable();
216 * Sets the height and width of this editor.
217 * @param {Number} width The new width
218 * @param {Number} height The new height
220 setSize : function(w, h){
221 this.field.setSize(w, h);
228 * Realigns the editor to the bound field based on the current alignment config value.
230 realign : function(){
231 this.el.alignTo(this.boundEl, this.alignment);
235 * Ends the editing process, persists the changed value to the underlying field, and hides the editor.
236 * @param {Boolean} remainVisible Override the default behavior and keep the editor visible after edit (defaults to false)
238 completeEdit : function(remainVisible){
242 var v = this.getValue();
243 if(this.revertInvalid !== false && !this.field.isValid()){
245 this.cancelEdit(true);
247 if(String(v) === String(this.startValue) && this.ignoreNoChange){
248 this.editing = false;
252 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
253 this.editing = false;
254 if(this.updateEl && this.boundEl){
255 this.boundEl.update(v);
257 if(remainVisible !== true){
260 this.fireEvent("complete", this, v, this.startValue);
267 if(this.hideEl !== false){
271 if(Roo.isIE && !this.fixIEFocus){ // IE has problems with focusing the first time
272 this.fixIEFocus = true;
273 this.deferredFocus.defer(50, this);
277 this.fireEvent("startedit", this.boundEl, this.startValue);
280 deferredFocus : function(){
287 * Cancels the editing process and hides the editor without persisting any changes. The field value will be
288 * reverted to the original starting value.
289 * @param {Boolean} remainVisible Override the default behavior and keep the editor visible after
290 * cancel (defaults to false)
292 cancelEdit : function(remainVisible){
294 this.setValue(this.startValue);
295 if(remainVisible !== true){
303 if(this.allowBlur !== true && this.editing){
315 if(this.field.collapse){
316 this.field.collapse();
319 if(this.hideEl !== false){
323 Roo.QuickTips.enable();
328 * Sets the data value of the editor
329 * @param {Mixed} value Any valid value supported by the underlying field
331 setValue : function(v){
332 this.field.setValue(v);
336 * Gets the data value of the editor
337 * @return {Mixed} The data value
339 getValue : function(){
340 return this.field.getValue();