X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/form/field/File.js diff --git a/src/form/field/File.js b/src/form/field/File.js new file mode 100644 index 00000000..814c00fb --- /dev/null +++ b/src/form/field/File.js @@ -0,0 +1,237 @@ +/** + * @class Ext.form.field.File + * @extends Ext.form.field.Text + +A file upload field which has custom styling and allows control over the button text and other +features of {@link Ext.form.field.Text text fields} like {@link Ext.form.field.Text#emptyText empty text}. +It uses a hidden file input element behind the scenes to allow user selection of a file and to +perform the actual upload during {@link Ext.form.Basic#submit form submit}. + +Because there is no secure cross-browser way to programmatically set the value of a file input, +the standard Field `setValue` method is not implemented. The `{@link #getValue}` method will return +a value that is browser-dependent; some have just the file name, some have a full path, some use +a fake path. +{@img Ext.form.File/Ext.form.File.png Ext.form.File component} +#Example Usage:# + + Ext.create('Ext.form.Panel', { + title: 'Upload a Photo', + width: 400, + bodyPadding: 10, + frame: true, + renderTo: Ext.getBody(), + items: [{ + xtype: 'filefield', + name: 'photo', + fieldLabel: 'Photo', + labelWidth: 50, + msgTarget: 'side', + allowBlank: false, + anchor: '100%', + buttonText: 'Select Photo...' + }], + + buttons: [{ + text: 'Upload', + handler: function() { + var form = this.up('form').getForm(); + if(form.isValid()){ + form.submit({ + url: 'photo-upload.php', + waitMsg: 'Uploading your photo...', + success: function(fp, o) { + Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.'); + } + }); + } + } + }] + }); + + * @constructor + * Create a new File field + * @param {Object} config Configuration options + * @xtype filefield + * @markdown + * @docauthor Jason Johnston + */ +Ext.define("Ext.form.field.File", { + extend: 'Ext.form.field.Text', + alias: ['widget.filefield', 'widget.fileuploadfield'], + alternateClassName: ['Ext.form.FileUploadField', 'Ext.ux.form.FileUploadField', 'Ext.form.File'], + uses: ['Ext.button.Button', 'Ext.layout.component.field.File'], + + /** + * @cfg {String} buttonText The button text to display on the upload button (defaults to + * 'Browse...'). Note that if you supply a value for {@link #buttonConfig}, the buttonConfig.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 Text members will still be available. + */ + buttonOnly: false, + + /** + * @cfg {Number} buttonMargin 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. + */ + buttonMargin: 3, + + /** + * @cfg {Object} buttonConfig A standard {@link Ext.button.Button} config object. + */ + + /** + * @event change + * 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.ux.form.FileUploadField} this + * @param {String} value The file value returned by the underlying file input field + */ + + /** + * @property fileInputEl + * @type {Ext.core.Element} + * A reference to the invisible file input element created for this upload field. Only + * populated after this component is rendered. + */ + + /** + * @property button + * @type {Ext.button.Button} + * A reference to the trigger Button component created for this upload field. Only + * populated after this component is rendered. + */ + + /** + * @cfg {String} fieldBodyCls + * An extra CSS class to be applied to the body content element in addition to {@link #fieldBodyCls}. + * Defaults to 'x-form-file-wrap' for file upload field. + */ + fieldBodyCls: Ext.baseCSSPrefix + 'form-file-wrap', + + + // private + readOnly: true, + componentLayout: 'filefield', + + // private + onRender: function() { + var me = this, + inputEl; + + me.callParent(arguments); + + me.createButton(); + me.createFileInput(); + + // we don't create the file/button til after onRender, the initial disable() is + // called in the onRender of the component. + if (me.disabled) { + me.disableItems(); + } + + inputEl = me.inputEl; + inputEl.dom.removeAttribute('name'); //name goes on the fileInput, not the text input + if (me.buttonOnly) { + inputEl.setDisplayed(false); + } + }, + + /** + * @private + * Creates the custom trigger Button component. The fileInput will be inserted into this. + */ + createButton: function() { + var me = this; + me.button = Ext.widget('button', Ext.apply({ + renderTo: me.bodyEl, + text: me.buttonText, + cls: Ext.baseCSSPrefix + 'form-file-btn', + preventDefault: false, + ownerCt: me, + style: me.buttonOnly ? '' : 'margin-left:' + me.buttonMargin + 'px' + }, me.buttonConfig)); + }, + + /** + * @private + * Creates the file input element. It is inserted into the trigger button component, made + * invisible, and floated on top of the button's other content so that it will receive the + * button's clicks. + */ + createFileInput : function() { + var me = this; + me.fileInputEl = me.button.el.createChild({ + name: me.getName(), + cls: Ext.baseCSSPrefix + 'form-file-input', + tag: 'input', + type: 'file', + size: 1 + }).on('change', me.onFileChange, me); + }, + + /** + * @private Event handler fired when the user selects a file. + */ + onFileChange: function() { + this.lastValue = null; // force change event to get fired even if the user selects a file with the same name + Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value); + }, + + /** + * Overridden to do nothing + * @hide + */ + setValue: Ext.emptyFn, + + reset : function(){ + this.fileInputEl.remove(); + this.createFileInput(); + this.callParent(); + }, + + onDisable: function(){ + this.callParent(); + this.disableItems(); + }, + + disableItems: function(){ + var file = this.fileInputEl, + button = this.button; + + if (file) { + file.dom.disabled = true; + } + if (button) { + button.disable(); + } + }, + + onEnable: function(){ + var me = this; + me.callParent(); + me.fileInputEl.dom.disabled = false; + me.button.enable(); + }, + + isFileUpload: function() { + return true; + }, + + extractFileInput: function() { + var fileInput = this.fileInputEl.dom; + this.reset(); + return fileInput; + }, + + onDestroy: function(){ + Ext.destroyMembers(this, 'fileInputEl', 'button'); + this.callParent(); + } + + +});