2

I'm trying to implement a file upload button, where once a file is selected, the user is directed to another page with a form to fill in extra data before submitting.

Is this possible? To pass the input value over to another page? I noticed that the "value" of the form item is not the true value (i.e. prefixed with "C:\fakepath\"), so a simple setValue() on the form will probably not work.

If it makes any difference, I am using angular and ui-router. And when I say change page, I really mean change state.

kennyg
  • 999
  • 2
  • 10
  • 23
  • 5
    you can't. allowing this would allow anyone to specify the path for ANY file on a user's system. e.g. an incredibly massive security problem. upload the file on one form, stuff it somewhere safe on the system, and then pull it out when the second form is submitted. – Marc B Jun 17 '15 at 20:30
  • 2
    @MarcB -- Since OP is working within a SPA, you could probably just store the file data in a service on input change, and then fetch from that service. (or would that be lost?) – tymeJV Jun 17 '15 at 20:31
  • technically you _could_ but you would have to use an iframe and use [window.postmessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage), specifying the file object as a [Transferable](https://developer.mozilla.org/en-US/docs/Web/API/Transferable) – Travis Kaufman Jun 17 '15 at 20:32
  • 2
    Use a variable and store the value of the `HTMLInputElement.files` property. Done. – Ram Jun 17 '15 at 20:32
  • I guessed as much. Didn't think the "direct" approach would have worked for the same reasoning you gave. There must be a workaround that someone has come up with that doesn't affect security. Worst case, I can try to combine the two pages in one and simple keep one or the other in a hidden div at any time... – kennyg Jun 17 '15 at 20:32
  • @Vohuman No, the precise file path is not accessible (let alone for storage in a variable) for security reasons. – Terry Jun 17 '15 at 20:33
  • 1
    @Terry One doesn't use the value property of the file input. What OP needs is the `files` property which returns a `FileList` object. It's a SPA application and the variable can be used in other states. – Ram Jun 17 '15 at 20:34
  • you can convert it to a hidden input or two to pass the file meta and file data, but you can't keep the file input populated between loads. – dandavis Jun 17 '15 at 20:35
  • @Travis Kaufman that's all new to me. Based on your wording though it seems like you don't think it'd be a good idea? – kennyg Jun 17 '15 at 20:35
  • I think that @Vohuman's solution(s) is/are the best. If it's a single-page app you can save the uploaded file as a variable and pass it along to the next controller route – Travis Kaufman Jun 17 '15 at 20:38
  • @Vohuman huh, interesting. I'm assuming then that you can set the files property manually on the other form then? – kennyg Jun 17 '15 at 20:39
  • 2
    You can read the file in a blob using the [File API](http://www.html5rocks.com/en/tutorials/file/dndfiles/) – Michael Jun 17 '15 at 20:41
  • Thanks @Michael, I'll take a look at the API. A quick skim doesn't seem to show an example of uploading the file once read, but I can probably figure it out. – kennyg Jun 17 '15 at 20:45
  • 1
    [Blob upload](http://stackoverflow.com/questions/19015555/pass-blob-through-ajax-to-generate-a-file) - it a jquery example but will also work with angular – Michael Jun 17 '15 at 20:49
  • Thanks, I'll try it out. – kennyg Jun 17 '15 at 20:52

2 Answers2

2

You can pass the File object from the HTMLInputElement.files as a parameter to the state: $state.go('form', {'file': file}).

I've created a fiddle to demonstrate this solution. The first state prompts the user to select a file, then redirects them to a second state passing the file as a parameter. In this example the file name is just printed out but you could easily read the file as well.

just95
  • 1,089
  • 8
  • 13
0

Try adding the form as a modal pop-up instead:

  $(function() {
    $("#dialog").dialog({
      autoOpen: false,
      show: {
        effect: "blind",
        duration: 1000
      },
      hide: {
        effect: "explode",
        duration: 1000
      }
    });

    $("#file").change(function() {
      $("#dialog").dialog("open");
    });
  });
<meta charset="utf-8">
<title>jQuery UI Dialog - Animation</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">

<div id="dialog" title="Basic dialog">
  <p>Put your form here, for example.</p>
</div>

<input type="file" id="file" />
omikes
  • 8,064
  • 8
  • 37
  • 50