mozilla

Revision 36062 of Using files from web applications

  • Revision slug: Using_files_from_web_applications
  • Revision title: Using files from web applications
  • Revision id: 36062
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment style fix; no wording changes

Revision Content

{{ gecko_minversion_header("1.9.2") }}

{{ draft() }}

Using the File API added to the DOM in HTML5, it's now possible for web content to ask the user to select local files, then read the contents of those files. This selection can be done by either using an HTML input element, or by drag and drop.

Selecting files using HTML

Selecting a single file for use with the File API is simple:

<input type="file" id="input" onchange="handleFiles(this.files)" />

When the user selects a file, the handleFiles() function gets called with a FileList object containing the File object representing the file selected by the user.

If you want to let the user select multiple files, simply use the multiple attribute on the input element:

<input type="file" id="input" multiple="true" onchange="handleFiles(this.files)" />

In this case, the file list passed to the handleFiles() function contains one File object for each file the user selected.

Selecting files using drag and drop

You can also let the user drag and drop files into your web application.

The first step is to establish a drop zone. Exactly what part of your content will accept drops may vary depending on the design of your application, but making an element receive drop events is easy:

var dropbox;

dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);

In this example, we're turning the element with the ID "dropbox" into our drop zone. This is done by adding listeners for the dragenter, dragover, and drop events.

We don't actually need to do anything with the dragenter and dragover events in our case, so these functions are both simple. They just stop propagation of the event and prevent the default action from occurring:

function dragenter(e) {
  e.stopPropagation();
  e.preventDefault();
}

function dragover(e) {
  e.stopPropagation();
  e.preventDefault();
} 

The real magic happens in the drop() function:

function drop(e) {
  var dt = e.dataTransfer;
  var files = dt.files;

  handleFiles(files);
  e.stopPropagation();
  e.preventDefault();
}

Here, we retrieve the dataTransfer field from the event, then pull the file list out of it, passing that to handleFiles(). From this point on, handling the files is the same whether the user used the input element or drag and drop.

Getting information about selected files

The FileList object provided by the DOM lists all the files selected by the user, each specified as a File object. You can determine how many files the user selected by checking the value of the file list's length attribute:

var numFiles = files.length;

Individual File objects can be retrieved by simply accessing the list as an array:

for (var i = 0; i < files.length; i++) {
  var file = files[i];
  ..
}

This loop iterates over all the files in the file list.

There are three attributes provided by the File object that contain useful information about the file.

name
The file's name as a read-only string. This is just the file name, and does not include any path information.
size
The size of the file in bytes as a read-only 64-bit integer.
type
The MIME type of the file as a read-only string, or null if the type couldn't be determined.

Example: Showing thumbnails of user-selected images

Let's say you're developing the next great photo-sharing web site, and want to use HTML5 to display thumbnail previews of images before the user actually uploads them. Simply establish your input element or drop zone as discussed previously, and have them call a function such as the handleFiles() function below.

function handleFiles(files) {
  var preview = document.getElementById("preview");
  
  for (var i = 0; i < files.length; i++) {
    var file = files[i];
    var imageType = /image.*/;

    if (!file.type.match(imageType)) {
      continue;
    }

    var img = document.createElement("img");
    img.classList.add("obj");
    img.src = file.getAsDataURL();
    img.file = file;
    preview.appendChild(img);
    }
}

Here our loop handling the user-selected files looks at each file's type attribute to see if it's an image file (by doing a regular expression match on the string "image.*"). For each file that is an image, we create a new img element, setting its src attribute to a data URL loaded from the file. CSS can be used to establish any pretty borders, shadows, and to specify the size of the image, so that doesn't even need to be done here.

We add a file attribute to each image indicating the File for the image; this will let us fetch the images for actually uploading later. Finally, we use appendChild() to add the new thumbnail to the preview area of our document.

Revision Source

