-
Notifications
You must be signed in to change notification settings - Fork 135
File Picker
Where possible we follow W3C specs (as close as possible), but there's no spec for file picker element, so we came up with our own. Our file picker is not simply a part of upload procedure. It is more or less standalone and can also be used in conjunction with FileReader component for example, in order to get hold of raw file data, even when the browser doesn't support it natively.
<div id="container">
<a id="file-picker" href="javascript:;">Browse...</a>
</div>
<script>
var fileInput = new moxie.file.FileInput({
browse_button: 'file-picker', // or document.getElementById('file-picker')
accept: [
{title: "Images", extensions: "jpg,gif,png"} // accept only images
]
});
fileInput.onchange = function(e) {
// do something to files array
console.info(e.target.files); // or this.files or fileInput.files
};
fileInput.init(); // initialize
</script>
Single required option for the FileInput to be created properly (all other options are optional). Specifies the element on the page that should become a file picker. Component can even be instantiated like this:
var fileInput = new moxie.file.FileInput('file-picker');
By default FileInput will append it's own HTML structures to the immediate parent of the browse_button element. In some cases this is not a desired behavior, for example when browse_button
resides in dialog, that is constantly hidden and shown, or even better - destroyed and created from scratch for every popup. Third party shims, like Flash and Silverlight can hardly survive such activity. In this case you would rather want to append File Picker structures to an element that resides much higher in DOM hierarchy, or even directly to the document.body
itself. You can pass specific container element to use as a value for container
option. Component accepts both: ids or DOM elements.
One drawback to using some other element as a container for File Picker structures is that you are not guaranteed anymore that they will follow the browse_button
as it gets resized or repositioned on the page, and therefore effectively keep their role as a file picker. For this reason we have a special method - refresh(). You can use it whenever you need to manually update shim's position and size to match that of browse_button
.
File picker can be configured to accept only files of specific format - only images, or only archive files. However there is a slight stumble point - different runtimes denote file formats differently. HTML5/HTML4 use MIME types, while Flash/Silverlight rely on extensions. accept
option can take in both, and convert them into each other internally.
It can be array of key-value pairs:
...
accept: [
{ title: "Images", extensions: "jpg,gif,png" },
{ title: "Archives", extensions: "zip" }
]
...
Or a comma-delimited string of MIME types:
...
accept: "image/*,application/zip"
...
Check this entry from Plupload FAQ as well.
This setting is optional. If not specified FileInput (just as any other moxie component) will use default order: html5,flash,silverlight,html4
- html5
will be tried first and then - flash
, etc, until functional runtime is found. Setting is useful if you want to alter the order or omit some runtimes completely.
Array of file objects that were selected from the dialog. Is repopulated after each selection. Initially is set to null.
Necessity of a dedicated initialization method might be arguable, but there's no other way to subscribe to the events like ready, which is absolutely required, since initialization might take some time depending on the runtime and environment. Call init()
method when you have all event listeners attached and ready.
Sometimes you might want to disable file picker. While visually it might be as simple as assigning some class to browse_button
element, you need to actually call this method with true as only argument to make it not clickable. Call it with state
set to false to make it clickable again.
Resizes and repositions file picker shim to match the size and position of the browse_button
element (also see container).
Initialization of the file picker might take some time, especially for non native runtimes (like Flash
and Silverlight
). It is asynchronous operation. Obviously it might be undesirable to have a picker element that looks like functional one, before it truly is. You can use event ready
to catch the moment when picker becomes truly available and style your picker element accordingly.
<div id="container">
<a id="file-picker" class="disabled" href="javascript:;">Browse...</a>
</div>
<script>
...
fileInput.onready = function() {
moxie.utils.Dom.removeClass(document.getElementById('file-picker'), 'disabled');
};
...
</script>
change
event is triggered every time user closes the file dialog with one or several files being selected. It can be used to grab the handlers of those files. See an entry for files property and also check an example above.
Any DOM element can be turned into file picker. We do not automatically style file picker element in any way. You are free to provide your own stylings for the picker element and we will attach file dialog to it. After initialization your original picker element might stay or not stay accessible, depending on the runtime. This might successfully block any :hover
or :active
interactivity on top of it. This is why we provide mouseenter
, mouseleave
, mousedown
and mouseup
events on FileInput component.
...
fileInput.onmouseenter = function() {
moxie.utils.Dom.addClass(document.getElementById('file-picker'), 'hover');
};
fileInput.onmouseleave = function() {
moxie.utils.Dom.removeClass(document.getElementById('file-picker'), 'hover');
};
fileInput.onmousedown = function() {
moxie.utils.Dom.addClass(document.getElementById('file-picker'), 'active');
};
fileInput.onmouseup = function() {
moxie.utils.Dom.removeClass(document.getElementById('file-picker'), 'active');
};
...
Is triggered right after ready event, and whenever refresh() is invoked. Check corresponding documentation entry for more info.