Form validation
PHP
<form action="" method="POST" enctype="multipart/form-data" class="validate_form" autocomplete="off" novalidate>
<p class="sub_title">Contact Us Today</p>
<div class="row_f">
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">First Name</span>
<label>
<input type="text" name="fname" class="input || validate" autocomplete="off">
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Last Name</span>
<label>
<input type="text" name="lname" class="input || validate" autocomplete="off">
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Phone</span>
<label>
<input type="tel" name="phone" class="input || phone_mask || validate_tel" inputmode="numeric" autocomplete="off">
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Email</span>
<div class="input_icon">
<div class="svg_wrap">
<?= svg('iconChat2','') ?>
</div>
<div class="input_wrap">
<label>
<input type="text" name="email" class="input || validate_email" autocomplete="off">
</label>
</div>
</div>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Date of birth</span>
<label>
<input type="text" name="birthday" class="input || birthday || validate" autocomplete="off">
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Upload a Picture</span>
<input type="file" name="file-8[]" id="file-8" class="input_file || validate" data-multiple-caption="{count} files selected" multiple />
<label for="file-8" class="input">
<?= svg('iconUpload', '') ?>
<span>Choose a file</span>
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Street Address</span>
<label>
<input type="text" name="address" class="input || validate" autocomplete="off">
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">City</span>
<label>
<input type="text" name="city" class="input || validate" autocomplete="off">
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Province/State</span>
<label class="label_select">
<select name="state" class="input || validate_select">
<option value="" selected="" disabled="">Select Province</option>
<option value="AB">Alberta</option>
<option value="BC">British Columbia</option>
<option value="MB">Manitoba</option>
<option value="NB">New Brunswick</option>
<option value="NL">Newfoundland and Labrador</option>
<option value="NS">Nova Scotia</option>
<option value="ON">Ontario</option>
<option value="PE">Prince Edward Island</option>
<option value="QC">Quebec</option>
<option value="SK">Saskatchewan</option>
<option value="NT">Northwest Territories</option>
<option value="NU">Nunavut</option>
<option value="YT">Yukon</option>
</select>
</label>
</div>
</div>
<div class="col_3 || col_sm_6 || col_xs_12">
<div class="form_item">
<span class="pre_input">Postal Code</span>
<label>
<input type="text" name="postal" class="input || postal_mask || validate" autocomplete="off">
</label>
</div>
</div>
<div class="col_3 || col_sm_12">
<div class="form_item">
<span class="pre_input">Password</span>
<label class="label_input_icon">
<input type="password" name="password" placeholder="Enter Password" class="input || validate_pass" autocomplete="off">
<?= svg('iconLock2','') ?>
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<p>Experience</p>
<div class="controls_wrap || validate_checkbox">
<input type="checkbox" name="experience[]" class="checkbox" id="experience1" value="1 year">
<label for="experience1">1 year</label>
<input type="checkbox" name="experience[]" class="checkbox" id="experience2" value="2 years">
<label for="experience2">2 years</label>
<input type="checkbox" name="experience[]" class="checkbox" id="experience3" value="3 years">
<label for="experience3">3 years</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<p>Gender</p>
<div class="controls_wrap || validate_radio">
<input type="radio" name="gender" class="radio_button" id="male" value="Male">
<label for="male">Male</label>
<input type="radio" name="gender" class="radio_button" id="female" value="Female">
<label for="female">Female</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<p>Level of education</p>
<div class="controls_wrap || validate_checkbox">
<input type="checkbox" name="education[]" class="custom_checkbox" id="education1" value="Preschool">
<label for="education1">
<span class="checkbox_design">
<?= svg('iconCheckbox','') ?>
</span>
<span class="checkbox_text">Preschool</span>
</label>
<input type="checkbox" name="education[]" class="custom_checkbox" id="education2" value="Primary school">
<label for="education2">
<span class="checkbox_design">
<?= svg('iconCheckbox','') ?>
</span>
<span class="checkbox_text">Primary school</span>
</label>
<input type="checkbox" name="education[]" class="custom_checkbox" id="education3" value="High school">
<label for="education3">
<span class="checkbox_design">
<?= svg('iconCheckbox','') ?>
</span>
<span class="checkbox_text">High school</span>
</label>
</div>
</div>
<div class="col_6 || col_xs_12">
<p>Willing to Cross Border</p>
<div class="controls_wrap || validate_radio">
<input type="radio" name="cross_border" class="custom_radio_button" id="yes" value="Yes">
<label for="yes">
<span class="radio_button_design"></span>
<span class="radio_button_text">Yes</span>
</label>
<input type="radio" name="cross_border" class="custom_radio_button" id="no" value="No">
<label for="no">
<span class="radio_button_design"></span>
<span class="radio_button_text">No</span>
</label>
</div>
</div>
<div class="col_12">
<div class="form_item">
<span class="pre_input">Message</span>
<label>
<textarea name="message" class="input || validate" autocomplete="off"></textarea>
</label>
</div>
</div>
</div>
<div class="row_f || captcha_submit_block">
<div class="col_4 || col_xs_12">
<div class="form_item">
<span class="pre_input">Please Answer</span>
<label>
<input type="number" name="a" class="input || validate_cap" inputmode="numeric" placeholder="<?= $firstCaptchaNumber ?>+<?= $secondCaptchaNumber ?>=" autocomplete="off">
</label>
</div>
</div>
<div class="col_8 || col_xs_12 || button_right">
<button type="submit" class="button">Submit</button>
</div>
</div>
</form>
CSS
.validate_error{border:.1rem solid #e57373!important}
.validate_error::-webkit-input-placeholder{color:#e31e26!important}
.validate_error:-moz-placeholder{color:#e31e26!important}
.validate_error::-moz-placeholder{color:#e31e26!important}
.validate_error:-ms-input-placeholder{color:#e31e26!important}
.validate_error::-ms-input-placeholder{color:#e31e26!important}
.validate_error::placeholder{color:#e31e26!important}
.validate_error+.icon {color: #e57373 !important}
textarea.validate_error{border:.1rem solid #e57373!important}
.input_file.validate_error + .input {border: .1rem solid #e57373 !important}
.input_file.validate_error + .input span {color: #e31e26 !important}
.validate_checkbox.validate_error{border:none!important}
.validate_checkbox.validate_error .checkbox + label::before{border:.1rem solid #e57373!important}
.validate_checkbox.validate_error .custom_checkbox + label .checkbox_design{border:.1rem solid #e57373!important}
.validate_radio.validate_error{border:none!important}
.validate_radio.validate_error .radio_button + label::before{border:.1rem solid #e57373!important}
.validate_radio.validate_error .custom_radio_button + label .radio_button_design{border:.1rem solid #e57373!important}
/* toasts */
#toast{position:fixed;z-index:1503;width:100%;max-width:280px;left:2rem;right:2rem;bottom:2rem;background-color:#fff;color:#fff;display:none;-webkit-box-shadow:1px 5px 15px rgba(0,0,0,0.25);-moz-box-shadow:1px 5px 15px rgba(0,0,0,0.25);box-shadow:1px 5px 15px rgba(0,0,0,0.25);padding:1rem 2rem;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden}
#toast p{display:block;margin-bottom:0;margin-top:.3rem;color:#fff;font-size:1.4rem;font-family:'Nunito Sans',sans-serif}
#toast.error{background-color:rgba(237,28,36,.8)}
#toast.success{background-color:rgba(28,32,126,.8)}
.toast_close{position:absolute;color:#fff;top:.3rem;right:1rem;font-size:2.5rem;cursor:pointer}
.toast_icon{color:#fff;float:left;margin-right:2rem;font-size:3rem}
SCSS
/* Vars */
$font: 'Nunito Sans', sans-serif;
$white: #ffffff;
$red: #e31e26;
$validate: #e57373;
$toastError: rgba(237, 28, 36, .8);
$toastSuccess: rgba(28, 32, 126, .8);
.validate_error {
border: .1rem solid $validate !important;
&::placeholder {
color: $red !important;
}
+ .icon {
color: $validate !important;
}
}
textarea.validate_error {
border: .1rem solid $validate !important;
}
.input_file.validate_error + .input {
border: .1rem solid $validate !important;
span {
color: $red !important;
}
}
.validate_checkbox {
&.validate_error {
border: none !important;
.checkbox + label::before {
border: .1rem solid $validate !important;
}
.custom_checkbox + label .checkbox_design {
border: .1rem solid $validate !important;
}
}
}
.validate_radio {
&.validate_error {
border: none !important;
.radio_button + label::before {
border: .1rem solid $validate !important;
}
.custom_radio_button + label .radio_button_design {
border: .1rem solid $validate !important;
}
}
}
/* toasts */
#toast {
position: fixed;
z-index: 1503;
width: 100%;
max-width: 280px;
left: 2rem;
right: 2rem;
bottom: 2rem;
background-color: $white;
color: $white;
display: none;
box-shadow: 1px 5px 15px rgba(0, 0, 0, 0.25);
padding: 1rem 2rem;
backface-visibility: hidden;
p {
display: block;
margin-bottom: 0;
margin-top: .3rem;
color: $white;
font-size: 1.4rem;
font-family: $font;
}
&.error {
background-color: $toastError;
}
&.success {
background-color: $toastSuccess;
}
}
.toast_close {
position: absolute;
color: $white;
top: .3rem;
right: 1rem;
font-size: 2.5rem;
cursor: pointer;
}
.toast_icon {
color: $white;
float: left;
margin-right: 2rem;
font-size: 3rem;
}
JavaScript
function validate_form(){
var validate_form = $('body').find('.validate_form');
validate_form.each(function () {
var $this = $(this),
$validate = $this.find('.validate'),
$validateEmail = $this.find('.validate_email'),
$validateTel = $this.find('.validate_tel'),
$validatePass = $this.find('.validate_pass'),
$validatePassConfirm = $this.find('.validate_pass_confirm'),
$validateCap = $this.find('.validate_cap'),
$validateSelect = $this.find('.validate_select'),
$validateRadio = $this.find('.validate_radio'),
$validateCheckbox = $this.find('.validate_checkbox'),
checkEmail = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/,
checkTel = /[0-9 -()+]+$/,
$FCN = $('header').data('id');
$this.on('submit', function () {
$this.find('button').attr('disabled',true);
setTimeout(function(){
$this.find('button').attr('disabled',false);
},1000);
var error = '',
passValue = $validatePass.val(),
passConfirmValue = $validatePassConfirm.val();
$validate.each(function () {
var value = $(this).val();
checking(value.length === 0, $(this));
});
$validateEmail.each(function () {
var value = $(this).val();
checking(checkEmail.test(value) === false, $(this));
});
$validateTel.each(function () {
var value = $(this).val();
checking(value.length < 7 || (!checkTel.test(value)), $(this));
});
$validatePass.each(function () {
checking(passValue === '' || passValue.length <= 6, $(this));
});
$validatePassConfirm.each(function () {
checking(passValue != passConfirmValue || passValue === '', $(this));
});
$validateCap.each(function () {
var value = $(this).val();
checking(value != $FCN, $(this));
});
$validateSelect.each(function () {
var value = $(this).find('option:selected').val();
checking(value == '', $(this));
});
$validateRadio.each(function (e) {
var value = 0,
$thisRadioWrapper = $(this);
$thisRadioWrapper.find('input').each(function (e) {
if ($(this).is(':checked')) {
value++;
}
});
checking(value == 0, $thisRadioWrapper);
});
$validateCheckbox.each(function () {
var value = 0,
$thisCheckboxWrapper = $(this);
$thisCheckboxWrapper.find('input').each(function (e) {
if ($(this).is(':checked')) {
value++;
}
});
checking(value == 0, $thisCheckboxWrapper);
});
function checking(check, $this) {
if (check) {
error++;
$this.addClass('validate_error');
} else {
$this.removeClass('validate_error');
}
}
if (error) {
toast('error', 'Incorrect values');
return false;
}
});
});
}
validate_form();
// toasts
function toast(cssClass, toastText) {
var $this = $('#toast'),
tl = new TimelineMax();
$this.attr('class', false);
$this.addClass(cssClass);
$this.find('#toast_text').html(toastText);
if (!$this.hasClass('active')) {
tl.fromTo($this, 0.3, {display: 'none', y: '100%', autoAlpha: 0}, {
display: 'block',
y: '0%',
autoAlpha: 1,
ease: Back.easeOut
}).to($this, 0.3, {
display: 'none',
y: '100%',
autoAlpha: 0,
ease: Back.easeIn,
delay: 3,
onComplete: function () {
$this.removeClass('active');
}
});
}
$this.addClass('active');
}
Captcha validation
PHP
<!-- init.php -->
if (!isset($_SESSION['finalCaptchaNumber'])) $_SESSION['finalCaptchaNumber'] = rand(10,20);
$firstCaptchaNumber = rand(1,$_SESSION['finalCaptchaNumber']-1);
$secondCaptchaNumber = $_SESSION['finalCaptchaNumber'] - $firstCaptchaNumber;
<!-- header.php -->
<header class="header" data-id="<?= $_SESSION['finalCaptchaNumber']?>"></header>
<!-- contact_form.php -->
...
<label>
<span>Please Answer</span>
<input name="a" type="text" placeholder="<?= $firstCaptchaNumber ?>+<?= $secondCaptchaNumber ?>=" class="input || validate_cap">
</label>
...
JavaScript
function validate_form(){
var $this = $(this),
$validateCap = $this.find('.validate_cap');
$this.on('submit', function () {
var $FCN = $('header').data('id');
$validateCap.each(function () {
var value = $(this).val();
checking(value != $FCN, $(this));
});
}
}
Validation for AJAX
Приймає: елемент* по якому клікнули та не обов'язковий аргумент клас в якому буде шукати, по дефолту ".form"
Повертає: результат = 0 - SUCCESS, результат > 0 - ERROR
JavaScript
function validate_ajax($this,$form='form') {
var validate_form = $this.closest('.'+$form);
var validation_result = 0;
validate_form.each(function () {
var $this = $(this),
$validate = $this.find('.validate:visible'),
$validateEmail = $this.find('.validate_email'),
$validateTel = $this.find('.validate_tel'),
$validatePass = $this.find('.validate_pass:visible'),
$validatePassConfirm = $this.find('.validate_pass_confirm:visible'),
$validateCap = $this.find('.validate_cap'),
$validateSelect = $this.find('.validate_select'),
$validateRadio = $this.find('.validate_radio'),
$validateCheckbox = $this.find('.validate_checkbox'),
checkEmail = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/,
checkTel = /[0-9 -()+]+$/,
$FCN = $('header').data('id');
$('body').find('.button_send').attr('disabled', true);
setTimeout(function () {
$('body').find('.button_send').attr('disabled', false);
}, 5000);
var error = '',
passValue = $validatePass.val(),
passConfirmValue = $validatePassConfirm.val();
$validate.each(function () {
if (!$validate.hasClass('hide_input')) {
var value = $(this).val();
checking(value.length === 0, $(this));
}
});
$validateEmail.each(function () {
var value = $(this).val();
checking(checkEmail.test(value) === false, $(this));
});
$validateTel.each(function () {
var value = $(this).val();
checking(value.length < 7 || (!checkTel.test(value)), $(this));
});
var password_field1 = $validatePass.closest('.password_field');
var password_field2 = $validatePassConfirm.closest('.password_field');
if (password_field1.length > 0) {
if (password_field1.hasClass('active')) {
$validatePass.each(function () {
checking(passValue === '' || passValue.length <= 3, $(this));
});
}
} else {
$validatePass.each(function () {
checking(passValue === '' || passValue.length <= 3, $(this));
});
}
if (password_field1.length > 0) {
if ($validatePassConfirm.closest('.password_field').hasClass('active')) {
$validatePassConfirm.each(function () {
checking(passValue != passConfirmValue || passValue === '', $(this));
});
}
} else {
$validatePassConfirm.each(function () {
checking(passValue != passConfirmValue || passValue === '', $(this));
});
}
$validateCap.each(function () {
var value = $(this).val();
checking(value != $FCN, $(this));
});
$validateSelect.each(function () {
var value = $(this).find('option:selected').val();
checking(value == '', $(this));
});
$validateRadio.each(function (e) {
var value = 0,
$thisRadioWrapper = $(this);
$thisRadioWrapper.find('input').each(function (e) {
if ($(this).is(':checked')) {
value++;
}
});
checking(value == 0, $thisRadioWrapper);
});
$validateCheckbox.each(function () {
var value = 0,
$thisCheckboxWrapper = $(this);
$thisCheckboxWrapper.find('input').each(function (e) {
if ($(this).is(':checked')) {
value++;
}
});
checking(value == 0, $thisCheckboxWrapper);
});
function checking(check, $this) {
if (check) {
error++;
$this.addClass('validate_error');
} else {
$this.removeClass('validate_error');
}
}
if (error) {
toast("error", "Incorrect values");
validation_result++;
}
});
return validation_result;
}
// Function call example
$('body').on('click', '.button_send', function (e) {
e.preventDefault();
var $this = $(this);
validate_ajax($this);
});
$('body').on('click', '[data-nav="next"]', function (e) {
e.preventDefault();
var valid = validate_ajax($(this), 'step_block');
if (valid === 0) {
console.log('Step valid!')
}
});