Threaded View

  1. #1
    Sencha User
    Join Date
    Mar 2007
    Posts
    186
    Vote Rating
    0
    Nullity is on a distinguished road

      0  

    Default [v1.3] new Ext.form field type - InlineTextField

    [v1.3] new Ext.form field type - InlineTextField


    I created a new form field type called InlineTextField. On render, the field shows as plain text. When the text is clicked on, it changes to a regular TextField (basically like an EditorGrid), and then changes back to plain text when the field is blurred. This is much easier and faster than using an Ext.Editor, which I'm not even sure can be used in a form anyway.

    Here is the code:

    Code:
    Ext.form.InlineTextField = function(config) {
    	Ext.form.InlineTextField.superclass.constructor.call(this, config);
    
    	this.on('specialkey', function(f, e) {
    		if (e.getKey() == e.ESC) {
    			f.setValue(this.startValue);
    			f.blur();
    		}
    	}, this);
    };
    
    Ext.extend(Ext.form.InlineTextField, Ext.form.TextField, {
    	inlineClass: 'x-form-inline-field',
    	disabledClass: 'x-form-inline-field-disabled',
    	saveOnlyOnChange: true,
    	confirmSave: false,
    	confirmText: 'The data has been successfully saved.',
    
    	doSave : function() {
    		var cfg = this.autoSave;
    
    		this.params = (this.name || this.id) + '=' + this.getValue();
    
    		if (typeof cfg == 'object') {
    			this.method = cfg.method || 'POST';
    			this.callback = (!cfg.callback) ? {success: Ext.emptyFn, failure: Ext.emptyFn} :
    				{success: cfg.callback.success || cfg.callback, failure: cfg.callback.failure || Ext.emptyFn};
    			this.scope = cfg.scope || this.callback;
    
    			if (this.confirmSave === true) {
    				var success = function() {
    					Ext.MessageBox.alert('Success', this.confirmText);
    				}.createDelegate(this);
    
    				this.callback.success = success.createSequence(this.callback.success);
    			}
    
    			var p = (cfg.params) ? cfg.params : '';
    
    			if (p) {
    				if (typeof p == 'object') {
    					this.params += '&' + Ext.urlEncode(p);
    				}
    				else if (typeof p == 'string' && p.length) {
    					this.params += '&' + p;
    				}
    			}
    
    			this.url = (this.method == 'POST') ? cfg.url : cfg.url + '?' + this.params;
    		}
    		else if (typeof cfg == 'string') {
    			this.method = 'POST';
    			this.url = (this.method == 'POST') ? cfg : cfg + '?' + this.params;
    		}
    
    		Ext.Ajax.request({
    			url: this.url,
    			method: this.method,
    			success: this.callback.success,
    			failure: this.callback.failure,
    			params: this.params,
    			scope: this.scope
    		});
    	},
    
    	reset : function() {
    		Ext.form.TextField.superclass.reset.call(this);
    
    		if (this.value) {
    			this.setRawValue(this.value);
    		}
    		else if (this.emptyText && this.getRawValue().length < 1) {
    			this.setRawValue(this.emptyText);
    			this.el.addClass(this.emptyClass);
    		}
    	}
    });
    
    Ext.override(Ext.form.InlineTextField, {
    	onRender : Ext.form.TextField.prototype.onRender.createSequence(function() {
    		this.el.addClass(this.inlineClass);
    
    		if (this.editable === false) {
    			this.disabled = true;
    		}
    	}),
    
    	onFocus : Ext.form.TextField.prototype.onFocus.createSequence(function() {
    		if (this.editable !== false) {
    			this.el.removeClass(this.inlineClass);
    		}
    	}),
    
    	onBlur : Ext.form.TextField.prototype.onBlur.createSequence(function() {
    		if (this.isValid() && !this.el.hasClass(this.inlineClass)) {
    			this.el.addClass(this.inlineClass);
    
    			if (this.autoSave && (this.saveOnlyOnChange === false || this.getValue() != this.startValue)) {
    				this.doSave();
    			}
    		}
    	})
    });
    ... and here is the needed CSS:

    Code:
    .x-form-inline-field, textarea.x-form-inline-field {
    	background: transparent;
    	border: 1px solid transparent;
    	cursor: pointer;
    	overflow: hidden;
    }
    
    .x-form-inline-field-disabled {
    	color: #000000;
    	cursor: default;
    	opacity: 1.0;
    	-moz-opacity: 1.0;
    	filter: alpha(opacity=100);
    }
    It includes a couple new config options. The first is 'autoSave', which when set and the field is blurred, it does and ajax call to immediately save the changes. The 'autoSave' option accepts either a string containing the url for the ajax call, or an object, like so:

    Code:
    autoSave: '/path/ajax.php'
    or
    autoSave: {url: '/path/ajax.php', method: 'POST', callback: some_function, scope: this}
    There is also a 'saveOnlyOnChange' option which should be pretty self-explanatory. When true (default), the field only auto-saves the data on blur if it was changed. So, when false, the data is always saved, whether changed or not.


    UPDATE 1: I added code suggested by schmidetzki which cancels the edit if the ESC key is pressed.


    UPDATE 2 (9/10/2007): Updated code to version 1.2. Added new options: 'confirmSave' and 'confirmText'. The first, 'confirmSave' is a boolean which when true, will display a MessageBox containing the text set by 'confirmText' (optional) when the changes are saved successfully. Also, the 'autoSave' object now supports a 'scope' setting.


    UPDATE 3 (9/11/2007): Updated code for version 1.3. Changed the way 'confirmSave' was handled to fix a bug. Refactored some code to be cleaner.
    Attached Images
    Last edited by Nullity; 12 Sep 2007 at 9:05 AM. Reason: version 1.3