Hybrid View
-
9 Sep 2008 2:19 PM #1
[2.2] FileUploadField reset + proposed solution
[2.2] FileUploadField reset + proposed solution
Hi all,
I have discovered that Ext.form.FileUploadField from the samples at [1] does not reset correctly when its parent form is reset. The FileUploadField does not define its own reset() function, and simply inherits one from Ext.form.TextField, meaning that the underlying <input type=file> remains unchanged. The upshot is that the 'change' event is not fired if you select the same file again after having reset the form.
Below is a modified version of FileUploadForm which implements a reset() function. Since browsers do not allow the value of an <input type=file> element to be changed, the reset function removes the existing <input> and replaces it with an exact copy. This works in all the browsers I'm able to test (FF3, FF2, Safari3 & Opera9 on OS X, XP; IE6, IE7 on XP).
In this example I've also added mouse listeners to the fileinput element, so that the fake icon button appears to represent the mouse actions.
Changes from the original are in bold.
Code:Ext.form.FileUploadField = Ext.extend(Ext.form.TextField, { /** * @cfg {String} buttonText The button text to display on the upload button (defaults to * 'Browse...'). Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text * value will be used instead if available. */ buttonText: 'Browse...', /** * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible * text field (defaults to false). If true, all inherited TextField members will still be available. */ buttonOnly: false, /** * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field * (defaults to 3). Note that this only applies if {@link #buttonOnly} = false. */ buttonOffset: 3, /** * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object. */ // private readOnly: true, /** * @hide * @method autoSize */ autoSize: Ext.emptyFn, // private initComponent: function(){ Ext.form.FileUploadField.superclass.initComponent.call(this); this.addEvents( /** * @event fileselected * Fires when the underlying file input field's value has changed from the user * selecting a new file from the system file selection dialog. * @param {Ext.form.FileUploadField} this * @param {String} value The file value returned by the underlying file input field */ 'fileselected' ); }, // private onRender : function(ct, position){ Ext.form.FileUploadField.superclass.onRender.call(this, ct, position); this.wrap = this.el.wrap({cls:'x-form-field-wrap x-form-file-wrap'}); this.el.addClass('x-form-file-text'); this.el.dom.removeAttribute('name'); this.createFileInput(); var btnCfg = Ext.applyIf(this.buttonCfg || {}, { text: this.buttonText }); this.button = new Ext.Button(Ext.apply(btnCfg, { renderTo: this.wrap, cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : '') })); if(this.buttonOnly){ this.el.hide(); this.wrap.setWidth(this.button.getEl().getWidth()); } this.addFileListener(); }, //private createFileInput : function() { this.fileInput = this.wrap.createChild({ id: this.getFileInputId(), name: this.name||this.getId(), cls: 'x-form-file', tag: 'input', type: 'file', size: 1 }); }, //private addFileListener : function() { this.fileInput.on('change', function(){ var v = this.fileInput.dom.value; this.setValue(v); this.fireEvent('fileselected', this, v); }, this); //make the fake icon button represent the mouse state on the transparent fileInput this.fileInput.on({ 'mouseover' : function() { this.button.addClass(['x-btn-over','x-btn-focus']) }, 'mouseout' : function() { this.button.removeClass(['x-btn-over','x-btn-focus','x-btn-click']) }, 'mousedown' : function() { this.button.addClass('x-btn-click') }, 'mouseup' : function() { this.button.removeClass(['x-btn-over','x-btn-focus','x-btn-click']) }, scope : this }) }, // private getFileInputId: function(){ return this.id+'-file'; }, // private onResize : function(w, h){ Ext.form.FileUploadField.superclass.onResize.call(this, w, h); this.wrap.setWidth(w); if(!this.buttonOnly){ var w = this.wrap.getWidth() - this.button.getEl().getWidth() - this.buttonOffset; this.el.setWidth(w); } }, // private preFocus : Ext.emptyFn, // private getResizeEl : function(){ return this.wrap; }, // private getPositionEl : function(){ return this.wrap; }, // private alignErrorIcon : function(){ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); }, //private reset : function(){ this.fileInput.remove(); this.createFileInput(); this.addFileListener(); Ext.form.FileUploadField.superclass.reset.call(this); } }); Ext.reg('fileuploadfield', Ext.form.FileUploadField);
There is perhaps a more elegant way to do the replace; I tried with DomHelper but I couldn't get the events all tied back up that way.
Matt.
[1] http://extjs.com/deploy/dev/examples...le-upload.htmlLast edited by mattbennett; 10 Sep 2008 at 4:59 AM. Reason: added mouse listeners to fileinput element
-
11 Sep 2008 7:31 AM #2
Thanks for your post Matt. I noticed the same problem and am glad to find your fix.
- Jit
-
23 Sep 2008 6:09 PM #3
how to add multi file by FileUploadField just like gmail.
it seems the FileUploadField just can add a file
-
23 Sep 2008 7:28 PM #4
please post requests for help in the Help forum.
please refrain from making identical posts in various forums too: http://extjs.com/forum/showthread.php?t=48024
Sencha Docs / Ext 3.x - ( Docs | Examples )
Learning Center / Saki's Examples (for 2.x) / HOWTO - ( Report Bugs | Post Proper Code )
-
10 Oct 2008 6:56 AM #5
improved again
improved again
Code:/* * Ext JS Library 2.2 * Copyright(c) 2006-2008, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ var FileUploadField = Ext.form.FileUploadField = Ext.extend(Ext.form.TextField, { /** * @cfg {String} buttonText The button text to display on the upload button (defaults to * 'Browse...'). Note that if you supply a value for {@link #buttonCfg}, the buttonCfg.text * value will be used instead if available. */ buttonText: 'Browse...', /** * @cfg {Boolean} buttonOnly True to display the file upload field as a button with no visible * text field (defaults to false). If true, all inherited TextField members will still be available. */ buttonOnly: false, /** * @cfg {Number} buttonOffset The number of pixels of space reserved between the button and the text field * (defaults to 3). Note that this only applies if {@link #buttonOnly} = false. */ buttonOffset: 3, /** * @cfg {Object} buttonCfg A standard {@link Ext.Button} config object. */ // private readOnly: true, /** * @hide * @method autoSize */ autoSize: Ext.emptyFn, // private initComponent: function(){ FileUploadField.superclass.initComponent.call(this); this.addEvents( /** * @event fileselected * Fires when the underlying file input field's value has changed from the user * selecting a new file from the system file selection dialog. * @param {Ext.form.FileUploadField} this * @param {String} value The file value returned by the underlying file input field */ 'fileselected' ); }, // private onRender : function(ct, position){ FileUploadField.superclass.onRender.call(this, ct, position); this.wrap = this.el.wrap({cls:'x-form-field-wrap x-form-file-wrap'}); this.el.addClass('x-form-file-text'); this.el.dom.removeAttribute('name'); this.createFileInput(); var btnCfg = Ext.applyIf(this.buttonCfg || {}, { text: this.buttonText }); this.button = new Ext.Button(Ext.apply(btnCfg, { renderTo: this.wrap, cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : '') })); if(this.buttonOnly){ this.el.hide(); this.wrap.setWidth(this.button.getEl().getWidth()); } this.addFileListener(); }, getName : function(){ return this.rendered && this.fileInput.dom.name ? this.fileInput.dom.name : (this.hiddenName || ''); }, // private getFileInputId: function(){ return this.id+'-file'; }, // private onResize : function(w, h){ FileUploadField.superclass.onResize.call(this, w, h); this.wrap.setWidth(w); if(!this.buttonOnly){ var w = this.wrap.getWidth() - this.button.getEl().getWidth() - this.buttonOffset; this.el.setWidth(w); } }, // private preFocus : Ext.emptyFn, // private getResizeEl : function(){ return this.wrap; }, // private getPositionEl : function(){ return this.wrap; }, // private alignErrorIcon : function(){ this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); }, createFileInput : function() { this.fileInput = this.wrap.createChild({ id: this.getFileInputId(), name: this.name || this.getId(), cls: 'x-form-file', tag: 'input', type: 'file', size: 1 }); if(this.disabled) { this.fileInput.dom.disabled = true; } }, addFileListener : function() { //make the fake icon button represent the mouse state on the transparent fileInput this.fileInput.on({ 'change': function(){ var v = this.fileInput.dom.value; this.setValue(v); this.fireEvent('fileselected', this, v); }, 'mouseover' : function() {this.button.addClass(['x-btn-over', 'x-btn-focus']) }, 'mouseout' : function() { this.button.removeClass(['x-btn-over', 'x-btn-focus','x-btn-click']) }, 'mousedown' : function() { this.button.addClass('x-btn-click') }, 'mouseup' : function() { this.button.removeClass(['x-btn-over', 'x-btn-focus', 'x-btn-click']) }, scope : this }); }, //private reset : function(){ Ext.destroy(this.fileInput); this.createFileInput(); this.addFileListener(); FileUploadField.superclass.reset.call(this); }, onDestroy : function(){ if(this.fileInput){ Ext.destroy(this.fileInput); } if(this.button) { this.button.destroy(); } FileUploadField.superclass.onDestroy.call(this); }, onEnable: function() { FileUploadField.superclass.onEnable.call(this); this.fileInput.dom.disabled = false; this.button.enable(); }, onDisable: function() { FileUploadField.superclass.onEnable.call(this); this.fileInput.dom.disabled = true; this.button.disable(); } }); Ext.reg('fileuploadfield', FileUploadField);
-
31 Oct 2008 4:50 AM #6
-
7 Nov 2008 8:52 AM #7
Big Thanks!
I was was just about to start working on reset issue an viola! Thanks!
-
12 Dec 2008 10:55 PM #8Sencha - Community Support Team
- Join Date
- Mar 2007
- Location
- The Netherlands
- Posts
- 24,251
- Vote Rating
- 41
Now the same thing as an override:
ps. I did add a call to removeAllListeners to avoid event leaks.Code:Ext.override(Ext.form.FileUploadField, { onRender : function(ct, position){ Ext.form.FileUploadField.superclass.onRender.call(this, ct, position); this.wrap = this.el.wrap({cls:'x-form-field-wrap x-form-file-wrap'}); this.el.addClass('x-form-file-text'); this.el.dom.removeAttribute('name'); this.createFileInput(); var btnCfg = Ext.applyIf(this.buttonCfg || {}, { text: this.buttonText }); this.button = new Ext.Button(Ext.apply(btnCfg, { renderTo: this.wrap, cls: 'x-form-file-btn' + (btnCfg.iconCls ? ' x-btn-icon' : '') })); if(this.buttonOnly){ this.el.hide(); this.wrap.setWidth(this.button.getEl().getWidth()); } this.addFileListener(); }, createFileInput : function() { this.fileInput = this.wrap.createChild({ id: this.getFileInputId(), name: this.name||this.getId(), cls: 'x-form-file', tag: 'input', type: 'file', size: 1 }); }, addFileListener : function() { this.fileInput.on({ change: function(){ var v = this.fileInput.dom.value; this.setValue(v); this.fireEvent('fileselected', this, v); }, mouseover: function() { this.button.addClass(['x-btn-over','x-btn-focus']) }, mouseout: function(){ this.button.removeClass(['x-btn-over','x-btn-focus','x-btn-click']) }, mousedown: function(){ this.button.addClass('x-btn-click') }, mouseup: function(){ this.button.removeClass(['x-btn-over','x-btn-focus','x-btn-click']) }, scope : this }); }, reset : function(){ this.fileInput.removeAllListeners(); this.fileInput.remove(); this.createFileInput(); this.addFileListener(); Ext.form.FileUploadField.superclass.reset.call(this); } });
-
18 Dec 2008 1:17 AM #9
Code works fine
Code works fine
dsonet code works fine! thanx a lot. I use it the reset the fileupload alone (not over the form - reset function)
-
23 Jul 2010 7:37 AM #10
how to get the FileUploadValue for validation
how to get the FileUploadValue for validation
if i try to get the value using fileUplodaField.getValue(),i am getting the error message like Object doest not support the property.
Is there any way to do it.
Any help would be Appreciated?



Reply With Quote