3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @docauthor Jason Johnston <jason@sencha.com>
18 * A file upload field which has custom styling and allows control over the button text and other
19 * features of {@link Ext.form.field.Text text fields} like {@link Ext.form.field.Text#emptyText empty text}.
20 * It uses a hidden file input element behind the scenes to allow user selection of a file and to
21 * perform the actual upload during {@link Ext.form.Basic#submit form submit}.
23 * Because there is no secure cross-browser way to programmatically set the value of a file input,
24 * the standard Field `setValue` method is not implemented. The `{@link #getValue}` method will return
25 * a value that is browser-dependent; some have just the file name, some have a full path, some use
28 * **IMPORTANT:** File uploads are not performed using normal 'Ajax' techniques; see the description for
29 * {@link Ext.form.Basic#hasUpload} for details.
34 * Ext.create('Ext.form.Panel', {
35 * title: 'Upload a Photo',
39 * renderTo: Ext.getBody(),
43 * fieldLabel: 'Photo',
48 * buttonText: 'Select Photo...'
53 * handler: function() {
54 * var form = this.up('form').getForm();
57 * url: 'photo-upload.php',
58 * waitMsg: 'Uploading your photo...',
59 * success: function(fp, o) {
60 * Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.');
68 Ext.define("Ext.form.field.File", {
69 extend: 'Ext.form.field.Text',
70 alias: ['widget.filefield', 'widget.fileuploadfield'],
71 alternateClassName: ['Ext.form.FileUploadField', 'Ext.ux.form.FileUploadField', 'Ext.form.File'],
72 uses: ['Ext.button.Button', 'Ext.layout.component.field.File'],
75 * @cfg {String} buttonText
76 * The button text to display on the upload button. Note that if you supply a value for
77 * {@link #buttonConfig}, the buttonConfig.text value will be used instead if available.
79 buttonText: 'Browse...',
82 * @cfg {Boolean} buttonOnly
83 * True to display the file upload field as a button with no visible text field. If true, all
84 * inherited Text members will still be available.
89 * @cfg {Number} buttonMargin
90 * The number of pixels of space reserved between the button and the text field. Note that this only
91 * applies if {@link #buttonOnly} = false.
96 * @cfg {Object} buttonConfig
97 * A standard {@link Ext.button.Button} config object.
102 * Fires when the underlying file input field's value has changed from the user selecting a new file from the system
103 * file selection dialog.
104 * @param {Ext.ux.form.FileUploadField} this
105 * @param {String} value The file value returned by the underlying file input field
109 * @property {Ext.Element} fileInputEl
110 * A reference to the invisible file input element created for this upload field. Only populated after this
111 * component is rendered.
115 * @property {Ext.button.Button} button
116 * A reference to the trigger Button component created for this upload field. Only populated after this component is
121 * @cfg {String} [fieldBodyCls='x-form-file-wrap']
122 * An extra CSS class to be applied to the body content element in addition to {@link #fieldBodyCls}.
124 fieldBodyCls: Ext.baseCSSPrefix + 'form-file-wrap',
127 * @cfg {Boolean} readOnly
128 * Unlike with other form fields, the readOnly config defaults to true in File field.
133 componentLayout: 'filefield',
136 onRender: function() {
140 me.callParent(arguments);
143 me.createFileInput();
145 // we don't create the file/button til after onRender, the initial disable() is
146 // called in the onRender of the component.
151 inputEl = me.inputEl;
152 inputEl.dom.removeAttribute('name'); //name goes on the fileInput, not the text input
154 inputEl.setDisplayed(false);
160 * Creates the custom trigger Button component. The fileInput will be inserted into this.
162 createButton: function() {
164 me.button = Ext.widget('button', Ext.apply({
168 cls: Ext.baseCSSPrefix + 'form-file-btn',
169 preventDefault: false,
170 style: me.buttonOnly ? '' : 'margin-left:' + me.buttonMargin + 'px'
171 }, me.buttonConfig));
176 * Creates the file input element. It is inserted into the trigger button component, made
177 * invisible, and floated on top of the button's other content so that it will receive the
180 createFileInput : function() {
182 me.fileInputEl = me.button.el.createChild({
184 cls: Ext.baseCSSPrefix + 'form-file-input',
188 }).on('change', me.onFileChange, me);
192 * @private Event handler fired when the user selects a file.
194 onFileChange: function() {
195 this.lastValue = null; // force change event to get fired even if the user selects a file with the same name
196 Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value);
200 * Overridden to do nothing
203 setValue: Ext.emptyFn,
208 me.fileInputEl.remove();
209 me.createFileInput();
210 me.inputEl.dom.value = '';
215 onDisable: function(){
220 disableItems: function(){
221 var file = this.fileInputEl,
222 button = this.button;
225 file.dom.disabled = true;
232 onEnable: function(){
235 me.fileInputEl.dom.disabled = false;
239 isFileUpload: function() {
243 extractFileInput: function() {
244 var fileInput = this.fileInputEl.dom;
249 onDestroy: function(){
250 Ext.destroyMembers(this, 'fileInputEl', 'button');