5

I have an HTML5/Bootstrap form with hidden fields: style="display: none"

which i show/hide via jQuery:

show() | hide()

For field validation i use the attribute required.

I want to have all my hidden fields as required but when some of them don't appear then the form can't proceed to submission.

Any thoughts about how can i have validation enabled only to fields displayed by user selections?

P. Tzik
  • 133
  • 1
  • 3
  • 12

7 Answers7

7

You can use this trick:

inside HTML form:

<input type="text" name="username" required="required" class="input-hidden">

CSS class:

.input-hidden{
        height:0;
        width:0;
        visibility: hidden;
        padding:0;
        margin:0;
        float:right;
}
EmRa228
  • 1,226
  • 13
  • 22
3

You can add a class name for all the required attributes in the html:

<input type="text" name="first_name" class="card-payment-info" required>
<input type="text" name="last_name" class="card-payment-info" required>

and, from js event like a click, you can enable or disable the required attributes:

// disable require:
$(".card-payment-info").attr('required', false);
// enable require
$(".card-payment-info").attr('required', true);
J.C. Gras
  • 4,934
  • 1
  • 37
  • 44
1

Add a class .hideable to your hideable required inputs. Then use these functions instead of your show() and hide():

function show1() {
//Your show() code here
$('.hideable').attr('required', 'required');
}
function hide1() {
//Your hide() code here
$('.hideable').removeAttr('required');
}
1

1 - Change the form to "novalidate"

2 - Catch the submit event

3 - Force the browser to check individually each visible input with input.reportValidity()

$('form')
  .attr('novalidate', true)
  .on('submit', function(){
    var isValid = true;
    $('input:visible,select:visible,textarea:visible', this).each(function() {
      // report validity returns validity of input and display error tooltip if needed
      isValid = isValid && this.reportValidity();
      // break each loop if not valid
      return isValid;
    });
    // do not submit if not valid
    return isValid;
  })

I've made a JQuery tool for this that also uses a mutation observer to automatically apply on dynamically created forms.

https://github.com/severinmoussel/VisibilityFormValidator/blob/master/VisibilityFormValidator.js

Séverin
  • 137
  • 1
  • 6
0

I wrote a drop-in replacement for the built-in show() and hide() that removes required on hide and restores them back on show (for all child elements).

(function ($) {
    var oldShow = $.fn.show;
    $.fn.show = function () {
        oldShow.apply(this, arguments); //run the original "show" method
        this.find("[notrequired]").prop("required", true).removeAttr("notrequired");
        return this;
    };
    var oldHide = $.fn.hide;
    $.fn.hide = function () {
        oldHide.apply(this, arguments); //run the original "hide" method
        this.find("[required]").prop("required", false).attr("notrequired", "1");
        return this;
    };
})(jQuery);

UPD: published as a gist here in case anyone wants to add anything https://github.com/alex-jitbit/jquery-required-visibility/blob/main/showhide.js

Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149
0

You can add pointer-events: none;, so the user can't click on the hidden element and also the cursor doesn't change when you hover it. As @DeadApe answered in this question https://stackoverflow.com/a/65356856/6938902

0

One solution is to write your own validation-function:

This function checks all textareas and inputs in the default way, but first check if the input is displayed.

function validateFormOnlyVisableInputs(elForm) {
    var inputs = elForm.querySelectorAll("input, textarea");
    for (var i = 0; i < inputs.length; i++) {
        console.log(i);
        // display:none inputs ignorieren
        if (inputs[i].offsetParent === null) continue;
        if (!inputs[i].checkValidity()){
            inputs[i].reportValidity();
            return false;
        } 
            
    }
    return true;
}

You have to add an eventlistener to the submit-button and call the valdation function:

 
 // this is out of a class, so you have to remove this...
 // if you have problems you can write me ;)
 this.elSendButton = this.elForm.querySelector("Button");

 this.elSendButton.addEventListener("click", async (e) => {
     e.preventDefault();
     if (validateFormOnlyVisableInputs(this.elForm)) {
        this.elForm.submit();
        ...
Bergi
  • 323
  • 3
  • 11