1

There's a form with two text fields and one checkbox, all of them are required and have the required attribute.

The submit button should only get enabled if the required inputs are filled and checked.

With the current code the text field validation seems to work fine however it doesn't have an effect on the checkbox.

Jsfiddle

<form action="#otherForm">
   Name * <input name="otherForm-name1" placeholder="required" required> <br />
   Tel * <input name="otherForm-surname" placeholder="required" required> <br />
   <input type="checkbox" name="otherForm-chcekbox" required><label for="otherForm-chcekbox">I agree</label> <br />
   <button id="otherForm-submitBtn" class="monitored-btn" type="submit">Submit</button>
</form>

<script>
    const inputSelector = ':input[required]:visible';

    function checkForm() {
        // here, "this" is an input element
        var isValidForm = true;
        $(this.form).find(inputSelector).each(function() {
            if (!this.value.trim()) {
                isValidForm = false;
            }
        });
        $(this.form).find('.monitored-btn').prop('disabled', !isValidForm);
        return isValidForm;
    }
    $('.monitored-btn').closest('form')
        // in a user hacked to remove "disabled" attribute, also monitor the submit event
        .submit(function() {
            // launch checkForm for the first encountered input,
            // use its return value to prevent default if form is not valid
            return checkForm.apply($(this).find(':input')[0]);
        })
        .find(inputSelector).keyup(checkForm).keyup();
</script>
Sachin
  • 40,216
  • 7
  • 90
  • 102
coce
  • 49
  • 9
  • You don't need a checkbox in this form. Just replace it with a text like `By submitting this form I agree with `. – Kosh Jan 08 '19 at 00:30
  • 2
    @KoshVery—in many jurisdictions, and depending on context, the checkbox **is** required. – RobG Jan 08 '19 at 00:33
  • @RobG, could you please provide some links to the corresponding laws? – Kosh Jan 08 '19 at 00:56
  • @KoshVery This isn't some kind of legal advice forum, but in many cases you need user's explicit consent instead of implicit consent. An example will be GDPR, where users need to explicit consent to have their data collected. – Terry Jan 08 '19 at 01:07
  • @KoshVery—client's I've done work for have legal advice that says a checkbox (or similar UI widget) is required where a consumer is asked to agree to terms and conditions, so I put them in. They can't be pre-checked, the user must actually select the checkbox and check it. If you work on a consumer ecommerce site you'll soon find out, it will likely be an explicit requirement if the jurisdiction requires it (and the BA has done their job properly). If you want more, seek your own advice. – RobG Jan 08 '19 at 01:21
  • Thank you all guys. I did not ask for a legal advice, but for any proof links. – Kosh Jan 08 '19 at 02:01
  • Here you go @KoshVery https://ico.org.uk/media/about-the-ico/consultations/2013551/draft-gdpr-consent-guidance-for-consultation-201703.pdf – coce Jan 08 '19 at 09:49

5 Answers5

0

CSS only required

#otherForm-submitBtn {
  enabled: false;
  color: grey;
}

input[type='checkbox']:checked ~ #otherForm-submitBtn {
  enabled: true;
  color: black;
}
<form action="#otherForm">
   Name * <input name="otherForm-name1" placeholder="required" required> <br />
   Tel * <input name="otherForm-surname" placeholder="required" required> <br />
   <input type="checkbox" name="otherForm-chcekbox" required><label for="otherForm-chcekbox">I agree</label> <br />
   <button id="otherForm-submitBtn" class="monitored-btn" type="submit">Submit</button>
</form>
Bibberty
  • 4,670
  • 2
  • 8
  • 23
  • Given "*The submit button should only get enabled if the required inputs are filled and checked.*", this needs to check if the other controls are also valid. – RobG Jan 08 '19 at 00:47
  • Nice try, but the "disabled" button is still clickable (at least in FF). Try to play with `pointer-events` property. – Kosh Jan 08 '19 at 01:01
  • Thanks @KoshVery I think to RobG point, in the real world with a complex form that may change over time, a script function that scans class labelled controls dynamically would be a better solution here. – Bibberty Jan 08 '19 at 01:03
0

Keyup event won't work on a checkbox also it's better to check for checked prop instead of value on a checkbox. Try this:

