Usage
This function runs automatically, so it is not called manually. Is this incorrect?
Examples
Various validated input elements.
<form class="nebula-validate"> <div class="form-group"> <label class="form-control-label" for="yourname">Your Name</label> <input id="yourname" class="form-control form-control-lg nebula-validate-text" type="text" placeholder="Your name" required /> <small class="form-text text-muted">Basic text validates as long as there is value.</small> </div> <div class="form-group"> <label class="form-control-label" for="emailaddress">Email</label> <input id="emailaddress" class="form-control form-control-lg nebula-validate-email" type="email" placeholder="Email address" /> <div class="invalid-feedback hidden">Please check that you've entered a valid email address.</div> </div> <div class="form-group"> <label class="form-control-label" for="url">URL</label> <input id="url" class="form-control form-control-lg nebula-validate-url" type="url" placeholder="http://" /> <div class="invalid-feedback hidden">Please verify you have entered a valid URL.</div> </div> <div class="form-group"> <label class="form-control-label" for="phonenumber">Phone Number</label> <input id="phonenumber" class="form-control form-control-lg nebula-validate-phone" type="tel" placeholder="Phone number" /> <div class="invalid-feedback hidden">Please verify you have entered a valid phone number.</div> <small class="form-text text-muted">Supports variations of country codes, area codes, delimiters, and even letters. Try adding an extension, too!</small> </div> <div class="form-group"> <label class="form-control-label" for="birthday">Date of Birth</label> <input id="birthday" class="form-control form-control-lg nebula-validate-date" type="text" placeholder="Date of birth" /> <div class="invalid-feedback hidden">Please verify you have entered a valid date.</div> <small class="form-text text-muted">Supports both month day year and day month year formats. Also support written out days (with or without year).<br/>Example shown as text input type, but works well with date input type too.</small> </div> <div class="form-group"> <label class="form-control-label" for="birthday">Favorite NFL Team</label> <select id="fav-nfl-team" class="form-control form-control-lg nebula-validate-regex" data-valid-regex="eagles"> <option value="">Select a team...</option> <option value="eagles">Philadelphia Eagles</option> <option value="cowboys">Dallas Cowboys</option> <option value="giants">New York Giants</option> <option value="redskins">Washington Redskins</option> </select> <div class="invalid-feedback hidden">I'm sorry, the team you have selected is terrible.</div> <small class="form-text text-muted">Example of simple RegEx validation. With select menus, be sure the first option has <code>value=""</code></small> </div> <div class="form-group"> <label class="form-control-label" for="regexexample">Favorite HEX color</label> <div class="input-group"> <div class="input-group-addon">#</div> <input id="regexexample" class="form-control form-control-lg nebula-validate-regex" data-valid-regex="^#?([a-f0-9]{6}|[a-f0-9]{3})$" type="text" /> </div> <div class="invalid-feedback hidden">Invalid HEX code.</div> <small class="form-text text-muted">Example of more complex RegEx validation.</small> </div> <div class="form-group"> <label class="form-control-label">Choose an option:</label> <div class="form-check form-check-inline"> <label class="form-check-label"> <input type="radio" class="form-check-input nebula-validate-radio" name="example-radio-options" value="option1" required /> <div class="label-options"> I am right-handed</div> </label> </div> <div class="form-check form-check-inline"> <label class="form-check-label"> <input type="radio" class="form-check-input nebula-validate-radio" name="example-radio-options" value="option2" required /> <div class="label-options"> I am left-handed</div> </label> </div> <div class="invalid-feedback hidden">Please choose your handedness.</div> <small class="form-text text-muted">Nebula validation for radios only appears if inputs are somehow unchecked or use <code>applyValidationClasses()</code> manually.</small> </div> <div class="form-group"> <label class="form-control-label">Check all that apply:</label> <div class="form-check"> <label class="form-check-label"> <input type="checkbox" class="form-check-input nebula-validate-checkbox" name="example-checkbox-apply" value="live-on-earth" required /> <div class="label-options"> My primary residence on planet Earth.</div> </label> </div> <div class="form-check"> <label class="form-check-label"> <input type="checkbox" class="form-check-input nebula-validate-checkbox" name="example-checkbox-apply" value="eyes-closed" required /> <div class="label-options"> When my eyes are closed they are usually not also open.</div> </label> </div> <div class="form-check"> <label class="form-check-label"> <input type="checkbox" class="form-check-input nebula-validate-checkbox" name="example-checkbox-apply" value="never-used-internet" required /> <div class="label-options"> I have never used the Internet.</div> </label> </div> <div class="invalid-feedback hidden">Certainly at least one of those applies!</div> <small class="form-text text-muted">Checkbox validation only triggers after an input within the group becomes unchecked.</small> </div> <div class="form-group"> <label class="form-control-label" for="yourname">Message</label> <textarea id="yourmessage" class="form-control form-control-lg nebula-validate-textarea" placeholder="Enter your message here..." rows="4"></textarea> <div class="invalid-feedback hidden">Your message can not be empty.</div> <small class="form-text text-muted">Nebula removes validation when focused on textareas to avoid distractions.</small> </div> </form>
Applying a RegEx validator to a Contact Form 7 input field (Zip Code)
jQuery('input[name=zipcode]').removeClass('nebula-validate-text').addClass('nebula-validate-regex').attr('data-valid-regex', '^\\d{5}((-)?\\d{4})?$'); //Remember to escape your escapes!
Additional Notes
Use the class nebula-validate
on the form (or containing element) to enable validation. In Contact Form 7, either wrap the whole thing in a <div>
or modify the shortcode with html_class="nebula-validate"
as seen here.
Note: This validation is meant for visual assistance only (to improve user experience). It is not intended to do secure validation- please use server-side validation for security purposes! Pre-defined RegEx patterns may not perfectly capture all nuances- this is meant for simple forms.
Text / Select
Use the class nebula-validate-text
or nebula-validate-select
to validate simple text fields and select menus.
Success if they have any value.
Regular Expressions (RegEx)
Use the class nebula-validate-regex
to validate fields using a custom RegEx pattern. This requires an attribute of data-valid-regex
to be used on the same input. This validation method can be used on any type of input! Be sure to set the value
attribute accordingly on appropriate types (like select
, checkbox
, radio
, etc).
Warning if not matching pattern while typing, danger if not matching and not focused. Success if matching.
RegEx patterns should not include the start or end slashes /
or flags (/g
,/m
,/i
, etc).
Note: It is currently not possible to use RegEx on a Contact Form 7 form without using custom JavaScript (due to it needing a data attribute). Remember, if using JavaScript to designate the pattern
attribute, you’ll need to escape your escapes (See JS example above)!
Use the class nebula-validate-email
to validate email fields.
Warning if not valid email address while typing. Danger if invalid and not focused. Success if valid.
URL
Use the class nebula-validate-url
to validate URL fields.
Warning if not valid URL while typing. Danger if invalid and not focused. Success if valid.
Phone Number
Use the class nebula-validate-phone
to validate phone number fields.
Warning if not valid phone number while typing. Danger if invalid and not focused. Success if valid.
Date
Use the class nebula-validate-date
to validate date fields (this works on both date
and text
input types). This supports both month, day, year and day, month, year formats (and various delimiters). It also works with written-out dates (with or without years).
Warning if not valid date while typing. Danger if invalid and not focused. Success if valid.
Textarea
Use the class nebula-validate-textarea
to validate textareas.
Success if they have any value. Removes validation while typing (to avoid distraction).
Checkbox / Radio
Use the class nebula-validate-checkbox
or nebula-validate-radio
to validate checkboxes and radio fields.
Validation classes will only be applied after unchecking an input. This means that radio groups may not get validation classes without manual JavaScript.
Submit Button
When the submit button is hovered or focused on, any empty fields that are required will highlight with a red border as a real-time visual indicator for the user. This highlight uses the class nebula-empty-required
.
Source File
Located in /assets/js/modules/forms.js on line 561.
No Hooks
This function does not have any filters or actions available. Request one?nebula.liveValidator = function(){ //CF7 Invalid events nebula.dom.document.on('wpcf7invalid', function(e){ setTimeout(function(){ //This triggers before these classes are added by CF7 so wait for 1ms jQuery('#' + e.detail.unitTag).find('.wpcf7-not-valid').each(function(){ //Find invalid fields only within this CF7 form nebula.applyValidationClasses(jQuery(this), 'invalid', true); }); }, 1); }); //Standard text inputs and select menus nebula.dom.document.on('keyup change blur', '.nebula-validate-text, .nebula-validate-textarea, .nebula-validate-select', function(e){ if ( e.type === 'focusout' ){ jQuery(this).val(jQuery(this).val().trim()); //Trim leading/trailing whitespace on blur } if ( jQuery(this).val() === '' ){ nebula.applyValidationClasses(jQuery(this), 'reset', false); } else if ( jQuery(this).val().trim().length ){ nebula.applyValidationClasses(jQuery(this), 'valid', false); } else { nebula.applyValidationClasses(jQuery(this), 'invalid', ( e.type !== 'keyup' )); } }); //RegEx input nebula.dom.document.on('keyup change blur', '.nebula-validate-regex', function(e){ if ( e.type === 'focusout' ){ jQuery(this).val(jQuery(this).val().trim()); //Trim leading/trailing whitespace on blur } let pattern = new RegExp(jQuery(this).attr('data-valid-regex'), 'i'); if ( jQuery(this).val() === '' ){ nebula.applyValidationClasses(jQuery(this), 'reset', false); } else if ( pattern.test(jQuery(this).val()) ){ nebula.applyValidationClasses(jQuery(this), 'valid', false); } else { nebula.applyValidationClasses(jQuery(this), 'invalid', ( e.type !== 'keyup' )); } }); //URL inputs nebula.dom.document.on('keyup change blur', '.nebula-validate-url', function(e){ if ( e.type === 'focusout' ){ jQuery(this).val(jQuery(this).val().trim()); //Trim leading/trailing whitespace on blur } if ( jQuery(this).val() === '' ){ nebula.applyValidationClasses(jQuery(this), 'reset', false); } else if ( nebula.regex.url.test(jQuery(this).val()) ){ nebula.applyValidationClasses(jQuery(this), 'valid', false); } else { nebula.applyValidationClasses(jQuery(this), 'invalid', ( e.type !== 'keyup' )); } }); //Email address inputs nebula.dom.document.on('keyup change blur', '.nebula-validate-email', function(e){ if ( e.type === 'focusout' ){ jQuery(this).val(jQuery(this).val().trim()); //Trim leading/trailing whitespace on blur } if ( jQuery(this).val() === '' ){ nebula.applyValidationClasses(jQuery(this), 'reset', false); } else if ( nebula.regex.email.test(jQuery(this).val()) ){ nebula.applyValidationClasses(jQuery(this), 'valid', false); } else { nebula.applyValidationClasses(jQuery(this), 'invalid', ( e.type !== 'keyup' )); } }); //Phone number inputs nebula.dom.document.on('keyup change blur', '.nebula-validate-phone', function(e){ if ( e.type === 'focusout' ){ jQuery(this).val(jQuery(this).val().trim()); //Trim leading/trailing whitespace on blur } if ( jQuery(this).val() === '' ){ nebula.applyValidationClasses(jQuery(this), 'reset', false); } else if ( nebula.regex.phone.test(jQuery(this).val()) ){ nebula.applyValidationClasses(jQuery(this), 'valid', false); } else { nebula.applyValidationClasses(jQuery(this), 'invalid', ( e.type !== 'keyup' )); } }); //Date inputs nebula.dom.document.on('keyup change blur', '.nebula-validate-date', function(e){ if ( e.type === 'focusout' ){ jQuery(this).val(jQuery(this).val().trim()); //Trim leading/trailing whitespace on blur } //Used to use day.js to validate the date and check that it was between 1800-2999. Now just check that it is not empty. if ( jQuery(this).val() === '' ){ nebula.applyValidationClasses(jQuery(this), 'reset', false); } else { nebula.applyValidationClasses(jQuery(this), 'valid', ( e.type !== 'keyup' )); //This indicates it is valid as long as it isn't empty } }); //Checkbox and Radio //Note: The CF7 "Privacy Acceptance" checkbox does not accept custom classes, so we must use its ID directly here nebula.dom.document.on('change blur', '#cf7-privacy-acceptance, .nebula-validate-checkbox, .nebula-validate-radio', function(e){ if ( jQuery(this).closest('.form-group, .form-check').find('input:checked').length ){ nebula.applyValidationClasses(jQuery(this), 'reset', false); } else { nebula.applyValidationClasses(jQuery(this), 'invalid', true); } }); //Highlight empty required fields when focusing/hovering on submit button nebula.dom.document.on('mouseover focus', 'form [type="submit"], form #submit', function(){ //Must be deferred because Nebula replaces CF7 submit inputs with buttons let invalidCount = 0; //This is a non-essential, cosmetic helper, so escape if any errors occur try { jQuery(this).closest('form').find('[required], .wpcf7-validates-as-required').each(function(){ //Look for checked checkboxes or radio buttons if ( jQuery(this).find('input:checked').length ){ return; //Continue } //Look for empty fields if ( jQuery(this).val().trim().length === 0 ){ //Sometimes jQuery(this) is null and errors on .trim(), so wrapped the whole thing in a try jQuery(this).addClass('nebula-empty-required'); invalidCount++; } }); } catch { //Ignore } if ( invalidCount > 0 ){ let invalidCountText = ( invalidCount === 1 )? ' invalid field remains' : ' invalid fields remain'; jQuery('form [type="submit"], form #submit').attr('title', invalidCount + invalidCountText); } }); nebula.dom.document.on('mouseout blur', 'form [type="submit"], form #submit', function(){ //Must be deferred because Nebula replaces CF7 submit inputs with buttons jQuery(this).closest('form').find('.nebula-empty-required').removeClass('nebula-empty-required'); jQuery('form [type="submit"], form #submit').removeAttr('title'); }); };
Override
To override or disable this JavaScript function, simply redeclare it with the exact same function name. Remember: Some functionality is conditionally loaded via dynamic imports, so if your function is not overriding properly, try listening for a DOM event (described below).
For non-module import functions:
nebula.liveValidator = function(){ //Write your own code here, leave it blank, or return false. }
For dynamically imported module function overrides:
jQuery(window).on('load', function(){ nebula.liveValidator = function(){ //Write your own code here, leave it blank, or return false. } });
Custom Nebula DOM events do also exist, so you could also try the following if the Window Load listener does not work:
jQuery(document).on('nebula_module_loaded', function(module){ //Note that the module variable is also available to know which module specifically was imported if ( typeof nebula.liveValidator === 'function' ){ nebula.liveValidator = function(){ //Write your own code here, leave it blank, or return false. } } });