disable submit button until file selected for upload
Asked Answered
G

8

30

I have a form for uploading images. I'd like to disable the submit button, until user selects an image to upload. I'd like to do it with jQuery. Currently I have a JavaScript function that prevent user from submitting the form more than once by disabling it on submit. It'd be nice to combine this functionality with the new one.

Here's what I've got now:

<script type="text/javascript">
function submitonce(theform) {
    //if IE 4+ or NS 6+
    if (document.all || document.getElementById) {
        //screen thru every element in the form, and hunt down "submit" and "reset"
        for (i = 0; i < theform.length; i++) {
            var tempobj = theform.elements[i]
            if (tempobj.type.toLowerCase() == "submit" || tempobj.type.toLowerCase() == "reset")
            //disable em
            tempobj.disabled = true
        }
    }
}
</script>
<form name="form" enctype="multipart/form-data" method="post" action="upload.php" onSubmit="submitonce(this)">
 <input type="file" name="my_field" value="" />
 <input type="submit">
</form>
Gerigerianna answered 29/10, 2010 at 22:24 Comment(0)
E
52

The following seems to work reliably in Chrome and Firefox (Ubuntu 10.10), I'm unable to check on other platforms at the moment:

jQuery

$(document).ready(
    function(){
        $('input:file').change(
            function(){
                if ($(this).val()) {
                    $('input:submit').attr('disabled',false);
                    // or, as has been pointed out elsewhere:
                    // $('input:submit').removeAttr('disabled'); 
                } 
            }
            );
    });

html

<form action="#" method="post">
    <input type="file" name="fileInput" id="fileInput" />
    <input type="submit" value="submit" disabled />
</form>
<div id="result"></div>

Demo at JS Fiddle.

Esemplastic answered 29/10, 2010 at 22:44 Comment(4)
Thanks, I like the simplicity of this solution. How can it be modified to disable submit button again once the form is submitted?Gerigerianna
OK, got it. I've added the following function: $("#uploadForm").submit(function(){ $("input[type=submit]", this).attr("disabled", "disabled"); });Gerigerianna
I believe it would be better if you wrote the condition in this manner: $('.upload-pm-btn').attr('disabled', !$(this).val()); That way when you later on delete the value from the file upload, the button gets disabled again.Extent
Bug: If you unselect files, the button keeps active!Austen
G
19

Slightly simpler way using prop() which I think is the preferred way to do it now:

$('input:file').on("change", function() {
    $('input:submit').prop('disabled', !$(this).val()); 
});

Tested in IE, Chrome and FireFox.

Gunman answered 13/8, 2013 at 11:54 Comment(2)
This works fine, since it gets the button disabled if one unselects the file(s)Austen
This looks (to my admittedly jQuery-challenged eye) like it would disable all submit buttons on a given form that has an empty file upload control? Fine in the OP's example but it might be worth mentioning what is needed if there are multiple submits or multiple file upload controls?Dilution
P
8

If anyone is looking at this now (in 2021), this is the non-jquery solution I was able to come up with!! Some of this won't work with older browsers, so your mileage might vary- but if you're looking for a modern simple solution- this should be more than fine.

<div>
  <form method="post" action="someAction" enctype="multipart/form-data">
    <input type="file" name="fileUploaded" />
    <input type="submit" disabled="true" />
  </form>
  <script>
    document.querySelector("input[type=file]").onchange = ({
      target: { value },
    }) => {
      document.querySelector("input[type=submit]").disabled = !value;
    };
  </script>
</div>

Some notes about this solution: onChange takes a function that returns an object event, which has target and in there value. value is the string of the file name uploaded, and returns empty string when a user cancels the selection.


If you're looking for a solution that works with multiple file inputs and submissions, you can use class names to grab the right one.

<!-- index.html -->
<div>
  <form
    method="post"
    action="someAction"
    enctype="multipart/form-data"
  >
    <input class="fileUpload1" type="file" name="fileUploaded" />
    <input class="fileUpload1" type="submit" disabled="true" />
  </form>
</div>
<div>
  <form
    method="post"
    action="someOtherAction"
    enctype="multipart/form-data"
  >
    <input class="fileUpload2" type="file" name="fileUploaded2" />
    <input class="fileUpload2" type="submit" disabled="true" />
  </form>