const inputSelector = ':input[required]:visible';
function checkForm() {
  // here, "this" is an input element
  var isValidForm = true; 
  $(this.form).find(inputSelector).each(function() {
    if (!this.value.trim() || (this.type == 'checkbox' && !this.checked)) {
      isValidForm = false;
    }
  });
  $(this.form).find('.monitored-btn').prop('disabled', !isValidForm);
  return isValidForm;
}
$('.monitored-btn').closest('form')
  // in a user hacked to remove "disabled" attribute, also monitor the submit event
  .submit(function() {
    // launch checkForm for the first encountered input,
    // use its return value to prevent default if form is not valid
    return checkForm.apply($(this).find(':input')[0]);
  })
  .find(inputSelector).on("keyup change", checkForm);
Kubwimana Adrien
  • 2,463
  • 2
  • 8
  • 11
0

I would do this very similarly to Kubwimana Adrien's answer with initially rendering a disabled button.

Also, generally, it is not considered secure to set initial state of validation booleans to TRUE. Thus, changing the code a little.

    const inputSelector = ':input[required]:visible';

    function checkForm() {
        // here, "this" is an input element
        var isValidForm = false;
        $(this.form).find(inputSelector).each(function() {
            if (((this.type != 'checkbox') && (this.value.trim() != "")) || (this.type == 'checkbox' && this.checked)) {
                isValidForm = true;
            }
            else{
             isValidForm = false
                return false //break out of each loop
            }
        });
        $(this.form).find('.monitored-btn').prop('disabled', !isValidForm);
        return isValidForm;
    }
    $('.monitored-btn').closest('form')
        // in a user hacked to remove "disabled" attribute, also monitor the submit event
        .submit(function() {
            // launch checkForm for the first encountered input,
            // use its return value to prevent default if form is not valid
            return checkForm.apply($(this).find(':input')[0]);
        })
        .find(inputSelector).on("keyup change", checkForm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
  <form action="#otherForm">
         Name * <input name="otherForm-name1" placeholder="required" required> <br />
         Tel * <input name="otherForm-surname" placeholder="required" required> <br />
         <input type="checkbox" name="otherForm-chcekbox" required><label for="otherForm-chcekbox">I agree</label> <br />
         <button id="otherForm-submitBtn" class="monitored-btn" type="submit" disabled>Submit</button>
  </form></body>
0

You need to check that condition in everytime user type or click checkbox , and toggle disable by removeAttr and attr ..

$("form input").keyup(check);
$("form input:checkbox").on("click", check);

function check() {  
 if($("input[name='otherForm-name1']").val() != "" &&
   $("input[name='otherForm-surname']").val() != "" &&
   $("input[name='otherForm-chcekbox']").prop("checked") == true) {
     $("#otherForm-submitBtn").removeAttr("disabled");
     return;
   }
   $("#otherForm-submitBtn").attr("disabled",true);
   
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="#otherForm">
   Name * <input name="otherForm-name1" placeholder="required" required> <br />
   Tel * <input name="otherForm-surname" placeholder="required" required> <br />
   <input type="checkbox" name="otherForm-chcekbox" id="otherForm-chcekbox" required><label for="otherForm-chcekbox">I agree</label> <br />
   <button id="otherForm-submitBtn" class="monitored-btn" type="submit" disabled>Submit</button>
</form>
David JP
  • 1
  • 1
-1

Disable the button with disable attribute. Then listen for the checkbox change event, and either remove the attribute or add it.

<form action="#otherForm">
    <input type="checkbox" name="otherForm-chcekbox" required><label for="otherForm-chcekbox">I agree</label> <br />
   <button id="otherForm-submitBtn" class="monitored-btn" type="submit" disabled>Submit</button>
</form>



$(".otherForm-chcekbox").change(function() {
    if(this.checked) {
      if (checkForm()) {
        $("otherForm-submitBtn").removeAttr("disabled");   
      }
    } else {
      $("otherForm-submitBtn").attr("disabled", "disabled");   
    }
});
Classified
  • 232
  • 1
  • 6
  • Given "*The submit button should only get enabled if the required inputs are filled and checked.*", this needs to check if the other controls are also valid. – RobG Jan 08 '19 at 00:47
  • @RobG yes missed that. I have updated answer to call the checkForm function before removing the attribute. – Classified Jan 08 '19 at 00:58
  • Also, do not use `.attr()` for boolean attributes/props. use `.prop()` instead. – Terry Jan 08 '19 at 01:06
  • @Terry. Okay sure. But they are interchangeable right? Is there a performance deficit to using attr? Or is it just the principle of using prop() for anything that is not a string attribute? – Classified Jan 08 '19 at 01:22
  • When you remove an attribute you cannot re-add it in some browsers: see https://stackoverflow.com/questions/5874652/prop-vs-attr – Terry Jan 08 '19 at 01:24