31

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>

8 Answers 8

53

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I like the simplicity of this solution. How can it be modified to disable submit button again once the form is submitted?
OK, got it. I've added the following function: $("#uploadForm").submit(function(){ $("input[type=submit]", this).attr("disabled", "disabled"); });
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.
Bug: If you unselect files, the button keeps active!
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.

2 Comments

This works fine, since it gets the button disabled if one unselects the file(s)
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?
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;
    })
  );

5 Comments

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.
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.
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 😅
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.
document.querySelector("button[type=submit]").disabled = !value;
5

Try

   $('#my_uploader').change(function() {
      if($(this).val()) {
        $('#my_submit_button').attr('disabled', '');
      } else {
        $('#my_submit_button').attr('disabled', 'disabled');
      }
    });

4 Comments

The disabled attribute is, properly, a Boolean; I'd recommend using .attr('disabled',true') / .attr('disabled',false).
you should use .removeAttr("disabled")
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)... =/ +1
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/…
4

instead of using script simply use required in input field

Comments

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));
        }
    );
});  

Comments

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

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.