4

I'm new to javascript / jquery so I may be missing something obvious, but I've found solutions that disable the submit button until all text fields are filled, and I've found solutions that disable it until a file is chosen. However, my form consists of a file input and 3 text fields and I cannot find a way of it being disabled until all text fields AND a file is chosen.

The distilled version of the code I'm working with is here:

HTML

    <div>
    <input type="file" /><br />
    <input type="text" /><br />
    <input type="text" /><br />
    <input type="text" /><br />
    <input type="submit" value="Upload" class="submit" id="submit" disabled="disabled" />
    </div>

JS

    $('.submit').click(function() {
var empty = $(this).parent().find("input").filter(function() {
        return this.value === "";
    });
    if(empty.length) {

        $('.submit').prop('disabled', false);
    }
    });
})()

Thanks for your help

https://jsfiddle.net/xG2KS/482/

Codedstuff
  • 179
  • 1
  • 3
  • 11

5 Answers5

2

Try capture the event on those field and checking the empty values by using another function, see below code :

$(':input').on('change keyup', function () {
  // call the function after
  // both change and keyup event trigger
  var k = checking();
  // if value inc not 0
  if (k) $('.submit').prop('disabled', true);
  // if value inc is 0
  else $('.submit').prop('disabled', false);
});

// this function check for empty values
function checking() {
  var inc = 0;
  // capture all input except submit button
  $(':input:not(:submit)').each(function () {
    if ($(this).val() == "") inc++;
  });
  return inc;
}

This is just an example, but the logic somehow like that.

Update : Event Delegation. You might need read this

 // document -> can be replaced with nearest parent/container
 // which is already exist on the page,
 // something that hold dynamic data(in your case form input)
 $(document).on('change keyup',':input', function (){..});

DEMO

Norlihazmey Ghazali
  • 9,000
  • 1
  • 23
  • 40
  • Thanks that fixes the jsfiddle, but for some reason it doesn't work with my actual code... Are there any possible reasons for this? It's in a form, uses placeholder text that is deleted on focus, uses a custom button and on click inserts the values into a database. Would any of those cause it not to work? – Codedstuff Nov 30 '15 at 02:02
  • 1
    does the input fields on form was created dynamically? if yes, try delegating those by doing like this : `$(document).on('change keyup',':input', function (){..});` – Norlihazmey Ghazali Nov 30 '15 at 02:04
  • That was it! Works perfectly now, thanks so much. I'd been stuck on that for ages! – Codedstuff Nov 30 '15 at 02:31
1

Please see this fiddle https://jsfiddle.net/xG2KS/482/

$('input').on('change',function(){
    var empty = $('div').find("input").filter(function() {
            return this.value === "";
        });

        if(empty.length>0) {

            $('.submit').prop('disabled', true);
        }
    else{
        $('.submit').prop('disabled', false);
    }
});

[1]:

1

The trick is

  • don’t disable the submit button; otherwise the user can’t click on it and testing won’t work
  • only when processing, only return true if all tests are satisfied

Here is a modified version of the HTML:

<form id="test" method="post" enctype="multipart/form-data" action="">
    <input type="file" name="file"><br>
    <input type="text" name="name"><br>
    <input type="text" name="email"><br>
    <button name="submit" type="submit">Upload</button>
</form>

and some pure JavaScript:

window.onload=init;
function init() {
    var form=document.getElementById('test');
    form.onsubmit=testSubmit;

    function testSubmit() {
        if(!form['file'].value) return false;
        if(!form['name'].value) return false;
        if(!form['email'].value) return false;
    }
}

Note that I have removed all traces of XHTML in the HTML. That’s not necessary, of course, but HTML5 does allow a simpler version of the above, without JavaScript. Simply use the required attribute:

<form id="test" method="post" enctype="multipart/form-data" action="">
    <input type="file" name="file" required><br>
    <input type="text" name="name" required><br>
    <input type="text" name="email" required><br>
    <button name="submit" type="submit">Upload</button>
</form>

This prevents form submission if a required field is empty and works for all modern (not IE8) browsers.

Manngo
  • 14,066
  • 10
  • 88
  • 110
1

Listen for the input event on file and text input elements, count number of unfilled inputs and, set the submit button's disabled property based on that number. Check out the demo below.

$(':text,:file').on('input', function() {
    //find number of unfilled inputs
    var n = $(':text,:file').filter(function() {
        return this.value.trim().length == 0;
    }).length;
    
    //set disabled property of submit based on number
    $('#submit').prop('disabled', n != 0);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
    <input type="file" /><br />
    <input type="text" /><br />
    <input type="text" /><br />
    <input type="text" /><br />
    <input type="submit" value="Upload" class="submit" id="submit" disabled="disabled" />
</div>
PeterKA
  • 24,158
  • 5
  • 26
  • 48
1

For my approach, I'd rather use array to store if all the conditions are true. Then use every to make sure that all is true

$(function(){
    function validateSubmit()
    {
       var result = [];
       $('input[type=file], input[type=text]').each(function(){
          if ($(this).val() == "")
            result.push(false);
          else
            result.push(true);
       });
       return result;
    }

    $('input[type=file], input[type=text]').bind('change keyup', function(){
       var res = validateSubmit().every(function(elem){
          return elem == true;
       });

       if (res)
        $('input[type=submit]').attr('disabled', false);
       else
        $('input[type=submit]').attr('disabled', true);
    });
});

Fiddle

choz
  • 17,242
  • 4
  • 53
  • 73