2

So I have an image, as a input type. Now when you select the file you want, I want the form to submit. So that then you don't have to press the submit button. So this is what I did

<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="image" id="IMG_1" src="<?php echo $result['profile_picture']?>" alt="">
    <input type="file" onchange='this.form.submit();' id="my_file" style="display: none;" />
</form>

And now the issue is that the form submitted, right when the file browser opens, therefore no file will be selected. So how can I stop that from happening, and only continuing when the user selects the image.

  • 3
    You should not be sending such forms automatically, not even _after_ the user chose a file – let them f.e. instead of `small_little_file.txt` _accidentally_ chose `very_big_file.blob` or even `my_password_list.txt`, and you have a UX disaster right there. – CBroe Jul 06 '14 at 02:26
  • Well it would be an image, and I do have size restrictions on the backend. If they're not PNG or JPEG, it won't save @CBroe –  Jul 06 '14 at 02:26
  • @user3100859 server-side things will do little to stop a `< 4` GiB upload unless you're accessing the stream before it's complete and forecefully terminating the connection – Paul S. Jul 06 '14 at 02:35
  • Not that I'm endorsing your whole approach here, but couldn't you test that a selection has been made, something like `onchange='if (this.value) { this.form.submit(); }'`? – nnnnnn Jul 06 '14 at 02:36
  • @nnnnnn `this.value` on a `type="file"`? – Paul S. Jul 06 '14 at 02:39
  • @PaulS. - Why not? How else do you test if the user has made a file selection? It worked for me in Chrome. – nnnnnn Jul 06 '14 at 02:43
  • @nnnnnn I would use `this.files.length > 0` to make sure that a file had been selected; accessing `.value` will usually give something like `"C:\fakepath\file.ext"` and really I always feel like it should give a warning in the _Console_ or perhaps throw a security exception (it doesn't though) because currently it is all inconsistant and lies :P – Paul S. Jul 06 '14 at 02:51
  • the inconsistency doesnt matter here because the point is to just check whether or not a file has been selected – chiliNUT Jul 06 '14 at 03:15
  • @CBroe "should not" is, I think, much too strong. Arguably the most visible file input on the internet, at google.com/images, submits automatically. I would rather advise to be aware of this mistake as a possibility and to take measures to reduce its probability and severity. Verifying file type and size both client- and server-side is one good measure; another is a clear visual indication that the user won't get to review their selection. – twhb Jul 06 '14 at 03:50

2 Answers2

2

It seems to me that you're talking about two different things at the same time. Firstly, the use of type="image". That should be used for only two purposes, if you want the code to be cross-browser reliably rendered:

  1. To enter the geographic coordinates of the focal point of the cursor when the image, which must be a suited geographic map, is clicked.
  2. To serve as submit button.

See for the full story http://www.w3.org/TR/html-markup/input.image.html.

The second thing you're talking about is submitting the form without having to click a node with a submit function, but no submitting with page onload. That is just a matter of correct syntax: live demo; used code:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo auto-submit</title>
</head>
<body>
    <form name="theForm" action="http://www.google.com">
        <input type="file" onchange="theForm.submit()">
    </form>
</body>
</html>
1

I dont see any issue on your example with firefox or chrome (and not with IE11). Look at http://jsfiddle.net/Pd465/1/

I remember a similar issue on older IE versions. The solution was to change the onchange to onclick and set a timeout with 0ms. Even that it's looking a little hacky it worked and the timeout just waited for the open-dialog to close. (Note: this must be done by browser-detection since it won't work on ff or chrome)

A pure javascript solution would be (for jQuery solution look at the last edit):

function submitForm(){
   window.setTimeout(
       function(){
           //will be executed when the dialog is closed -> submit your form
           //you might want to check if a file is selected here since the onclick will be triggered also in case of pressing 'cancel'-button
            document.getElementById('submitForm').submit();
       }, 0
   );
}
....

<form id="submitForm" action="upload.php" method="post" enctype="multipart/form-data">
    <input type="image" id="IMG_1" src="<?php echo $result['profile_picture']?>" alt="">
    <input type="file" onclick='submitForm();' id="my_file" style="display: none;" />
</form>


EDIT :
I found the article again where i got this solution from: Jquery: change event to input file on IE


EDIT :
I did not see this is not only javascript but also jQuery tagged... so I think you can overtake the solution from @Clint Tseng of the article i mentioned above. His solution:

var $input = $('#your-file-input-element');

var someFunction = function()
{
    // what you actually want to do
};

if ($.browser.msie)
{
    // IE suspends timeouts until after the file dialog closes
    $input.click(function(event)
    {
        setTimeout(function()
        {
            if($input.val().length > 0) {
              someFunction();
            }
        }, 0);
    });
}
else
{
    // All other browsers behave
    $input.change(someFunction);
}
Community
  • 1
  • 1
L. Monty
  • 872
  • 9
  • 17
  • if you are using jQuery 1.9 or above, you will need to do the browser-check without ´$.browser´ ... since browser-detection has been removed in the new versions in favor of feature-detection – L. Monty Jul 06 '14 at 03:07