<p>{{ gecko_minversion_header("1.9.2") }}</p>
<p>{{ draft() }}</p>
<p>Using the File API added to the DOM in HTML5, it's now possible for web content to ask the user to select local files, then read the contents of those files. This selection can be done by either using an HTML <a href="/en/DOM/Input" title="en/DOM/Input"><code>input</code></a> element, or by drag and drop.</p>
<h2>Selecting files using HTML</h2>
<p>Selecting a single file for use with the File API is simple:</p>
<pre><code>&lt;input type="file" id="input" onchange="handleFiles(this.files)" /&gt;</code>
</pre>
<p>When the user selects a file, the <code>handleFiles()</code> function gets called with a <a href="/en/DOM/FileList" title="en/DOM/FileList"><code>FileList</code></a> object containing the <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> object representing the file selected by the user.</p>
<p>If you want to let the user select multiple files, simply use the <code>multiple</code> attribute on the <code>input</code> element:</p>
<pre><code>&lt;input type="file" id="input" multiple="true" onchange="handleFiles(this.files)" /&gt;</code>
</pre>
<p>In this case, the file list passed to the <code>handleFiles()</code> function contains one <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> object for each file the user selected.</p>
<h2>Selecting files using drag and drop</h2>
<p>You can also let the user drag and drop files into your web application.</p>
<p>The first step is to establish a drop zone. Exactly what part of your content will accept drops may vary depending on the design of your application, but making an element receive drop events is easy:</p>
<pre class="brush: js">var dropbox;

dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
</pre>
<p>In this example, we're turning the element with the ID "dropbox" into our drop zone. This is done by adding listeners for the <code>dragenter</code>, <code>dragover</code>, and <code>drop</code> events.</p>
<p>We don't actually need to do anything with the <code>dragenter</code> and <code>dragover</code> events in our case, so these functions are both simple. They just stop propagation of the event and prevent the default action from occurring:</p>
<pre class="brush: js">function dragenter(e) {
  e.stopPropagation();
  e.preventDefault();
}

function dragover(e) {
  e.stopPropagation();
  e.preventDefault();
} 
</pre>
<p>The real magic happens in the <code>drop()</code> function:</p>
<pre class="brush: js">function drop(e) {
  var dt = e.dataTransfer;
  var files = dt.files;

  handleFiles(files);
  e.stopPropagation();
  e.preventDefault();
}
</pre>
<p>Here, we retrieve the <code>dataTransfer</code> field from the event, then pull the file list out of it, passing that to <code>handleFiles()</code>. From this point on, handling the files is the same whether the user used the <code>input</code> element or drag and drop.</p><h2>Getting information about selected files</h2>
<p>The <a href="/en/DOM/FileList" title="en/DOM/FileList"><code>FileList</code></a> object provided by the DOM lists all the files selected by the user, each specified as a <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> object. You can determine how many files the user selected by checking the value of the file list's <code>length</code> attribute:</p>
<pre>var numFiles = files.length;
</pre>
<p>Individual <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> objects can be retrieved by simply accessing the list as an array:</p>
<pre class="brush: js">for (var i = 0; i &lt; files.length; i++) {
  var file = files[i];
  ..
}
</pre>
<p>This loop iterates over all the files in the file list.</p>
<p>There are three attributes provided by the <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> object that contain useful information about the file.</p>
<dl> <dt><code>name</code></dt> <dd>The file's name as a read-only string. This is just the file name, and does not include any path information.</dd> <dt><code>size</code></dt> <dd>The size of the file in bytes as a read-only 64-bit integer.</dd> <dt><code>type</code></dt> <dd>The MIME type of the file as a read-only string, or null if the type couldn't be determined.</dd>
</dl>
<h2>Example: Showing thumbnails of user-selected images</h2>
<p>Let's say you're developing the next great photo-sharing web site, and want to use HTML5 to display thumbnail previews of images before the user actually uploads them. Simply establish your input element or drop zone as discussed previously, and have them call a function such as the <code>handleFiles()</code> function below.</p>
<pre class="brush: js">function handleFiles(files) {
  var preview = document.getElementById("preview");
  
  for (var i = 0; i &lt; files.length; i++) {
    var file = files[i];
    var imageType = /image.*/;

    if (!file.type.match(imageType)) {
      continue;
    }

    var img = document.createElement("img");
    img.classList.add("obj");
    img.src = file.getAsDataURL();
    img.file = file;
    preview.appendChild(img);
    }
}
</pre>
<p>Here our loop handling the user-selected files looks at each file's <code>type</code> attribute to see if it's an image file (by doing a regular expression match on the string "image.*"). For each file that is an image, we create a new <code>img</code> element, setting its <code>src</code> attribute to a data URL loaded from the file. CSS can be used to establish any pretty borders, shadows, and to specify the size of the image, so that doesn't even need to be done here.</p>
<p>We add a <code>file</code> attribute to each image indicating the <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> for the image; this will let us fetch the images for actually uploading later. Finally, we use <a href="/En/DOM/Node.appendChild" title="en/DOM/element.appendChild"><code>appendChild()</code></a> to add the new thumbnail to the preview area of our document.</p>
Revert to this revision