File.Select
Ask the user to select some files.
SECURITY NOTE: Browsers will only open a file selector in reaction to a user event. So rather than allowing malicious sites to ask for files whenever they please, the user at least have to click a button first. As a result, the following commands only work when they are triggered by some user event.
Ask the user to select one file. To ask for a single .zip
file you
could say:
import File.Select as Select
type Msg
= ZipRequested
| ZipLoaded File
requestZip : Cmd Msg
requestZip =
Select.file ["application/zip"] ZipLoaded
You provide (1) a list of acceptable MIME types and (2) a function to turn the
resulting file into a message for your update
function. In this case, we only
want files with MIME type application/zip
.
Note: This only works when the command is the direct result of a user event, like clicking something.
Note: This command may not resolve, partly because it is unclear how to
reliably detect Cancel
clicks across browsers. More about that in the
section on limitations below.
Ask the user to select one or more files. To ask for many image files, you could say:
import File.Select as Select
type Msg
= ImagesRequested
| ImagesLoaded File (Array File)
requestImages : Cmd Msg
requestImages =
Select.files ["image/png","image/jpg"] ImagesLoaded
In this case, we only want PNG and JPG files.
Notice that the function that turns the resulting files into a message takes two arguments: the first file selected and then a list of the other selected files. This guarantees that one file (or more) is available. This way you do not have to handle “no files loaded” in your code. That can never happen!
Note: This only works when the command is the direct result of a user event, like clicking something.
Note: This command may not resolve, partly because it is unclear how to
reliably detect Cancel
clicks across browsers. More about that in the
section on limitations below.
Limitations
The API here uses commands, but it seems like it could also provide tasks.
The trouble is that a Task
is guaranteed to succeed or fail. There should
not be any cases where it just does neither. File selection makes this tricky
because there are two limitations in JavaScript as of this writing:
- File selection must be a direct response to a user event. This is intended to help with security. It is not clear how to reliably detect when these commands were issued at invalid times, especially across browsers.
- The user can always click
Cancel
on the file dialog. It is quite difficult to reliably detect if someone has clicked this button across browsers, especially when it is hard to know if the dialog is even open in the first place.
I think it would be worth figuring out how to know these two things reliably
before exposing a Task
API for things.