</div>
// script.js
document.querySelectorAll("input[type=file]").forEach(
  (fileInput) =>
    (fileInput.onchange = ({ target: { value } }) => {
      document.querySelector(
        `input[type=submit].${fileInput.className}`
      ).disabled = !value;
    })
  );
Pend answered 21/11, 2021 at 16:53 Comment(5)
This is useful—though it's worth acknowledging that the original question explicitly asks for jQuery, and thus this answers a question that wasn't asked.Nurserymaid
You are absolutely correct that the question description asks for "I'd like to do it in jQuery"... However, it's not explicitly clear if the usage of jQuery is necessary, or if it's being asked naively- assuming that a pure js solution wouldn't be elegant. Hopefully this example shows that pure js solution can be achieved, and (because it's still JavaScript) is fully compatible with jQuery library in use. Furthermore, unlike the selected solution, this one correctly disables the button again if the selection is cancelled.Pend
I think it's also important to note that the original question was asked over a decade ago, but since this is one of the top Google results for disabling a form button in JavaScript, hopefully this helps people looking for a solution even if you are correct that it's not exactly fitting 😅Pend
The JS as given wasn't working for me. After a few minutes' troubleshooting I found the difficulty: it targets an input element, but my form uses a button element for its submit. I tweaked the JS accordingly and it works perfectly.Almeda
document.querySelector("button[type=submit]").disabled = !value;Almeda
T
5

Try

   $('#my_uploader').change(function() {
      if($(this).val()) {
        $('#my_submit_button').attr('disabled', '');
      } else {
        $('#my_submit_button').attr('disabled', 'disabled');
      }
    });
Three answered 29/10, 2010 at 22:32 Comment(4)
The disabled attribute is, properly, a Boolean; I'd recommend using .attr('disabled',true') / .attr('disabled',false).Esemplastic
you should use .removeAttr("disabled")Viridity
That's such an obvious point, @hunter, I'm ashamed that it had never occurred to me before you pointed out (sincerely, I'm not (to my shame) being facetious)... =/ +1Esemplastic
In HTML boolean attributes such as disabled and readonly can only legally take the name of the attribute. eg. disabled="disabled" readonly="readonly" Most browsers however accept any value for the attribute as being in the affimative. So the following are equivalent: disabled="disabled" disabled disabled="true" disabled="no" w3.org/TR/REC-html40/intro/…Flagler
G
4

instead of using script simply use required in input field

Glissando answered 21/11, 2021 at 14:38 Comment(0)
H
1

If you're a fan of ternary expressions:

$(document).ready(function(){
    var $submit = $('#submit_document');
    var $file = $('#file_path');

    $file.change(
        function(){
            $submit.attr('disabled',($(this).val() ? false : true));
        }
    );
});  
Hermitage answered 29/11, 2016 at 13:1 Comment(0)
D
1

Instead of disabling the submit, is it potentially more helpful to offer instruction if the user presses it without selecting a file first? So add something like this as the onclick code of the submit?

var bFileEmpty = !document.getElementById('filControl').value; if (bFileEmpty) alert('Please select a file'); return !bFileEmpty;

Note that your file control will need an ID as well as a name

Dilution answered 4/7, 2018 at 6:57 Comment(0)
C
0

A modern non-JQuery derivation of Ethan Jurman's answer, for multiple forms whose inputs are intermixed and not all within <form></form> blocks.

document.querySelectorAll("input[type=file]").forEach(
     (fileInput) =>
          (fileInput.onchange = ({target: {value}}) => {
               document.querySelector(
                    `input[form="${fileInput.form.id}"][type=submit]`
               ).disabled = !value;
          })
);
<form method="post" id="formA"></form>
<form method="post" id="formB"></form>

<input form="formA" type="file">
<input form="formA" type="submit" disabled="true">
<br>
<input form="formB" type="file">
<input form="formB" type="submit" disabled="true">

Make sure that code is not executed until the document has been loaded, or else the elements won't yet exist for it to attach the events handlers to.

Cailean answered 30/7, 2024 at 12:3 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.