Skip to content

File Picker

Davit Barbakadze edited this page Aug 6, 2017 · 13 revisions

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.

Table of Contents

Example

	<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>

Options

browse_button

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');

container

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.

accept

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.

runtime_order

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.

Properties

files

Array of file objects that were selected from the dialog. Is repopulated after each selection. Initially is set to null.

Methods

init()

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.

disable([state=true])

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.

refresh()

Resizes and repositions file picker shim to match the size and position of the browse_button element (also see container).

Events

ready

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

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.

mouseenter, mouseleave, mousedown and mouseup

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');
};
...

refresh

Is triggered right after ready event, and whenever refresh() is invoked. Check corresponding documentation entry for more info.