If you need to validate user-uploaded files not only on the server, but also on the client, or you want to allow the user to select several files to load at once (multiple = "multiple"), then most likely you will encounter some difficulties when using Ext.form .field .File.
The essence of the problem
Checking the extension of the file being downloaded, if the user has selected only one file, is not difficult - simply declare vtype and see the value input-a:
Ext.apply(Ext.form.field.VTypes, { file: function(val, field) { var types = ['rtf', 'pdf', 'doc'], ext = val.substring(val.lastIndexOf('.') + 1); if(Ext.Array.indexOf(types, ext) === -1) { return false; } return true; } ,fileText: 'Invalid file' });
Problems begin when there are several files, and / or you need to check the “weight” of the file. The thing is that in the code above, the field refers not to the input in which the selected files are located, but to the table in which the input lies.
Getting to the input itself is easy enough:
var input = Ext.get(field.id+'-fileInputEl'); - input.files.
If it is not clear for someone, the line above on vanilla.js will sound like this:
var input = document.getElementById(field.id+'-fileInputEl');
Probably vanilla would even save a few matches, but I don’t really like when porridge starts, and my body doesn’t feel the difference in work.
')
If there is only one file, and you are not against using non-native input file loading, then the problem is solved (you can say it wasn’t) - we get the file upload field and validate the file weight using the File API. Otherwise - some problems remain:
1. When selecting several files (after some manipulations), the field on the form will show you only the first selected file.
2. If you want native input, its size attribute will be 1, after setting inputType: 'file' in the field configuration, and setting the size: 50 property will not help you.
Regarding the use of native browser elements, there is no desire to hollify on this topic - I just prefer to use them if the element has any behavior and if there is such a possibility. It's just that this is more familiar to the user - he knows what to expect from this thing.
Although, if we digress a little from the topic, when FF in one of the recent updates adopted the Chrome-style attribute of the placeholder attribute (the text ceased to disappear with the focus on the field) - it slightly jarred me. I do not understand the advantages of this behavior - I always want to erase this text before entering.
Decision
If you google, the Internet, in most cases, will advise you to validate files only on the server, or use flash. If you want and can - you can do so. I also saw
ux , which can load many files and validate them - may also be an option.
And you can get by with just a few lines, and use the File API. At the same time, all IEs are falling off for us, but personally I don’t have much experience with this - the download option still remains, but I still validate it on the server. In addition, if you use ext and write a more or less complex application, then, most likely, you can dictate browsers to the end user.
We proceed in the following way - inherit from textfield, set inputType: 'file' to it, let us set size and input multiple in the configuration. Assign alias to this case for short access (xtype). The validation rules are described by vtype. All this will allow you to use the field with the desired behavior many times in any application view, and flexibly configure it (for example, specify the allowed file types and their maximum size).
We describe the field:
Ext.define('fileupload',{ extend: 'Ext.form.field.Text' ,alias: 'widget.fileupload'
I don’t even know if something needs clarification. If, in a nutshell, after the “drawing” of a native input, the size attribute is set (set in the configuration or defaulted to 1) and the multiple attribute if it is set in the configuration. Thus, we now have a native configurable input.
We describe the validator:
Ext.apply(Ext.form.field.VTypes, { file: function(val, field) { var input, files, file ,acceptSize = field.acceptSize || 4096
Here, I think, everything is also quite clear. Just set the default file types / size, get input and run through its files - check their type / size. Everything is very simple.
Now we can load and validate files, describing the form field as follows:
{ xtype: 'fileupload' ,vtype: 'file' ,multiple: true
In action, all this farming can be
viewed here - everything is collected in one file for clarity, although in general I love the fourth century EXT MWC.