2

Imagine a newsletter subscription form. I have the form with just two different field types (text, checkbox), some of them need to be complete before submission. For sure, the required email field and at least one from the checkboxes. The submit/subscribe button should stay disabled until the condition from above is fulfilled. It also should revert from enabled to disabled state when the fields with values get empty. I know this kind of question has been answered here a few times already. I went through some examples from previous questions of this functionality working with radios and checkboxes or <input> fields only:

Some of them are answered but used code is outdated. Moreover, I'm not able to make a working code for my specific case. Quite close was Disable submit button with jQuery until all fields have values (input, radio, select, checkbox). I used them all to make it to as far as here: I can count a number of filled fields and enable the button when at least two of them are completed. However, two checkboxes (without the email) are enough - which is wrong. Can you please help me?

$(function() {
    $('.subscribe-form').on('input',':input',function() {
        var inputs = $('.subscribe-form :input');
        var num_inputs = inputs.length;
        var num_filled = inputs.filter(function() { return $(this).is(':checkbox')?$(this).is(':checked'):!!this.value }).length;
        $('.subscribe-form :submit').prop('disabled',(num_filled+1<num_inputs));
    });
});
.subscribe-form {
  width: 400px;
  margin: 50px;
}

.subscribe-form__row {
  padding: 0 0 10px;
  margin: 0 0 10px;
  border-bottom: 1px solid grey;
}

p {
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset class="subscribe-form">
  <div class="subscribe-form__row">
    <p>E-mail</p>
    <input type="text" placeholder="your e-mail" />
  </div>
  <div class="subscribe-form__row">
    <p>Interests</p>
    <label for="checkbox-1">Nature</label>
    <input id="checkbox-1" type="checkbox" />
    <label for="checkbox-2">Travel</label>
    <input id="checkbox-2" type="checkbox" />
  </div>

  <input type="submit" value="Subscribe" disabled />
</fieldset>
mik013
  • 21
  • 5

1 Answers1

1

I would count the email field and checkboxes separately.

Below, I added the required class to ease the selection of the required elements. Maybe you will need some not requiered fields someday.

Then, for the email field, I added an email class, because maybe you will want to add some first and last name fields in the future. I would suggest you to test it againt a regular expression instead of just empty... See this other SO answer to start on that.

Then having my_condition in a variable makes the code easier to read and maintain AND to debug... ;)

$(function() {
    $('.subscribe-form').on('input',':input',function() {
        console.clear() // Just for this demo...
    
        var email = $('.subscribe-form .required.email').filter((i,el)=>el.value!=="");
        var checkboxes = $('.subscribe-form .required:checkbox:checked');
        console.log("email",email.length,"checkbox",checkboxes.length)
        
        var my_condition = email.length>0 && checkboxes.length>0
        console.log(my_condition)
        $('.subscribe-form :submit').prop('disabled',!my_condition);
    });
});
.subscribe-form {
  width: 400px;
  margin: 50px;
}

.subscribe-form__row {
  padding: 0 0 10px;
  margin: 0 0 10px;
  border-bottom: 1px solid grey;
}

p {
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset class="subscribe-form">
  <div class="subscribe-form__row">
    <p>E-mail</p>
    <input type="text" placeholder="your e-mail" class="required email"/>
  </div>
  <div class="subscribe-form__row">
    <p>Interests</p>
    <label for="checkbox-1">Nature</label>
    <input id="checkbox-1" type="checkbox" class="required" />
    <label for="checkbox-2">Travel</label>
    <input id="checkbox-2" type="checkbox" class="required" />
  </div>

  <input type="submit" value="Subscribe" disabled />
</fieldset>
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
  • Thank you very much for the super quick answer! Seems to work for me. Could you please explain to me the `filter((i,el)=>el.value!=="")` syntax? I can read the `value!=="` part but not the rest. – mik013 Dec 07 '20 at 04:02
  • 1
    That is just an [arrow function expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) and is equivalent to `function(i,el){return el.value!==""})` and `function(){ return this.value!==""}`. I named the arguments `i` and `el` for index and element... I did not use `i` because iI needed only the second argument here. – Louys Patrice Bessette Dec 07 '20 at 16:37