HTML5/CSS live Validation w/jQuery












4














I've been working on a live form validation project, initially I intended on finding a way to solely use CSS for said validation but it quickly became apparent I would require some jQuery to get it to function properly. That said, I'd like another set of eyes on my jQuery to see if anyone has improvements or tips to streamline it a little better. It seems like there is an awful lot of code repetition but I'm not sure how to best minimize that.



If you'd like to offer improvements for the HTML/CSS then by all means have at it but my primary concern is the jQuery below since I haven't polished the styles yet.



Disclaimer: *This is a work in progress, so there are no fallbacks/polyfills for older browsers at this time.






var timer = 0,
input = $('input').not('[type=radio]'),
radio = $('input[type=radio]'),
select = $('select'),
notRequired = input.not('[required]'),
form = $('form');

function supportsHtml5Validation() {
return typeof document.createElement('input').checkValidity === 'function';
}

function windowSize() {
windowHeight = window.innerHeight ? window.innerHeight : $(window).height();
windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
AddValidationClasses();
}
windowSize();
$(window).resize(function () {
windowSize();
});

function isValid(input) {
$(input).addClass('valid').removeClass('invalid');
}

function inValid(input) {
$(input).addClass('invalid').removeClass('valid');
}

function isEmpty(input) {
if (!$.trim($(input).val())) {
$(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');
}
}

function delay(callback, ms) {
timer = setTimeout(callback, ms);
}

function AddValidationClasses(){
$('.group').each(function () {
if (windowWidth >= 800 && input.not(':checked')) {
$(this).addClass('invalid-radio');
radio.on('change', function(){
$(this).closest('.group').removeClass('invalid-radio');
});
} else if (windowWidth < 800 && input.not(':checked')) {
$(this).parent().removeClass('invalid-radio');
$(this).closest('.field').addClass('invalid-radio');
radio.on('change', function(){
$(this).closest('.field').removeClass('invalid-radio');
});
}
});
}

$(document).ready(function () {

if (!supportsHtml5Validation()) { return; }

input.on('keyup', function () {
clearTimeout(timer);
if ($.trim($(this).val()) === '') {
isEmpty(this);
return false;
} else if (!this.checkValidity()) {
timer = setTimeout(inValid(this), 300);
//delay(function(){ return inValid(inputToValidate); }, 300);
} else if (this.checkValidity()) {
isValid(this);
}
});

select.on('change', function(){
if (!this.checkValidity()) {
inValid(this);
} else {
isValid(this);
}
});

form.on('submit', function (e) {

input.add(select).each(function () {
if (!this.checkValidity()) {
e.preventDefault();
inValid(this);
} else {
isValid(this);
}
});


/*
.field
label
.input
.group
radio's */

AddValidationClasses();
});

$('button[type=reset]').on('click', function () {
console.log('reset clicked');
$('.group, .field, input, select').each(function () {
isEmpty(this);
});
});

if(notRequired){
notRequired.on('keyup', function(){
if($(this).val().match($(this).attr('pattern'))) {
notRequired.each(function(){
isValid(this);
});
}else{
notRequired.each(function(){
inValid(this);
});
}
});
}
});

@import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600);
@-ms-viewport{width:device-width;zoom:1;max-zoom:150%}

@-o-viewport{width:device-width;zoom:1;max-zoom:150%}

@viewport{width:device-width;zoom:1;max-zoom:150%}

html {
box-sizing: border-box;
font-family: 'Source Sans Pro', sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%
}
body {
margin: 0;
color: #27415a;
background: #e9f4f8;
font-size: 16px;
}
:focus::-webkit-input-placeholder {
color: transparent
}
:focus:-moz-placeholder {
color: transparent
}
:focus::-moz-placeholder {
color: transparent
}
:focus:-ms-input-placeholder {
color: transparent
}
::-webkit-input-placeholder {
color: slategray
}
:-moz-placeholder {
color: slategray
}
::-moz-placeholder {
color: slategray
}
:-ms-input-placeholder {
color: slategray
}
select option:nth-child(1) {
color: slategray!important
}
*,
:before,
:after {
box-sizing: inherit;
}
h1 {
color: #27415a;
font-size: 24px
}
.margin-top {
margin-top: 50px
}
.field {
position: relative;
padding: 5px 10px
}
.error .field{
background-color:}
.field .label,
.field label:not(.radio-label) {
font-weight: 600;
margin-top: 0;
margin-bottom: 5px
}
.inline {
margin-bottom: 15px
}
.group {
text-align: right
}
.group .radio-label,
label{
cursor: pointer
}
input:not([type=radio]),
select {
position: relative;
margin-top: 5px;
margin-bottom: 20px;
padding: 8px;
width: 100%;
display: block;
border: #5bf 1px solid;
box-shadow: inset 0 0 1px #5bf;
border-radius: 2px;
background-color: white;
background-color: rgba(255, 255, 255, .85);
background-image: none;
color: #27415a;

-webkit-transition: color .2s, background-color .2s, border .2s ease;
transition: color .2s, background-color .2s, border .2s ease;
}
input:focus:not([type=radio]),
select:focus {
padding-left: 10px;
outline: 0;
border-left-width: 3px;
box-shadow: inset 0 0 2px white
}
input[required]:valid:focus:not([type=radio]),
select[required]:valid:focus,
input[required]:valid:not([type=radio]),
select[required]:valid,
.valid{
background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
background-position: 98% 50%;
background-size: 28px 28px;
background-repeat: no-repeat;
box-shadow: inset 0 3px 3px -3px white!important;
color: green!important
}
.valid{
border-color: #79bf6d!important;
background-color: white!important;
background-color: rgba(207, 254, 168, 0.2)!important;}
.invalid {
border-color: #f7a716!important;
background-color: white;
background-color: rgba(255, 213, 0, 0.13)!important;
background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
background-position: 98% 50%;
background-size: 28px 28px;
background-repeat: no-repeat;
box-shadow: inset 0 3px 3px -3px white;
color: #b63910!important
}

.invalid-radio {
border: 1px solid #f7a716;
margin: 0 10px 15px 10px;
background-color: white;
background-color: rgba(255, 213, 0, 0.13)!important;
box-shadow: inset 0 3px 3px -3px white;
color: #b63910!important
}
.invalid::-webkit-input-placeholder {
color: #b63910!important
}
.invalid:-moz-placeholder {
color: #b63910!important
}
.invalid::-moz-placeholder {
color: #b63910!important
}
.invalid:-ms-input-placeholder {
color: #b63910!important
}
select: {
outline: 0
}
select:not(:checked) {
padding-left: 5px;
}
input:-webkit-autofill:not([type=radio]) {
-webkit-box-shadow: 0 0 0 1000px #e9f4f8 inset
}
textarea,
select[size],
select[multiple] {
height: auto
}
select[size="0"],
select[size="1"] {
height: 1.8em;
*height: auto
}
button,
.button {
margin:10px 0 25px 10px;
padding: 12px 25px;
float: right;
border-radius: 3px;
background-color: #79bf6d;
border:1px solid #70AB66;
color: white;
box-shadow:inset 0 1px 1px -1px white;
}
button[disabled]{
background-color:#ddd;
color:slategray;
text-shadow:1px 0 0 white;
border:1px solid #ccc}
input[type=checkbox]:not(old),
input[type=radio]:not(old) {
margin: 0;
padding: 0;
opacity: 0
}
input[type=checkbox]:not(old)+label,
input[type=radio]:not(old)+label {
display: inline-block;
margin-left: 0;
padding-left: 36px;
background: url('http://leftdeaf.com/ppi/quote/new/img/disc.png') no-repeat 0 3px;
background-size: 28px 28px;
line-height: 36px;
text-transform: uppercase;
font-weight: 600
}
input[type=checkbox]:not(old):checked+label,
input[type=radio]:not(old):checked+label {
background: url('http://leftdeaf.com/ppi/quote/new/img/valid.png') no-repeat 0 3px;
background-size: 28px 28px
}
input[type=radio]:not(old):active+label {
background-position: -1px 2px;
background-size: 30px
}
select[size],
select[multiple],
select[multiple][size] {
padding-right: 3px;
background-image: none
}
select,
select[size="0"],
select[size="1"] {
padding-right: 20px;
background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-basic.png);
background-position: 98% 50%;
background-size: 24px;
background-repeat: no-repeat;
text-indent: 1px;
text-overflow: '';
cursor: pointer;
-webkit-appearance: none;
-moz-appearance: none
}
select:not(:checked),
select[size="0"]:not(:checked),
select[size="1"]:not(:checked){
color:slategray;
}
select:focus option:nth-child(1),
select[size="0"]:focus option:nth-child(1),
select[size="1"]:focus option:nth-child(1) {
display: none
}

select.invalid:not(:selected) {
background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-invalid.png')
}
select:focus,
select[size="0"]:focus,
select[size="1"]:focus {
background-image: url(http://leftdeaf.com/ppi/quote/new/img/add-basic.png)
}
select:checked:valid,
select[size="0"]:checked:valid,
select[size="1"]:checked:valid {
background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png);
color: #27415a
}
select:focus:valid,
select[size="0"]:required:focus:valid,
select[size="1"]:required:focus:valid {
background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)
}
select:valid:not(:checked),
select[size="0"]:valid:not(:checked),
select[size="1"]:valid:not(:checked) {
background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png)
}
select.valid:valid,
select[size="0"]:required.valid:valid,
select[size="1"]:required.valid:valid {
background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
}
select::-ms-expand {
display: none
}


.inline-always,
.inline-always .group,
.inline-always .label,
.inline-always .input {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-direction: normal;
-webkit-box-orient: horizontal;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-box-pack: end;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end;
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-items: center;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch;
}
.inline-always .input {
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
justify-content: center;
}
.inline-always .group {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
align-items: center;
}
.inline-always .label{
width: 300px;
padding-right: 25px;
}
.inline-always .input {
width: 500px;
}
.inline-always .label
.inline-always .input {
height: 60px!important;
}
.inline-always .label {
text-align: left;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
align-items: center;
justify-content: flex-start;
}
.inline-always input:not([type=radio]),
.inline-always select {
margin-top: 0;
margin-bottom: 0;
}
.inline-always .inline {
margin-bottom: 0
}

@media (min-width: 800px) {
/* flex layout */
form {
width: 100%;
max-width: 800px;
margin: 0 auto
}
.group {
text-align: left
}
.field,
.group,
label:not(.radio-label),
.label,
.input,
.inline-always,
.inline-always .group,
.inline-always .label,
.inline-always .input{
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-direction: normal;
-webkit-box-orient: horizontal;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-items: center;
-webkit-box-align: stretch;
-webkit-align-items: stretch;
-ms-flex-align: stretch;
align-items: stretch;
}
.input,
.inline-always input{
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
justify-content: center;
}
.inline-always .group,
.group {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
align-items: center;
}
.label,
.inline-always .label,
label:not(.radio-label) {
width: 300px;
padding-right: 25px;
}
.input {
width: 500px;
}
.label,
.inline-always .label,
label:not(.radio-label),
.input,
.inline-always .input{
height: 60px!important;
}
label:not(.radio-label),
.inline-always .label,
.label {
text-align: right;
-webkit-box-pack: end;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
align-items: center;
justify-content: flex-end;
}
input:not([type=radio]),
select {
margin-top: 0;
margin-bottom: 0;
}
.inline {
margin-bottom: 0
}

.invalid,.invalid-radio {
border-color: #f7a716!important;
background-color: white;
background-color: rgba(255, 213, 0, 0.13)!important;
background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
background-position: 98% 50%;
background-size: 28px 28px;
background-repeat: no-repeat;
box-shadow: inset 0 3px 3px -3px white;
color: #b63910!important
}

.invalid-radio {
margin:0;
}
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="step-one" method="get" novalidate autocomplete="off">

<h1>Step 1 &mdash; Information</h1>
<p>Fill in all that apply.</p>

<div class="field">
<label for="pet-name">Pet name</label>
<div class="input">
<input required id="pet-name" value type="text" placeholder="e.g. Milo" pattern="^[a-zA-Z0-9_ ]*$" tabindex="1" accesskey="p">
</div>
</div>

<div class="field">
<label for="zipcode">Zipcode</label>
<div class="input">
<input required aria-required="required" value type="text" placeholder="e.g. 12345 or 12345-9876" id="zipcode" pattern="(d{5}([-]d{4})?)" tabindex="2" accesskey="z">
</div>
</div>

<div class="field inline inline-always">
<p class="label">Select a pet type</p>
<div class="input">
<div class="group">
<input type="radio" id="dog" name="type" tabindex="3" required aria-required="required" accesskey="a">
<label for="dog" class="radio-label">Dog</label>
<input type="radio" id="cat" name="type">
<label for="cat" class="radio-label">Cat</label>
</div>
</div>
</div>

<div class="field">
<label for="breed">Select breed</label>
<div class="input">
<select id="breed" class="select" required aria-required="required" tabindex="4" accesskey="b">
<option value disabled>Breeds List</option>
<optgroup label="Common Breeds">
<option value="5">Mixed Breed</option>
<option value="27">Bearded Collie</option>
<option value="28">Beauceron</option>
<option value="224">Bedlington Terrier</option>
</optgroup>
<optgroup label="All Breeds">
<option value="6">Affenpinscher</option>
<option value="7">Afghan Hound</option>
</optgroup>
</select>
</div>
</div>

<div class="field">
<label for="age">Select age</label>
<div class="input">
<select id="age" class="select" required aria-required="required" tabindex="5" accesskey="y">
<option value disabled>Years of age</option>
<option value="1">Under 1</option>
<option value="2">1</option>
<option value="3">2</option>
<option value="4">3</option>
<option value="5">4</option>
<option value="6">5</option>
<option value="7">6</option>
<option value="7">7</option>
<option value="9">8</option>
<option value="10">9</option>
<option value="11">10</option>
<option value="12">11</option>
<option value="13">12</option>
<option value="14">13</option>
<option value="15">14</option>
<option value="16">15</option>
<option value="17">16</option>
<option value="17">17</option>
<option value="19">18</option>
<option value="20">19</option>
<option value="21">20</option>
<option value="22">21</option>
<option value="23">22</option>
<option value="24">23</option>
<option value="25">24</option>
<option value="26">25</option>
<option value="27">26</option>
<option value="27">27</option>
<option value="29">28</option>
<option value="30">29</option>
<option value="31">30</option>
</select>
</div>
</div>

<div class="field inline">
<p class="label">Has your pet ever been diagnosed with or shown symptoms of Diabetes, Cushing’s Disease, or FeLV/FIV?</p>
<div class="input">
<div class="group">
<input type="radio" id="yes" name="q" tabindex="6" required aria-required="required" accesskey="h">
<label for="yes" class="radio-label">Yes</label>
<input type="radio" id="no" name="q">
<label for="no" class="radio-label">No</label>
</div>
</div>
</div>

<div class="field">
<label for="email">Email address</label>
<div class="input">
<input id="email" value type="text" placeholder="e.g. name@address.co" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$" tabindex="7" accesskey="e">
</div>
</div>

<button type="submit" tabindex="8" accesskey="n">Next</button>
<button type="reset" tabindex="0" accesskey="r">Reset</button>

</form>












share|improve this question





























    4














    I've been working on a live form validation project, initially I intended on finding a way to solely use CSS for said validation but it quickly became apparent I would require some jQuery to get it to function properly. That said, I'd like another set of eyes on my jQuery to see if anyone has improvements or tips to streamline it a little better. It seems like there is an awful lot of code repetition but I'm not sure how to best minimize that.



    If you'd like to offer improvements for the HTML/CSS then by all means have at it but my primary concern is the jQuery below since I haven't polished the styles yet.



    Disclaimer: *This is a work in progress, so there are no fallbacks/polyfills for older browsers at this time.






    var timer = 0,
    input = $('input').not('[type=radio]'),
    radio = $('input[type=radio]'),
    select = $('select'),
    notRequired = input.not('[required]'),
    form = $('form');

    function supportsHtml5Validation() {
    return typeof document.createElement('input').checkValidity === 'function';
    }

    function windowSize() {
    windowHeight = window.innerHeight ? window.innerHeight : $(window).height();
    windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
    AddValidationClasses();
    }
    windowSize();
    $(window).resize(function () {
    windowSize();
    });

    function isValid(input) {
    $(input).addClass('valid').removeClass('invalid');
    }

    function inValid(input) {
    $(input).addClass('invalid').removeClass('valid');
    }

    function isEmpty(input) {
    if (!$.trim($(input).val())) {
    $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');
    }
    }

    function delay(callback, ms) {
    timer = setTimeout(callback, ms);
    }

    function AddValidationClasses(){
    $('.group').each(function () {
    if (windowWidth >= 800 && input.not(':checked')) {
    $(this).addClass('invalid-radio');
    radio.on('change', function(){
    $(this).closest('.group').removeClass('invalid-radio');
    });
    } else if (windowWidth < 800 && input.not(':checked')) {
    $(this).parent().removeClass('invalid-radio');
    $(this).closest('.field').addClass('invalid-radio');
    radio.on('change', function(){
    $(this).closest('.field').removeClass('invalid-radio');
    });
    }
    });
    }

    $(document).ready(function () {

    if (!supportsHtml5Validation()) { return; }

    input.on('keyup', function () {
    clearTimeout(timer);
    if ($.trim($(this).val()) === '') {
    isEmpty(this);
    return false;
    } else if (!this.checkValidity()) {
    timer = setTimeout(inValid(this), 300);
    //delay(function(){ return inValid(inputToValidate); }, 300);
    } else if (this.checkValidity()) {
    isValid(this);
    }
    });

    select.on('change', function(){
    if (!this.checkValidity()) {
    inValid(this);
    } else {
    isValid(this);
    }
    });

    form.on('submit', function (e) {

    input.add(select).each(function () {
    if (!this.checkValidity()) {
    e.preventDefault();
    inValid(this);
    } else {
    isValid(this);
    }
    });


    /*
    .field
    label
    .input
    .group
    radio's */

    AddValidationClasses();
    });

    $('button[type=reset]').on('click', function () {
    console.log('reset clicked');
    $('.group, .field, input, select').each(function () {
    isEmpty(this);
    });
    });

    if(notRequired){
    notRequired.on('keyup', function(){
    if($(this).val().match($(this).attr('pattern'))) {
    notRequired.each(function(){
    isValid(this);
    });
    }else{
    notRequired.each(function(){
    inValid(this);
    });
    }
    });
    }
    });

    @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600);
    @-ms-viewport{width:device-width;zoom:1;max-zoom:150%}

    @-o-viewport{width:device-width;zoom:1;max-zoom:150%}

    @viewport{width:device-width;zoom:1;max-zoom:150%}

    html {
    box-sizing: border-box;
    font-family: 'Source Sans Pro', sans-serif;
    -ms-text-size-adjust: 100%;
    -webkit-text-size-adjust: 100%
    }
    body {
    margin: 0;
    color: #27415a;
    background: #e9f4f8;
    font-size: 16px;
    }
    :focus::-webkit-input-placeholder {
    color: transparent
    }
    :focus:-moz-placeholder {
    color: transparent
    }
    :focus::-moz-placeholder {
    color: transparent
    }
    :focus:-ms-input-placeholder {
    color: transparent
    }
    ::-webkit-input-placeholder {
    color: slategray
    }
    :-moz-placeholder {
    color: slategray
    }
    ::-moz-placeholder {
    color: slategray
    }
    :-ms-input-placeholder {
    color: slategray
    }
    select option:nth-child(1) {
    color: slategray!important
    }
    *,
    :before,
    :after {
    box-sizing: inherit;
    }
    h1 {
    color: #27415a;
    font-size: 24px
    }
    .margin-top {
    margin-top: 50px
    }
    .field {
    position: relative;
    padding: 5px 10px
    }
    .error .field{
    background-color:}
    .field .label,
    .field label:not(.radio-label) {
    font-weight: 600;
    margin-top: 0;
    margin-bottom: 5px
    }
    .inline {
    margin-bottom: 15px
    }
    .group {
    text-align: right
    }
    .group .radio-label,
    label{
    cursor: pointer
    }
    input:not([type=radio]),
    select {
    position: relative;
    margin-top: 5px;
    margin-bottom: 20px;
    padding: 8px;
    width: 100%;
    display: block;
    border: #5bf 1px solid;
    box-shadow: inset 0 0 1px #5bf;
    border-radius: 2px;
    background-color: white;
    background-color: rgba(255, 255, 255, .85);
    background-image: none;
    color: #27415a;

    -webkit-transition: color .2s, background-color .2s, border .2s ease;
    transition: color .2s, background-color .2s, border .2s ease;
    }
    input:focus:not([type=radio]),
    select:focus {
    padding-left: 10px;
    outline: 0;
    border-left-width: 3px;
    box-shadow: inset 0 0 2px white
    }
    input[required]:valid:focus:not([type=radio]),
    select[required]:valid:focus,
    input[required]:valid:not([type=radio]),
    select[required]:valid,
    .valid{
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
    background-position: 98% 50%;
    background-size: 28px 28px;
    background-repeat: no-repeat;
    box-shadow: inset 0 3px 3px -3px white!important;
    color: green!important
    }
    .valid{
    border-color: #79bf6d!important;
    background-color: white!important;
    background-color: rgba(207, 254, 168, 0.2)!important;}
    .invalid {
    border-color: #f7a716!important;
    background-color: white;
    background-color: rgba(255, 213, 0, 0.13)!important;
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
    background-position: 98% 50%;
    background-size: 28px 28px;
    background-repeat: no-repeat;
    box-shadow: inset 0 3px 3px -3px white;
    color: #b63910!important
    }

    .invalid-radio {
    border: 1px solid #f7a716;
    margin: 0 10px 15px 10px;
    background-color: white;
    background-color: rgba(255, 213, 0, 0.13)!important;
    box-shadow: inset 0 3px 3px -3px white;
    color: #b63910!important
    }
    .invalid::-webkit-input-placeholder {
    color: #b63910!important
    }
    .invalid:-moz-placeholder {
    color: #b63910!important
    }
    .invalid::-moz-placeholder {
    color: #b63910!important
    }
    .invalid:-ms-input-placeholder {
    color: #b63910!important
    }
    select: {
    outline: 0
    }
    select:not(:checked) {
    padding-left: 5px;
    }
    input:-webkit-autofill:not([type=radio]) {
    -webkit-box-shadow: 0 0 0 1000px #e9f4f8 inset
    }
    textarea,
    select[size],
    select[multiple] {
    height: auto
    }
    select[size="0"],
    select[size="1"] {
    height: 1.8em;
    *height: auto
    }
    button,
    .button {
    margin:10px 0 25px 10px;
    padding: 12px 25px;
    float: right;
    border-radius: 3px;
    background-color: #79bf6d;
    border:1px solid #70AB66;
    color: white;
    box-shadow:inset 0 1px 1px -1px white;
    }
    button[disabled]{
    background-color:#ddd;
    color:slategray;
    text-shadow:1px 0 0 white;
    border:1px solid #ccc}
    input[type=checkbox]:not(old),
    input[type=radio]:not(old) {
    margin: 0;
    padding: 0;
    opacity: 0
    }
    input[type=checkbox]:not(old)+label,
    input[type=radio]:not(old)+label {
    display: inline-block;
    margin-left: 0;
    padding-left: 36px;
    background: url('http://leftdeaf.com/ppi/quote/new/img/disc.png') no-repeat 0 3px;
    background-size: 28px 28px;
    line-height: 36px;
    text-transform: uppercase;
    font-weight: 600
    }
    input[type=checkbox]:not(old):checked+label,
    input[type=radio]:not(old):checked+label {
    background: url('http://leftdeaf.com/ppi/quote/new/img/valid.png') no-repeat 0 3px;
    background-size: 28px 28px
    }
    input[type=radio]:not(old):active+label {
    background-position: -1px 2px;
    background-size: 30px
    }
    select[size],
    select[multiple],
    select[multiple][size] {
    padding-right: 3px;
    background-image: none
    }
    select,
    select[size="0"],
    select[size="1"] {
    padding-right: 20px;
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-basic.png);
    background-position: 98% 50%;
    background-size: 24px;
    background-repeat: no-repeat;
    text-indent: 1px;
    text-overflow: '';
    cursor: pointer;
    -webkit-appearance: none;
    -moz-appearance: none
    }
    select:not(:checked),
    select[size="0"]:not(:checked),
    select[size="1"]:not(:checked){
    color:slategray;
    }
    select:focus option:nth-child(1),
    select[size="0"]:focus option:nth-child(1),
    select[size="1"]:focus option:nth-child(1) {
    display: none
    }

    select.invalid:not(:selected) {
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-invalid.png')
    }
    select:focus,
    select[size="0"]:focus,
    select[size="1"]:focus {
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/add-basic.png)
    }
    select:checked:valid,
    select[size="0"]:checked:valid,
    select[size="1"]:checked:valid {
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png);
    color: #27415a
    }
    select:focus:valid,
    select[size="0"]:required:focus:valid,
    select[size="1"]:required:focus:valid {
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)
    }
    select:valid:not(:checked),
    select[size="0"]:valid:not(:checked),
    select[size="1"]:valid:not(:checked) {
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png)
    }
    select.valid:valid,
    select[size="0"]:required.valid:valid,
    select[size="1"]:required.valid:valid {
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
    }
    select::-ms-expand {
    display: none
    }


    .inline-always,
    .inline-always .group,
    .inline-always .label,
    .inline-always .input {
    display: -webkit-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-box-direction: normal;
    -webkit-box-orient: horizontal;
    -webkit-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
    -webkit-flex-wrap: nowrap;
    -ms-flex-wrap: nowrap;
    flex-wrap: nowrap;
    -webkit-box-pack: end;
    -webkit-justify-content: flex-end;
    -ms-flex-pack: end;
    justify-content: flex-end;
    -webkit-align-content: stretch;
    -ms-flex-line-pack: stretch;
    align-items: center;
    -webkit-box-align: stretch;
    -webkit-align-items: stretch;
    -ms-flex-align: stretch;
    align-items: stretch;
    }
    .inline-always .input {
    -webkit-box-orient: vertical;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    justify-content: center;
    }
    .inline-always .group {
    -webkit-box-flex: 1;
    -webkit-flex: 1;
    -ms-flex: 1;
    flex: 1;
    align-items: center;
    }
    .inline-always .label{
    width: 300px;
    padding-right: 25px;
    }
    .inline-always .input {
    width: 500px;
    }
    .inline-always .label
    .inline-always .input {
    height: 60px!important;
    }
    .inline-always .label {
    text-align: left;
    -webkit-box-pack: start;
    -webkit-justify-content: flex-start;
    -ms-flex-pack: start;
    align-items: center;
    justify-content: flex-start;
    }
    .inline-always input:not([type=radio]),
    .inline-always select {
    margin-top: 0;
    margin-bottom: 0;
    }
    .inline-always .inline {
    margin-bottom: 0
    }

    @media (min-width: 800px) {
    /* flex layout */
    form {
    width: 100%;
    max-width: 800px;
    margin: 0 auto
    }
    .group {
    text-align: left
    }
    .field,
    .group,
    label:not(.radio-label),
    .label,
    .input,
    .inline-always,
    .inline-always .group,
    .inline-always .label,
    .inline-always .input{
    display: -webkit-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    -webkit-box-direction: normal;
    -webkit-box-orient: horizontal;
    -webkit-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
    -webkit-flex-wrap: nowrap;
    -ms-flex-wrap: nowrap;
    flex-wrap: nowrap;
    -webkit-box-pack: start;
    -webkit-justify-content: flex-start;
    -ms-flex-pack: start;
    justify-content: flex-start;
    -webkit-align-content: stretch;
    -ms-flex-line-pack: stretch;
    align-items: center;
    -webkit-box-align: stretch;
    -webkit-align-items: stretch;
    -ms-flex-align: stretch;
    align-items: stretch;
    }
    .input,
    .inline-always input{
    -webkit-box-orient: vertical;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    justify-content: center;
    }
    .inline-always .group,
    .group {
    -webkit-box-flex: 1;
    -webkit-flex: 1;
    -ms-flex: 1;
    flex: 1;
    align-items: center;
    }
    .label,
    .inline-always .label,
    label:not(.radio-label) {
    width: 300px;
    padding-right: 25px;
    }
    .input {
    width: 500px;
    }
    .label,
    .inline-always .label,
    label:not(.radio-label),
    .input,
    .inline-always .input{
    height: 60px!important;
    }
    label:not(.radio-label),
    .inline-always .label,
    .label {
    text-align: right;
    -webkit-box-pack: end;
    -webkit-justify-content: flex-end;
    -ms-flex-pack: end;
    align-items: center;
    justify-content: flex-end;
    }
    input:not([type=radio]),
    select {
    margin-top: 0;
    margin-bottom: 0;
    }
    .inline {
    margin-bottom: 0
    }

    .invalid,.invalid-radio {
    border-color: #f7a716!important;
    background-color: white;
    background-color: rgba(255, 213, 0, 0.13)!important;
    background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
    background-position: 98% 50%;
    background-size: 28px 28px;
    background-repeat: no-repeat;
    box-shadow: inset 0 3px 3px -3px white;
    color: #b63910!important
    }

    .invalid-radio {
    margin:0;
    }
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <form id="step-one" method="get" novalidate autocomplete="off">

    <h1>Step 1 &mdash; Information</h1>
    <p>Fill in all that apply.</p>

    <div class="field">
    <label for="pet-name">Pet name</label>
    <div class="input">
    <input required id="pet-name" value type="text" placeholder="e.g. Milo" pattern="^[a-zA-Z0-9_ ]*$" tabindex="1" accesskey="p">
    </div>
    </div>

    <div class="field">
    <label for="zipcode">Zipcode</label>
    <div class="input">
    <input required aria-required="required" value type="text" placeholder="e.g. 12345 or 12345-9876" id="zipcode" pattern="(d{5}([-]d{4})?)" tabindex="2" accesskey="z">
    </div>
    </div>

    <div class="field inline inline-always">
    <p class="label">Select a pet type</p>
    <div class="input">
    <div class="group">
    <input type="radio" id="dog" name="type" tabindex="3" required aria-required="required" accesskey="a">
    <label for="dog" class="radio-label">Dog</label>
    <input type="radio" id="cat" name="type">
    <label for="cat" class="radio-label">Cat</label>
    </div>
    </div>
    </div>

    <div class="field">
    <label for="breed">Select breed</label>
    <div class="input">
    <select id="breed" class="select" required aria-required="required" tabindex="4" accesskey="b">
    <option value disabled>Breeds List</option>
    <optgroup label="Common Breeds">
    <option value="5">Mixed Breed</option>
    <option value="27">Bearded Collie</option>
    <option value="28">Beauceron</option>
    <option value="224">Bedlington Terrier</option>
    </optgroup>
    <optgroup label="All Breeds">
    <option value="6">Affenpinscher</option>
    <option value="7">Afghan Hound</option>
    </optgroup>
    </select>
    </div>
    </div>

    <div class="field">
    <label for="age">Select age</label>
    <div class="input">
    <select id="age" class="select" required aria-required="required" tabindex="5" accesskey="y">
    <option value disabled>Years of age</option>
    <option value="1">Under 1</option>
    <option value="2">1</option>
    <option value="3">2</option>
    <option value="4">3</option>
    <option value="5">4</option>
    <option value="6">5</option>
    <option value="7">6</option>
    <option value="7">7</option>
    <option value="9">8</option>
    <option value="10">9</option>
    <option value="11">10</option>
    <option value="12">11</option>
    <option value="13">12</option>
    <option value="14">13</option>
    <option value="15">14</option>
    <option value="16">15</option>
    <option value="17">16</option>
    <option value="17">17</option>
    <option value="19">18</option>
    <option value="20">19</option>
    <option value="21">20</option>
    <option value="22">21</option>
    <option value="23">22</option>
    <option value="24">23</option>
    <option value="25">24</option>
    <option value="26">25</option>
    <option value="27">26</option>
    <option value="27">27</option>
    <option value="29">28</option>
    <option value="30">29</option>
    <option value="31">30</option>
    </select>
    </div>
    </div>

    <div class="field inline">
    <p class="label">Has your pet ever been diagnosed with or shown symptoms of Diabetes, Cushing’s Disease, or FeLV/FIV?</p>
    <div class="input">
    <div class="group">
    <input type="radio" id="yes" name="q" tabindex="6" required aria-required="required" accesskey="h">
    <label for="yes" class="radio-label">Yes</label>
    <input type="radio" id="no" name="q">
    <label for="no" class="radio-label">No</label>
    </div>
    </div>
    </div>

    <div class="field">
    <label for="email">Email address</label>
    <div class="input">
    <input id="email" value type="text" placeholder="e.g. name@address.co" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$" tabindex="7" accesskey="e">
    </div>
    </div>

    <button type="submit" tabindex="8" accesskey="n">Next</button>
    <button type="reset" tabindex="0" accesskey="r">Reset</button>

    </form>












    share|improve this question



























      4












      4








      4







      I've been working on a live form validation project, initially I intended on finding a way to solely use CSS for said validation but it quickly became apparent I would require some jQuery to get it to function properly. That said, I'd like another set of eyes on my jQuery to see if anyone has improvements or tips to streamline it a little better. It seems like there is an awful lot of code repetition but I'm not sure how to best minimize that.



      If you'd like to offer improvements for the HTML/CSS then by all means have at it but my primary concern is the jQuery below since I haven't polished the styles yet.



      Disclaimer: *This is a work in progress, so there are no fallbacks/polyfills for older browsers at this time.






      var timer = 0,
      input = $('input').not('[type=radio]'),
      radio = $('input[type=radio]'),
      select = $('select'),
      notRequired = input.not('[required]'),
      form = $('form');

      function supportsHtml5Validation() {
      return typeof document.createElement('input').checkValidity === 'function';
      }

      function windowSize() {
      windowHeight = window.innerHeight ? window.innerHeight : $(window).height();
      windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
      AddValidationClasses();
      }
      windowSize();
      $(window).resize(function () {
      windowSize();
      });

      function isValid(input) {
      $(input).addClass('valid').removeClass('invalid');
      }

      function inValid(input) {
      $(input).addClass('invalid').removeClass('valid');
      }

      function isEmpty(input) {
      if (!$.trim($(input).val())) {
      $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');
      }
      }

      function delay(callback, ms) {
      timer = setTimeout(callback, ms);
      }

      function AddValidationClasses(){
      $('.group').each(function () {
      if (windowWidth >= 800 && input.not(':checked')) {
      $(this).addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.group').removeClass('invalid-radio');
      });
      } else if (windowWidth < 800 && input.not(':checked')) {
      $(this).parent().removeClass('invalid-radio');
      $(this).closest('.field').addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.field').removeClass('invalid-radio');
      });
      }
      });
      }

      $(document).ready(function () {

      if (!supportsHtml5Validation()) { return; }

      input.on('keyup', function () {
      clearTimeout(timer);
      if ($.trim($(this).val()) === '') {
      isEmpty(this);
      return false;
      } else if (!this.checkValidity()) {
      timer = setTimeout(inValid(this), 300);
      //delay(function(){ return inValid(inputToValidate); }, 300);
      } else if (this.checkValidity()) {
      isValid(this);
      }
      });

      select.on('change', function(){
      if (!this.checkValidity()) {
      inValid(this);
      } else {
      isValid(this);
      }
      });

      form.on('submit', function (e) {

      input.add(select).each(function () {
      if (!this.checkValidity()) {
      e.preventDefault();
      inValid(this);
      } else {
      isValid(this);
      }
      });


      /*
      .field
      label
      .input
      .group
      radio's */

      AddValidationClasses();
      });

      $('button[type=reset]').on('click', function () {
      console.log('reset clicked');
      $('.group, .field, input, select').each(function () {
      isEmpty(this);
      });
      });

      if(notRequired){
      notRequired.on('keyup', function(){
      if($(this).val().match($(this).attr('pattern'))) {
      notRequired.each(function(){
      isValid(this);
      });
      }else{
      notRequired.each(function(){
      inValid(this);
      });
      }
      });
      }
      });

      @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600);
      @-ms-viewport{width:device-width;zoom:1;max-zoom:150%}

      @-o-viewport{width:device-width;zoom:1;max-zoom:150%}

      @viewport{width:device-width;zoom:1;max-zoom:150%}

      html {
      box-sizing: border-box;
      font-family: 'Source Sans Pro', sans-serif;
      -ms-text-size-adjust: 100%;
      -webkit-text-size-adjust: 100%
      }
      body {
      margin: 0;
      color: #27415a;
      background: #e9f4f8;
      font-size: 16px;
      }
      :focus::-webkit-input-placeholder {
      color: transparent
      }
      :focus:-moz-placeholder {
      color: transparent
      }
      :focus::-moz-placeholder {
      color: transparent
      }
      :focus:-ms-input-placeholder {
      color: transparent
      }
      ::-webkit-input-placeholder {
      color: slategray
      }
      :-moz-placeholder {
      color: slategray
      }
      ::-moz-placeholder {
      color: slategray
      }
      :-ms-input-placeholder {
      color: slategray
      }
      select option:nth-child(1) {
      color: slategray!important
      }
      *,
      :before,
      :after {
      box-sizing: inherit;
      }
      h1 {
      color: #27415a;
      font-size: 24px
      }
      .margin-top {
      margin-top: 50px
      }
      .field {
      position: relative;
      padding: 5px 10px
      }
      .error .field{
      background-color:}
      .field .label,
      .field label:not(.radio-label) {
      font-weight: 600;
      margin-top: 0;
      margin-bottom: 5px
      }
      .inline {
      margin-bottom: 15px
      }
      .group {
      text-align: right
      }
      .group .radio-label,
      label{
      cursor: pointer
      }
      input:not([type=radio]),
      select {
      position: relative;
      margin-top: 5px;
      margin-bottom: 20px;
      padding: 8px;
      width: 100%;
      display: block;
      border: #5bf 1px solid;
      box-shadow: inset 0 0 1px #5bf;
      border-radius: 2px;
      background-color: white;
      background-color: rgba(255, 255, 255, .85);
      background-image: none;
      color: #27415a;

      -webkit-transition: color .2s, background-color .2s, border .2s ease;
      transition: color .2s, background-color .2s, border .2s ease;
      }
      input:focus:not([type=radio]),
      select:focus {
      padding-left: 10px;
      outline: 0;
      border-left-width: 3px;
      box-shadow: inset 0 0 2px white
      }
      input[required]:valid:focus:not([type=radio]),
      select[required]:valid:focus,
      input[required]:valid:not([type=radio]),
      select[required]:valid,
      .valid{
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white!important;
      color: green!important
      }
      .valid{
      border-color: #79bf6d!important;
      background-color: white!important;
      background-color: rgba(207, 254, 168, 0.2)!important;}
      .invalid {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      border: 1px solid #f7a716;
      margin: 0 10px 15px 10px;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }
      .invalid::-webkit-input-placeholder {
      color: #b63910!important
      }
      .invalid:-moz-placeholder {
      color: #b63910!important
      }
      .invalid::-moz-placeholder {
      color: #b63910!important
      }
      .invalid:-ms-input-placeholder {
      color: #b63910!important
      }
      select: {
      outline: 0
      }
      select:not(:checked) {
      padding-left: 5px;
      }
      input:-webkit-autofill:not([type=radio]) {
      -webkit-box-shadow: 0 0 0 1000px #e9f4f8 inset
      }
      textarea,
      select[size],
      select[multiple] {
      height: auto
      }
      select[size="0"],
      select[size="1"] {
      height: 1.8em;
      *height: auto
      }
      button,
      .button {
      margin:10px 0 25px 10px;
      padding: 12px 25px;
      float: right;
      border-radius: 3px;
      background-color: #79bf6d;
      border:1px solid #70AB66;
      color: white;
      box-shadow:inset 0 1px 1px -1px white;
      }
      button[disabled]{
      background-color:#ddd;
      color:slategray;
      text-shadow:1px 0 0 white;
      border:1px solid #ccc}
      input[type=checkbox]:not(old),
      input[type=radio]:not(old) {
      margin: 0;
      padding: 0;
      opacity: 0
      }
      input[type=checkbox]:not(old)+label,
      input[type=radio]:not(old)+label {
      display: inline-block;
      margin-left: 0;
      padding-left: 36px;
      background: url('http://leftdeaf.com/ppi/quote/new/img/disc.png') no-repeat 0 3px;
      background-size: 28px 28px;
      line-height: 36px;
      text-transform: uppercase;
      font-weight: 600
      }
      input[type=checkbox]:not(old):checked+label,
      input[type=radio]:not(old):checked+label {
      background: url('http://leftdeaf.com/ppi/quote/new/img/valid.png') no-repeat 0 3px;
      background-size: 28px 28px
      }
      input[type=radio]:not(old):active+label {
      background-position: -1px 2px;
      background-size: 30px
      }
      select[size],
      select[multiple],
      select[multiple][size] {
      padding-right: 3px;
      background-image: none
      }
      select,
      select[size="0"],
      select[size="1"] {
      padding-right: 20px;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-basic.png);
      background-position: 98% 50%;
      background-size: 24px;
      background-repeat: no-repeat;
      text-indent: 1px;
      text-overflow: '';
      cursor: pointer;
      -webkit-appearance: none;
      -moz-appearance: none
      }
      select:not(:checked),
      select[size="0"]:not(:checked),
      select[size="1"]:not(:checked){
      color:slategray;
      }
      select:focus option:nth-child(1),
      select[size="0"]:focus option:nth-child(1),
      select[size="1"]:focus option:nth-child(1) {
      display: none
      }

      select.invalid:not(:selected) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-invalid.png')
      }
      select:focus,
      select[size="0"]:focus,
      select[size="1"]:focus {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/add-basic.png)
      }
      select:checked:valid,
      select[size="0"]:checked:valid,
      select[size="1"]:checked:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png);
      color: #27415a
      }
      select:focus:valid,
      select[size="0"]:required:focus:valid,
      select[size="1"]:required:focus:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)
      }
      select:valid:not(:checked),
      select[size="0"]:valid:not(:checked),
      select[size="1"]:valid:not(:checked) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png)
      }
      select.valid:valid,
      select[size="0"]:required.valid:valid,
      select[size="1"]:required.valid:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      }
      select::-ms-expand {
      display: none
      }


      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input {
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      justify-content: flex-end;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .inline-always .input {
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .inline-always .label{
      width: 300px;
      padding-right: 25px;
      }
      .inline-always .input {
      width: 500px;
      }
      .inline-always .label
      .inline-always .input {
      height: 60px!important;
      }
      .inline-always .label {
      text-align: left;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      align-items: center;
      justify-content: flex-start;
      }
      .inline-always input:not([type=radio]),
      .inline-always select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline-always .inline {
      margin-bottom: 0
      }

      @media (min-width: 800px) {
      /* flex layout */
      form {
      width: 100%;
      max-width: 800px;
      margin: 0 auto
      }
      .group {
      text-align: left
      }
      .field,
      .group,
      label:not(.radio-label),
      .label,
      .input,
      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input{
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      justify-content: flex-start;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .input,
      .inline-always input{
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group,
      .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label) {
      width: 300px;
      padding-right: 25px;
      }
      .input {
      width: 500px;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label),
      .input,
      .inline-always .input{
      height: 60px!important;
      }
      label:not(.radio-label),
      .inline-always .label,
      .label {
      text-align: right;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      align-items: center;
      justify-content: flex-end;
      }
      input:not([type=radio]),
      select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline {
      margin-bottom: 0
      }

      .invalid,.invalid-radio {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      margin:0;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      <form id="step-one" method="get" novalidate autocomplete="off">

      <h1>Step 1 &mdash; Information</h1>
      <p>Fill in all that apply.</p>

      <div class="field">
      <label for="pet-name">Pet name</label>
      <div class="input">
      <input required id="pet-name" value type="text" placeholder="e.g. Milo" pattern="^[a-zA-Z0-9_ ]*$" tabindex="1" accesskey="p">
      </div>
      </div>

      <div class="field">
      <label for="zipcode">Zipcode</label>
      <div class="input">
      <input required aria-required="required" value type="text" placeholder="e.g. 12345 or 12345-9876" id="zipcode" pattern="(d{5}([-]d{4})?)" tabindex="2" accesskey="z">
      </div>
      </div>

      <div class="field inline inline-always">
      <p class="label">Select a pet type</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="dog" name="type" tabindex="3" required aria-required="required" accesskey="a">
      <label for="dog" class="radio-label">Dog</label>
      <input type="radio" id="cat" name="type">
      <label for="cat" class="radio-label">Cat</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="breed">Select breed</label>
      <div class="input">
      <select id="breed" class="select" required aria-required="required" tabindex="4" accesskey="b">
      <option value disabled>Breeds List</option>
      <optgroup label="Common Breeds">
      <option value="5">Mixed Breed</option>
      <option value="27">Bearded Collie</option>
      <option value="28">Beauceron</option>
      <option value="224">Bedlington Terrier</option>
      </optgroup>
      <optgroup label="All Breeds">
      <option value="6">Affenpinscher</option>
      <option value="7">Afghan Hound</option>
      </optgroup>
      </select>
      </div>
      </div>

      <div class="field">
      <label for="age">Select age</label>
      <div class="input">
      <select id="age" class="select" required aria-required="required" tabindex="5" accesskey="y">
      <option value disabled>Years of age</option>
      <option value="1">Under 1</option>
      <option value="2">1</option>
      <option value="3">2</option>
      <option value="4">3</option>
      <option value="5">4</option>
      <option value="6">5</option>
      <option value="7">6</option>
      <option value="7">7</option>
      <option value="9">8</option>
      <option value="10">9</option>
      <option value="11">10</option>
      <option value="12">11</option>
      <option value="13">12</option>
      <option value="14">13</option>
      <option value="15">14</option>
      <option value="16">15</option>
      <option value="17">16</option>
      <option value="17">17</option>
      <option value="19">18</option>
      <option value="20">19</option>
      <option value="21">20</option>
      <option value="22">21</option>
      <option value="23">22</option>
      <option value="24">23</option>
      <option value="25">24</option>
      <option value="26">25</option>
      <option value="27">26</option>
      <option value="27">27</option>
      <option value="29">28</option>
      <option value="30">29</option>
      <option value="31">30</option>
      </select>
      </div>
      </div>

      <div class="field inline">
      <p class="label">Has your pet ever been diagnosed with or shown symptoms of Diabetes, Cushing’s Disease, or FeLV/FIV?</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="yes" name="q" tabindex="6" required aria-required="required" accesskey="h">
      <label for="yes" class="radio-label">Yes</label>
      <input type="radio" id="no" name="q">
      <label for="no" class="radio-label">No</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="email">Email address</label>
      <div class="input">
      <input id="email" value type="text" placeholder="e.g. name@address.co" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$" tabindex="7" accesskey="e">
      </div>
      </div>

      <button type="submit" tabindex="8" accesskey="n">Next</button>
      <button type="reset" tabindex="0" accesskey="r">Reset</button>

      </form>












      share|improve this question















      I've been working on a live form validation project, initially I intended on finding a way to solely use CSS for said validation but it quickly became apparent I would require some jQuery to get it to function properly. That said, I'd like another set of eyes on my jQuery to see if anyone has improvements or tips to streamline it a little better. It seems like there is an awful lot of code repetition but I'm not sure how to best minimize that.



      If you'd like to offer improvements for the HTML/CSS then by all means have at it but my primary concern is the jQuery below since I haven't polished the styles yet.



      Disclaimer: *This is a work in progress, so there are no fallbacks/polyfills for older browsers at this time.






      var timer = 0,
      input = $('input').not('[type=radio]'),
      radio = $('input[type=radio]'),
      select = $('select'),
      notRequired = input.not('[required]'),
      form = $('form');

      function supportsHtml5Validation() {
      return typeof document.createElement('input').checkValidity === 'function';
      }

      function windowSize() {
      windowHeight = window.innerHeight ? window.innerHeight : $(window).height();
      windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
      AddValidationClasses();
      }
      windowSize();
      $(window).resize(function () {
      windowSize();
      });

      function isValid(input) {
      $(input).addClass('valid').removeClass('invalid');
      }

      function inValid(input) {
      $(input).addClass('invalid').removeClass('valid');
      }

      function isEmpty(input) {
      if (!$.trim($(input).val())) {
      $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');
      }
      }

      function delay(callback, ms) {
      timer = setTimeout(callback, ms);
      }

      function AddValidationClasses(){
      $('.group').each(function () {
      if (windowWidth >= 800 && input.not(':checked')) {
      $(this).addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.group').removeClass('invalid-radio');
      });
      } else if (windowWidth < 800 && input.not(':checked')) {
      $(this).parent().removeClass('invalid-radio');
      $(this).closest('.field').addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.field').removeClass('invalid-radio');
      });
      }
      });
      }

      $(document).ready(function () {

      if (!supportsHtml5Validation()) { return; }

      input.on('keyup', function () {
      clearTimeout(timer);
      if ($.trim($(this).val()) === '') {
      isEmpty(this);
      return false;
      } else if (!this.checkValidity()) {
      timer = setTimeout(inValid(this), 300);
      //delay(function(){ return inValid(inputToValidate); }, 300);
      } else if (this.checkValidity()) {
      isValid(this);
      }
      });

      select.on('change', function(){
      if (!this.checkValidity()) {
      inValid(this);
      } else {
      isValid(this);
      }
      });

      form.on('submit', function (e) {

      input.add(select).each(function () {
      if (!this.checkValidity()) {
      e.preventDefault();
      inValid(this);
      } else {
      isValid(this);
      }
      });


      /*
      .field
      label
      .input
      .group
      radio's */

      AddValidationClasses();
      });

      $('button[type=reset]').on('click', function () {
      console.log('reset clicked');
      $('.group, .field, input, select').each(function () {
      isEmpty(this);
      });
      });

      if(notRequired){
      notRequired.on('keyup', function(){
      if($(this).val().match($(this).attr('pattern'))) {
      notRequired.each(function(){
      isValid(this);
      });
      }else{
      notRequired.each(function(){
      inValid(this);
      });
      }
      });
      }
      });

      @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600);
      @-ms-viewport{width:device-width;zoom:1;max-zoom:150%}

      @-o-viewport{width:device-width;zoom:1;max-zoom:150%}

      @viewport{width:device-width;zoom:1;max-zoom:150%}

      html {
      box-sizing: border-box;
      font-family: 'Source Sans Pro', sans-serif;
      -ms-text-size-adjust: 100%;
      -webkit-text-size-adjust: 100%
      }
      body {
      margin: 0;
      color: #27415a;
      background: #e9f4f8;
      font-size: 16px;
      }
      :focus::-webkit-input-placeholder {
      color: transparent
      }
      :focus:-moz-placeholder {
      color: transparent
      }
      :focus::-moz-placeholder {
      color: transparent
      }
      :focus:-ms-input-placeholder {
      color: transparent
      }
      ::-webkit-input-placeholder {
      color: slategray
      }
      :-moz-placeholder {
      color: slategray
      }
      ::-moz-placeholder {
      color: slategray
      }
      :-ms-input-placeholder {
      color: slategray
      }
      select option:nth-child(1) {
      color: slategray!important
      }
      *,
      :before,
      :after {
      box-sizing: inherit;
      }
      h1 {
      color: #27415a;
      font-size: 24px
      }
      .margin-top {
      margin-top: 50px
      }
      .field {
      position: relative;
      padding: 5px 10px
      }
      .error .field{
      background-color:}
      .field .label,
      .field label:not(.radio-label) {
      font-weight: 600;
      margin-top: 0;
      margin-bottom: 5px
      }
      .inline {
      margin-bottom: 15px
      }
      .group {
      text-align: right
      }
      .group .radio-label,
      label{
      cursor: pointer
      }
      input:not([type=radio]),
      select {
      position: relative;
      margin-top: 5px;
      margin-bottom: 20px;
      padding: 8px;
      width: 100%;
      display: block;
      border: #5bf 1px solid;
      box-shadow: inset 0 0 1px #5bf;
      border-radius: 2px;
      background-color: white;
      background-color: rgba(255, 255, 255, .85);
      background-image: none;
      color: #27415a;

      -webkit-transition: color .2s, background-color .2s, border .2s ease;
      transition: color .2s, background-color .2s, border .2s ease;
      }
      input:focus:not([type=radio]),
      select:focus {
      padding-left: 10px;
      outline: 0;
      border-left-width: 3px;
      box-shadow: inset 0 0 2px white
      }
      input[required]:valid:focus:not([type=radio]),
      select[required]:valid:focus,
      input[required]:valid:not([type=radio]),
      select[required]:valid,
      .valid{
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white!important;
      color: green!important
      }
      .valid{
      border-color: #79bf6d!important;
      background-color: white!important;
      background-color: rgba(207, 254, 168, 0.2)!important;}
      .invalid {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      border: 1px solid #f7a716;
      margin: 0 10px 15px 10px;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }
      .invalid::-webkit-input-placeholder {
      color: #b63910!important
      }
      .invalid:-moz-placeholder {
      color: #b63910!important
      }
      .invalid::-moz-placeholder {
      color: #b63910!important
      }
      .invalid:-ms-input-placeholder {
      color: #b63910!important
      }
      select: {
      outline: 0
      }
      select:not(:checked) {
      padding-left: 5px;
      }
      input:-webkit-autofill:not([type=radio]) {
      -webkit-box-shadow: 0 0 0 1000px #e9f4f8 inset
      }
      textarea,
      select[size],
      select[multiple] {
      height: auto
      }
      select[size="0"],
      select[size="1"] {
      height: 1.8em;
      *height: auto
      }
      button,
      .button {
      margin:10px 0 25px 10px;
      padding: 12px 25px;
      float: right;
      border-radius: 3px;
      background-color: #79bf6d;
      border:1px solid #70AB66;
      color: white;
      box-shadow:inset 0 1px 1px -1px white;
      }
      button[disabled]{
      background-color:#ddd;
      color:slategray;
      text-shadow:1px 0 0 white;
      border:1px solid #ccc}
      input[type=checkbox]:not(old),
      input[type=radio]:not(old) {
      margin: 0;
      padding: 0;
      opacity: 0
      }
      input[type=checkbox]:not(old)+label,
      input[type=radio]:not(old)+label {
      display: inline-block;
      margin-left: 0;
      padding-left: 36px;
      background: url('http://leftdeaf.com/ppi/quote/new/img/disc.png') no-repeat 0 3px;
      background-size: 28px 28px;
      line-height: 36px;
      text-transform: uppercase;
      font-weight: 600
      }
      input[type=checkbox]:not(old):checked+label,
      input[type=radio]:not(old):checked+label {
      background: url('http://leftdeaf.com/ppi/quote/new/img/valid.png') no-repeat 0 3px;
      background-size: 28px 28px
      }
      input[type=radio]:not(old):active+label {
      background-position: -1px 2px;
      background-size: 30px
      }
      select[size],
      select[multiple],
      select[multiple][size] {
      padding-right: 3px;
      background-image: none
      }
      select,
      select[size="0"],
      select[size="1"] {
      padding-right: 20px;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-basic.png);
      background-position: 98% 50%;
      background-size: 24px;
      background-repeat: no-repeat;
      text-indent: 1px;
      text-overflow: '';
      cursor: pointer;
      -webkit-appearance: none;
      -moz-appearance: none
      }
      select:not(:checked),
      select[size="0"]:not(:checked),
      select[size="1"]:not(:checked){
      color:slategray;
      }
      select:focus option:nth-child(1),
      select[size="0"]:focus option:nth-child(1),
      select[size="1"]:focus option:nth-child(1) {
      display: none
      }

      select.invalid:not(:selected) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-invalid.png')
      }
      select:focus,
      select[size="0"]:focus,
      select[size="1"]:focus {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/add-basic.png)
      }
      select:checked:valid,
      select[size="0"]:checked:valid,
      select[size="1"]:checked:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png);
      color: #27415a
      }
      select:focus:valid,
      select[size="0"]:required:focus:valid,
      select[size="1"]:required:focus:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)
      }
      select:valid:not(:checked),
      select[size="0"]:valid:not(:checked),
      select[size="1"]:valid:not(:checked) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png)
      }
      select.valid:valid,
      select[size="0"]:required.valid:valid,
      select[size="1"]:required.valid:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      }
      select::-ms-expand {
      display: none
      }


      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input {
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      justify-content: flex-end;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .inline-always .input {
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .inline-always .label{
      width: 300px;
      padding-right: 25px;
      }
      .inline-always .input {
      width: 500px;
      }
      .inline-always .label
      .inline-always .input {
      height: 60px!important;
      }
      .inline-always .label {
      text-align: left;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      align-items: center;
      justify-content: flex-start;
      }
      .inline-always input:not([type=radio]),
      .inline-always select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline-always .inline {
      margin-bottom: 0
      }

      @media (min-width: 800px) {
      /* flex layout */
      form {
      width: 100%;
      max-width: 800px;
      margin: 0 auto
      }
      .group {
      text-align: left
      }
      .field,
      .group,
      label:not(.radio-label),
      .label,
      .input,
      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input{
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      justify-content: flex-start;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .input,
      .inline-always input{
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group,
      .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label) {
      width: 300px;
      padding-right: 25px;
      }
      .input {
      width: 500px;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label),
      .input,
      .inline-always .input{
      height: 60px!important;
      }
      label:not(.radio-label),
      .inline-always .label,
      .label {
      text-align: right;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      align-items: center;
      justify-content: flex-end;
      }
      input:not([type=radio]),
      select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline {
      margin-bottom: 0
      }

      .invalid,.invalid-radio {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      margin:0;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      <form id="step-one" method="get" novalidate autocomplete="off">

      <h1>Step 1 &mdash; Information</h1>
      <p>Fill in all that apply.</p>

      <div class="field">
      <label for="pet-name">Pet name</label>
      <div class="input">
      <input required id="pet-name" value type="text" placeholder="e.g. Milo" pattern="^[a-zA-Z0-9_ ]*$" tabindex="1" accesskey="p">
      </div>
      </div>

      <div class="field">
      <label for="zipcode">Zipcode</label>
      <div class="input">
      <input required aria-required="required" value type="text" placeholder="e.g. 12345 or 12345-9876" id="zipcode" pattern="(d{5}([-]d{4})?)" tabindex="2" accesskey="z">
      </div>
      </div>

      <div class="field inline inline-always">
      <p class="label">Select a pet type</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="dog" name="type" tabindex="3" required aria-required="required" accesskey="a">
      <label for="dog" class="radio-label">Dog</label>
      <input type="radio" id="cat" name="type">
      <label for="cat" class="radio-label">Cat</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="breed">Select breed</label>
      <div class="input">
      <select id="breed" class="select" required aria-required="required" tabindex="4" accesskey="b">
      <option value disabled>Breeds List</option>
      <optgroup label="Common Breeds">
      <option value="5">Mixed Breed</option>
      <option value="27">Bearded Collie</option>
      <option value="28">Beauceron</option>
      <option value="224">Bedlington Terrier</option>
      </optgroup>
      <optgroup label="All Breeds">
      <option value="6">Affenpinscher</option>
      <option value="7">Afghan Hound</option>
      </optgroup>
      </select>
      </div>
      </div>

      <div class="field">
      <label for="age">Select age</label>
      <div class="input">
      <select id="age" class="select" required aria-required="required" tabindex="5" accesskey="y">
      <option value disabled>Years of age</option>
      <option value="1">Under 1</option>
      <option value="2">1</option>
      <option value="3">2</option>
      <option value="4">3</option>
      <option value="5">4</option>
      <option value="6">5</option>
      <option value="7">6</option>
      <option value="7">7</option>
      <option value="9">8</option>
      <option value="10">9</option>
      <option value="11">10</option>
      <option value="12">11</option>
      <option value="13">12</option>
      <option value="14">13</option>
      <option value="15">14</option>
      <option value="16">15</option>
      <option value="17">16</option>
      <option value="17">17</option>
      <option value="19">18</option>
      <option value="20">19</option>
      <option value="21">20</option>
      <option value="22">21</option>
      <option value="23">22</option>
      <option value="24">23</option>
      <option value="25">24</option>
      <option value="26">25</option>
      <option value="27">26</option>
      <option value="27">27</option>
      <option value="29">28</option>
      <option value="30">29</option>
      <option value="31">30</option>
      </select>
      </div>
      </div>

      <div class="field inline">
      <p class="label">Has your pet ever been diagnosed with or shown symptoms of Diabetes, Cushing’s Disease, or FeLV/FIV?</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="yes" name="q" tabindex="6" required aria-required="required" accesskey="h">
      <label for="yes" class="radio-label">Yes</label>
      <input type="radio" id="no" name="q">
      <label for="no" class="radio-label">No</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="email">Email address</label>
      <div class="input">
      <input id="email" value type="text" placeholder="e.g. name@address.co" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$" tabindex="7" accesskey="e">
      </div>
      </div>

      <button type="submit" tabindex="8" accesskey="n">Next</button>
      <button type="reset" tabindex="0" accesskey="r">Reset</button>

      </form>








      var timer = 0,
      input = $('input').not('[type=radio]'),
      radio = $('input[type=radio]'),
      select = $('select'),
      notRequired = input.not('[required]'),
      form = $('form');

      function supportsHtml5Validation() {
      return typeof document.createElement('input').checkValidity === 'function';
      }

      function windowSize() {
      windowHeight = window.innerHeight ? window.innerHeight : $(window).height();
      windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
      AddValidationClasses();
      }
      windowSize();
      $(window).resize(function () {
      windowSize();
      });

      function isValid(input) {
      $(input).addClass('valid').removeClass('invalid');
      }

      function inValid(input) {
      $(input).addClass('invalid').removeClass('valid');
      }

      function isEmpty(input) {
      if (!$.trim($(input).val())) {
      $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');
      }
      }

      function delay(callback, ms) {
      timer = setTimeout(callback, ms);
      }

      function AddValidationClasses(){
      $('.group').each(function () {
      if (windowWidth >= 800 && input.not(':checked')) {
      $(this).addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.group').removeClass('invalid-radio');
      });
      } else if (windowWidth < 800 && input.not(':checked')) {
      $(this).parent().removeClass('invalid-radio');
      $(this).closest('.field').addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.field').removeClass('invalid-radio');
      });
      }
      });
      }

      $(document).ready(function () {

      if (!supportsHtml5Validation()) { return; }

      input.on('keyup', function () {
      clearTimeout(timer);
      if ($.trim($(this).val()) === '') {
      isEmpty(this);
      return false;
      } else if (!this.checkValidity()) {
      timer = setTimeout(inValid(this), 300);
      //delay(function(){ return inValid(inputToValidate); }, 300);
      } else if (this.checkValidity()) {
      isValid(this);
      }
      });

      select.on('change', function(){
      if (!this.checkValidity()) {
      inValid(this);
      } else {
      isValid(this);
      }
      });

      form.on('submit', function (e) {

      input.add(select).each(function () {
      if (!this.checkValidity()) {
      e.preventDefault();
      inValid(this);
      } else {
      isValid(this);
      }
      });


      /*
      .field
      label
      .input
      .group
      radio's */

      AddValidationClasses();
      });

      $('button[type=reset]').on('click', function () {
      console.log('reset clicked');
      $('.group, .field, input, select').each(function () {
      isEmpty(this);
      });
      });

      if(notRequired){
      notRequired.on('keyup', function(){
      if($(this).val().match($(this).attr('pattern'))) {
      notRequired.each(function(){
      isValid(this);
      });
      }else{
      notRequired.each(function(){
      inValid(this);
      });
      }
      });
      }
      });

      @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600);
      @-ms-viewport{width:device-width;zoom:1;max-zoom:150%}

      @-o-viewport{width:device-width;zoom:1;max-zoom:150%}

      @viewport{width:device-width;zoom:1;max-zoom:150%}

      html {
      box-sizing: border-box;
      font-family: 'Source Sans Pro', sans-serif;
      -ms-text-size-adjust: 100%;
      -webkit-text-size-adjust: 100%
      }
      body {
      margin: 0;
      color: #27415a;
      background: #e9f4f8;
      font-size: 16px;
      }
      :focus::-webkit-input-placeholder {
      color: transparent
      }
      :focus:-moz-placeholder {
      color: transparent
      }
      :focus::-moz-placeholder {
      color: transparent
      }
      :focus:-ms-input-placeholder {
      color: transparent
      }
      ::-webkit-input-placeholder {
      color: slategray
      }
      :-moz-placeholder {
      color: slategray
      }
      ::-moz-placeholder {
      color: slategray
      }
      :-ms-input-placeholder {
      color: slategray
      }
      select option:nth-child(1) {
      color: slategray!important
      }
      *,
      :before,
      :after {
      box-sizing: inherit;
      }
      h1 {
      color: #27415a;
      font-size: 24px
      }
      .margin-top {
      margin-top: 50px
      }
      .field {
      position: relative;
      padding: 5px 10px
      }
      .error .field{
      background-color:}
      .field .label,
      .field label:not(.radio-label) {
      font-weight: 600;
      margin-top: 0;
      margin-bottom: 5px
      }
      .inline {
      margin-bottom: 15px
      }
      .group {
      text-align: right
      }
      .group .radio-label,
      label{
      cursor: pointer
      }
      input:not([type=radio]),
      select {
      position: relative;
      margin-top: 5px;
      margin-bottom: 20px;
      padding: 8px;
      width: 100%;
      display: block;
      border: #5bf 1px solid;
      box-shadow: inset 0 0 1px #5bf;
      border-radius: 2px;
      background-color: white;
      background-color: rgba(255, 255, 255, .85);
      background-image: none;
      color: #27415a;

      -webkit-transition: color .2s, background-color .2s, border .2s ease;
      transition: color .2s, background-color .2s, border .2s ease;
      }
      input:focus:not([type=radio]),
      select:focus {
      padding-left: 10px;
      outline: 0;
      border-left-width: 3px;
      box-shadow: inset 0 0 2px white
      }
      input[required]:valid:focus:not([type=radio]),
      select[required]:valid:focus,
      input[required]:valid:not([type=radio]),
      select[required]:valid,
      .valid{
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white!important;
      color: green!important
      }
      .valid{
      border-color: #79bf6d!important;
      background-color: white!important;
      background-color: rgba(207, 254, 168, 0.2)!important;}
      .invalid {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      border: 1px solid #f7a716;
      margin: 0 10px 15px 10px;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }
      .invalid::-webkit-input-placeholder {
      color: #b63910!important
      }
      .invalid:-moz-placeholder {
      color: #b63910!important
      }
      .invalid::-moz-placeholder {
      color: #b63910!important
      }
      .invalid:-ms-input-placeholder {
      color: #b63910!important
      }
      select: {
      outline: 0
      }
      select:not(:checked) {
      padding-left: 5px;
      }
      input:-webkit-autofill:not([type=radio]) {
      -webkit-box-shadow: 0 0 0 1000px #e9f4f8 inset
      }
      textarea,
      select[size],
      select[multiple] {
      height: auto
      }
      select[size="0"],
      select[size="1"] {
      height: 1.8em;
      *height: auto
      }
      button,
      .button {
      margin:10px 0 25px 10px;
      padding: 12px 25px;
      float: right;
      border-radius: 3px;
      background-color: #79bf6d;
      border:1px solid #70AB66;
      color: white;
      box-shadow:inset 0 1px 1px -1px white;
      }
      button[disabled]{
      background-color:#ddd;
      color:slategray;
      text-shadow:1px 0 0 white;
      border:1px solid #ccc}
      input[type=checkbox]:not(old),
      input[type=radio]:not(old) {
      margin: 0;
      padding: 0;
      opacity: 0
      }
      input[type=checkbox]:not(old)+label,
      input[type=radio]:not(old)+label {
      display: inline-block;
      margin-left: 0;
      padding-left: 36px;
      background: url('http://leftdeaf.com/ppi/quote/new/img/disc.png') no-repeat 0 3px;
      background-size: 28px 28px;
      line-height: 36px;
      text-transform: uppercase;
      font-weight: 600
      }
      input[type=checkbox]:not(old):checked+label,
      input[type=radio]:not(old):checked+label {
      background: url('http://leftdeaf.com/ppi/quote/new/img/valid.png') no-repeat 0 3px;
      background-size: 28px 28px
      }
      input[type=radio]:not(old):active+label {
      background-position: -1px 2px;
      background-size: 30px
      }
      select[size],
      select[multiple],
      select[multiple][size] {
      padding-right: 3px;
      background-image: none
      }
      select,
      select[size="0"],
      select[size="1"] {
      padding-right: 20px;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-basic.png);
      background-position: 98% 50%;
      background-size: 24px;
      background-repeat: no-repeat;
      text-indent: 1px;
      text-overflow: '';
      cursor: pointer;
      -webkit-appearance: none;
      -moz-appearance: none
      }
      select:not(:checked),
      select[size="0"]:not(:checked),
      select[size="1"]:not(:checked){
      color:slategray;
      }
      select:focus option:nth-child(1),
      select[size="0"]:focus option:nth-child(1),
      select[size="1"]:focus option:nth-child(1) {
      display: none
      }

      select.invalid:not(:selected) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-invalid.png')
      }
      select:focus,
      select[size="0"]:focus,
      select[size="1"]:focus {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/add-basic.png)
      }
      select:checked:valid,
      select[size="0"]:checked:valid,
      select[size="1"]:checked:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png);
      color: #27415a
      }
      select:focus:valid,
      select[size="0"]:required:focus:valid,
      select[size="1"]:required:focus:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)
      }
      select:valid:not(:checked),
      select[size="0"]:valid:not(:checked),
      select[size="1"]:valid:not(:checked) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png)
      }
      select.valid:valid,
      select[size="0"]:required.valid:valid,
      select[size="1"]:required.valid:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      }
      select::-ms-expand {
      display: none
      }


      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input {
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      justify-content: flex-end;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .inline-always .input {
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .inline-always .label{
      width: 300px;
      padding-right: 25px;
      }
      .inline-always .input {
      width: 500px;
      }
      .inline-always .label
      .inline-always .input {
      height: 60px!important;
      }
      .inline-always .label {
      text-align: left;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      align-items: center;
      justify-content: flex-start;
      }
      .inline-always input:not([type=radio]),
      .inline-always select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline-always .inline {
      margin-bottom: 0
      }

      @media (min-width: 800px) {
      /* flex layout */
      form {
      width: 100%;
      max-width: 800px;
      margin: 0 auto
      }
      .group {
      text-align: left
      }
      .field,
      .group,
      label:not(.radio-label),
      .label,
      .input,
      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input{
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      justify-content: flex-start;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .input,
      .inline-always input{
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group,
      .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label) {
      width: 300px;
      padding-right: 25px;
      }
      .input {
      width: 500px;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label),
      .input,
      .inline-always .input{
      height: 60px!important;
      }
      label:not(.radio-label),
      .inline-always .label,
      .label {
      text-align: right;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      align-items: center;
      justify-content: flex-end;
      }
      input:not([type=radio]),
      select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline {
      margin-bottom: 0
      }

      .invalid,.invalid-radio {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      margin:0;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      <form id="step-one" method="get" novalidate autocomplete="off">

      <h1>Step 1 &mdash; Information</h1>
      <p>Fill in all that apply.</p>

      <div class="field">
      <label for="pet-name">Pet name</label>
      <div class="input">
      <input required id="pet-name" value type="text" placeholder="e.g. Milo" pattern="^[a-zA-Z0-9_ ]*$" tabindex="1" accesskey="p">
      </div>
      </div>

      <div class="field">
      <label for="zipcode">Zipcode</label>
      <div class="input">
      <input required aria-required="required" value type="text" placeholder="e.g. 12345 or 12345-9876" id="zipcode" pattern="(d{5}([-]d{4})?)" tabindex="2" accesskey="z">
      </div>
      </div>

      <div class="field inline inline-always">
      <p class="label">Select a pet type</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="dog" name="type" tabindex="3" required aria-required="required" accesskey="a">
      <label for="dog" class="radio-label">Dog</label>
      <input type="radio" id="cat" name="type">
      <label for="cat" class="radio-label">Cat</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="breed">Select breed</label>
      <div class="input">
      <select id="breed" class="select" required aria-required="required" tabindex="4" accesskey="b">
      <option value disabled>Breeds List</option>
      <optgroup label="Common Breeds">
      <option value="5">Mixed Breed</option>
      <option value="27">Bearded Collie</option>
      <option value="28">Beauceron</option>
      <option value="224">Bedlington Terrier</option>
      </optgroup>
      <optgroup label="All Breeds">
      <option value="6">Affenpinscher</option>
      <option value="7">Afghan Hound</option>
      </optgroup>
      </select>
      </div>
      </div>

      <div class="field">
      <label for="age">Select age</label>
      <div class="input">
      <select id="age" class="select" required aria-required="required" tabindex="5" accesskey="y">
      <option value disabled>Years of age</option>
      <option value="1">Under 1</option>
      <option value="2">1</option>
      <option value="3">2</option>
      <option value="4">3</option>
      <option value="5">4</option>
      <option value="6">5</option>
      <option value="7">6</option>
      <option value="7">7</option>
      <option value="9">8</option>
      <option value="10">9</option>
      <option value="11">10</option>
      <option value="12">11</option>
      <option value="13">12</option>
      <option value="14">13</option>
      <option value="15">14</option>
      <option value="16">15</option>
      <option value="17">16</option>
      <option value="17">17</option>
      <option value="19">18</option>
      <option value="20">19</option>
      <option value="21">20</option>
      <option value="22">21</option>
      <option value="23">22</option>
      <option value="24">23</option>
      <option value="25">24</option>
      <option value="26">25</option>
      <option value="27">26</option>
      <option value="27">27</option>
      <option value="29">28</option>
      <option value="30">29</option>
      <option value="31">30</option>
      </select>
      </div>
      </div>

      <div class="field inline">
      <p class="label">Has your pet ever been diagnosed with or shown symptoms of Diabetes, Cushing’s Disease, or FeLV/FIV?</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="yes" name="q" tabindex="6" required aria-required="required" accesskey="h">
      <label for="yes" class="radio-label">Yes</label>
      <input type="radio" id="no" name="q">
      <label for="no" class="radio-label">No</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="email">Email address</label>
      <div class="input">
      <input id="email" value type="text" placeholder="e.g. name@address.co" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$" tabindex="7" accesskey="e">
      </div>
      </div>

      <button type="submit" tabindex="8" accesskey="n">Next</button>
      <button type="reset" tabindex="0" accesskey="r">Reset</button>

      </form>





      var timer = 0,
      input = $('input').not('[type=radio]'),
      radio = $('input[type=radio]'),
      select = $('select'),
      notRequired = input.not('[required]'),
      form = $('form');

      function supportsHtml5Validation() {
      return typeof document.createElement('input').checkValidity === 'function';
      }

      function windowSize() {
      windowHeight = window.innerHeight ? window.innerHeight : $(window).height();
      windowWidth = window.innerWidth ? window.innerWidth : $(window).width();
      AddValidationClasses();
      }
      windowSize();
      $(window).resize(function () {
      windowSize();
      });

      function isValid(input) {
      $(input).addClass('valid').removeClass('invalid');
      }

      function inValid(input) {
      $(input).addClass('invalid').removeClass('valid');
      }

      function isEmpty(input) {
      if (!$.trim($(input).val())) {
      $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');
      }
      }

      function delay(callback, ms) {
      timer = setTimeout(callback, ms);
      }

      function AddValidationClasses(){
      $('.group').each(function () {
      if (windowWidth >= 800 && input.not(':checked')) {
      $(this).addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.group').removeClass('invalid-radio');
      });
      } else if (windowWidth < 800 && input.not(':checked')) {
      $(this).parent().removeClass('invalid-radio');
      $(this).closest('.field').addClass('invalid-radio');
      radio.on('change', function(){
      $(this).closest('.field').removeClass('invalid-radio');
      });
      }
      });
      }

      $(document).ready(function () {

      if (!supportsHtml5Validation()) { return; }

      input.on('keyup', function () {
      clearTimeout(timer);
      if ($.trim($(this).val()) === '') {
      isEmpty(this);
      return false;
      } else if (!this.checkValidity()) {
      timer = setTimeout(inValid(this), 300);
      //delay(function(){ return inValid(inputToValidate); }, 300);
      } else if (this.checkValidity()) {
      isValid(this);
      }
      });

      select.on('change', function(){
      if (!this.checkValidity()) {
      inValid(this);
      } else {
      isValid(this);
      }
      });

      form.on('submit', function (e) {

      input.add(select).each(function () {
      if (!this.checkValidity()) {
      e.preventDefault();
      inValid(this);
      } else {
      isValid(this);
      }
      });


      /*
      .field
      label
      .input
      .group
      radio's */

      AddValidationClasses();
      });

      $('button[type=reset]').on('click', function () {
      console.log('reset clicked');
      $('.group, .field, input, select').each(function () {
      isEmpty(this);
      });
      });

      if(notRequired){
      notRequired.on('keyup', function(){
      if($(this).val().match($(this).attr('pattern'))) {
      notRequired.each(function(){
      isValid(this);
      });
      }else{
      notRequired.each(function(){
      inValid(this);
      });
      }
      });
      }
      });

      @import url(http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600);
      @-ms-viewport{width:device-width;zoom:1;max-zoom:150%}

      @-o-viewport{width:device-width;zoom:1;max-zoom:150%}

      @viewport{width:device-width;zoom:1;max-zoom:150%}

      html {
      box-sizing: border-box;
      font-family: 'Source Sans Pro', sans-serif;
      -ms-text-size-adjust: 100%;
      -webkit-text-size-adjust: 100%
      }
      body {
      margin: 0;
      color: #27415a;
      background: #e9f4f8;
      font-size: 16px;
      }
      :focus::-webkit-input-placeholder {
      color: transparent
      }
      :focus:-moz-placeholder {
      color: transparent
      }
      :focus::-moz-placeholder {
      color: transparent
      }
      :focus:-ms-input-placeholder {
      color: transparent
      }
      ::-webkit-input-placeholder {
      color: slategray
      }
      :-moz-placeholder {
      color: slategray
      }
      ::-moz-placeholder {
      color: slategray
      }
      :-ms-input-placeholder {
      color: slategray
      }
      select option:nth-child(1) {
      color: slategray!important
      }
      *,
      :before,
      :after {
      box-sizing: inherit;
      }
      h1 {
      color: #27415a;
      font-size: 24px
      }
      .margin-top {
      margin-top: 50px
      }
      .field {
      position: relative;
      padding: 5px 10px
      }
      .error .field{
      background-color:}
      .field .label,
      .field label:not(.radio-label) {
      font-weight: 600;
      margin-top: 0;
      margin-bottom: 5px
      }
      .inline {
      margin-bottom: 15px
      }
      .group {
      text-align: right
      }
      .group .radio-label,
      label{
      cursor: pointer
      }
      input:not([type=radio]),
      select {
      position: relative;
      margin-top: 5px;
      margin-bottom: 20px;
      padding: 8px;
      width: 100%;
      display: block;
      border: #5bf 1px solid;
      box-shadow: inset 0 0 1px #5bf;
      border-radius: 2px;
      background-color: white;
      background-color: rgba(255, 255, 255, .85);
      background-image: none;
      color: #27415a;

      -webkit-transition: color .2s, background-color .2s, border .2s ease;
      transition: color .2s, background-color .2s, border .2s ease;
      }
      input:focus:not([type=radio]),
      select:focus {
      padding-left: 10px;
      outline: 0;
      border-left-width: 3px;
      box-shadow: inset 0 0 2px white
      }
      input[required]:valid:focus:not([type=radio]),
      select[required]:valid:focus,
      input[required]:valid:not([type=radio]),
      select[required]:valid,
      .valid{
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white!important;
      color: green!important
      }
      .valid{
      border-color: #79bf6d!important;
      background-color: white!important;
      background-color: rgba(207, 254, 168, 0.2)!important;}
      .invalid {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      border: 1px solid #f7a716;
      margin: 0 10px 15px 10px;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }
      .invalid::-webkit-input-placeholder {
      color: #b63910!important
      }
      .invalid:-moz-placeholder {
      color: #b63910!important
      }
      .invalid::-moz-placeholder {
      color: #b63910!important
      }
      .invalid:-ms-input-placeholder {
      color: #b63910!important
      }
      select: {
      outline: 0
      }
      select:not(:checked) {
      padding-left: 5px;
      }
      input:-webkit-autofill:not([type=radio]) {
      -webkit-box-shadow: 0 0 0 1000px #e9f4f8 inset
      }
      textarea,
      select[size],
      select[multiple] {
      height: auto
      }
      select[size="0"],
      select[size="1"] {
      height: 1.8em;
      *height: auto
      }
      button,
      .button {
      margin:10px 0 25px 10px;
      padding: 12px 25px;
      float: right;
      border-radius: 3px;
      background-color: #79bf6d;
      border:1px solid #70AB66;
      color: white;
      box-shadow:inset 0 1px 1px -1px white;
      }
      button[disabled]{
      background-color:#ddd;
      color:slategray;
      text-shadow:1px 0 0 white;
      border:1px solid #ccc}
      input[type=checkbox]:not(old),
      input[type=radio]:not(old) {
      margin: 0;
      padding: 0;
      opacity: 0
      }
      input[type=checkbox]:not(old)+label,
      input[type=radio]:not(old)+label {
      display: inline-block;
      margin-left: 0;
      padding-left: 36px;
      background: url('http://leftdeaf.com/ppi/quote/new/img/disc.png') no-repeat 0 3px;
      background-size: 28px 28px;
      line-height: 36px;
      text-transform: uppercase;
      font-weight: 600
      }
      input[type=checkbox]:not(old):checked+label,
      input[type=radio]:not(old):checked+label {
      background: url('http://leftdeaf.com/ppi/quote/new/img/valid.png') no-repeat 0 3px;
      background-size: 28px 28px
      }
      input[type=radio]:not(old):active+label {
      background-position: -1px 2px;
      background-size: 30px
      }
      select[size],
      select[multiple],
      select[multiple][size] {
      padding-right: 3px;
      background-image: none
      }
      select,
      select[size="0"],
      select[size="1"] {
      padding-right: 20px;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-basic.png);
      background-position: 98% 50%;
      background-size: 24px;
      background-repeat: no-repeat;
      text-indent: 1px;
      text-overflow: '';
      cursor: pointer;
      -webkit-appearance: none;
      -moz-appearance: none
      }
      select:not(:checked),
      select[size="0"]:not(:checked),
      select[size="1"]:not(:checked){
      color:slategray;
      }
      select:focus option:nth-child(1),
      select[size="0"]:focus option:nth-child(1),
      select[size="1"]:focus option:nth-child(1) {
      display: none
      }

      select.invalid:not(:selected) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-invalid.png')
      }
      select:focus,
      select[size="0"]:focus,
      select[size="1"]:focus {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/add-basic.png)
      }
      select:checked:valid,
      select[size="0"]:checked:valid,
      select[size="1"]:checked:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png);
      color: #27415a
      }
      select:focus:valid,
      select[size="0"]:required:focus:valid,
      select[size="1"]:required:focus:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)
      }
      select:valid:not(:checked),
      select[size="0"]:valid:not(:checked),
      select[size="1"]:valid:not(:checked) {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/down-valid.png)
      }
      select.valid:valid,
      select[size="0"]:required.valid:valid,
      select[size="1"]:required.valid:valid {
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/valid.png)!important;
      }
      select::-ms-expand {
      display: none
      }


      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input {
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      justify-content: flex-end;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .inline-always .input {
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .inline-always .label{
      width: 300px;
      padding-right: 25px;
      }
      .inline-always .input {
      width: 500px;
      }
      .inline-always .label
      .inline-always .input {
      height: 60px!important;
      }
      .inline-always .label {
      text-align: left;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      align-items: center;
      justify-content: flex-start;
      }
      .inline-always input:not([type=radio]),
      .inline-always select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline-always .inline {
      margin-bottom: 0
      }

      @media (min-width: 800px) {
      /* flex layout */
      form {
      width: 100%;
      max-width: 800px;
      margin: 0 auto
      }
      .group {
      text-align: left
      }
      .field,
      .group,
      label:not(.radio-label),
      .label,
      .input,
      .inline-always,
      .inline-always .group,
      .inline-always .label,
      .inline-always .input{
      display: -webkit-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-box-direction: normal;
      -webkit-box-orient: horizontal;
      -webkit-flex-direction: row;
      -ms-flex-direction: row;
      flex-direction: row;
      -webkit-flex-wrap: nowrap;
      -ms-flex-wrap: nowrap;
      flex-wrap: nowrap;
      -webkit-box-pack: start;
      -webkit-justify-content: flex-start;
      -ms-flex-pack: start;
      justify-content: flex-start;
      -webkit-align-content: stretch;
      -ms-flex-line-pack: stretch;
      align-items: center;
      -webkit-box-align: stretch;
      -webkit-align-items: stretch;
      -ms-flex-align: stretch;
      align-items: stretch;
      }
      .input,
      .inline-always input{
      -webkit-box-orient: vertical;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
      justify-content: center;
      }
      .inline-always .group,
      .group {
      -webkit-box-flex: 1;
      -webkit-flex: 1;
      -ms-flex: 1;
      flex: 1;
      align-items: center;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label) {
      width: 300px;
      padding-right: 25px;
      }
      .input {
      width: 500px;
      }
      .label,
      .inline-always .label,
      label:not(.radio-label),
      .input,
      .inline-always .input{
      height: 60px!important;
      }
      label:not(.radio-label),
      .inline-always .label,
      .label {
      text-align: right;
      -webkit-box-pack: end;
      -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
      align-items: center;
      justify-content: flex-end;
      }
      input:not([type=radio]),
      select {
      margin-top: 0;
      margin-bottom: 0;
      }
      .inline {
      margin-bottom: 0
      }

      .invalid,.invalid-radio {
      border-color: #f7a716!important;
      background-color: white;
      background-color: rgba(255, 213, 0, 0.13)!important;
      background-image: url(http://leftdeaf.com/ppi/quote/new/img/warning.png)!important;
      background-position: 98% 50%;
      background-size: 28px 28px;
      background-repeat: no-repeat;
      box-shadow: inset 0 3px 3px -3px white;
      color: #b63910!important
      }

      .invalid-radio {
      margin:0;
      }
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
      <form id="step-one" method="get" novalidate autocomplete="off">

      <h1>Step 1 &mdash; Information</h1>
      <p>Fill in all that apply.</p>

      <div class="field">
      <label for="pet-name">Pet name</label>
      <div class="input">
      <input required id="pet-name" value type="text" placeholder="e.g. Milo" pattern="^[a-zA-Z0-9_ ]*$" tabindex="1" accesskey="p">
      </div>
      </div>

      <div class="field">
      <label for="zipcode">Zipcode</label>
      <div class="input">
      <input required aria-required="required" value type="text" placeholder="e.g. 12345 or 12345-9876" id="zipcode" pattern="(d{5}([-]d{4})?)" tabindex="2" accesskey="z">
      </div>
      </div>

      <div class="field inline inline-always">
      <p class="label">Select a pet type</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="dog" name="type" tabindex="3" required aria-required="required" accesskey="a">
      <label for="dog" class="radio-label">Dog</label>
      <input type="radio" id="cat" name="type">
      <label for="cat" class="radio-label">Cat</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="breed">Select breed</label>
      <div class="input">
      <select id="breed" class="select" required aria-required="required" tabindex="4" accesskey="b">
      <option value disabled>Breeds List</option>
      <optgroup label="Common Breeds">
      <option value="5">Mixed Breed</option>
      <option value="27">Bearded Collie</option>
      <option value="28">Beauceron</option>
      <option value="224">Bedlington Terrier</option>
      </optgroup>
      <optgroup label="All Breeds">
      <option value="6">Affenpinscher</option>
      <option value="7">Afghan Hound</option>
      </optgroup>
      </select>
      </div>
      </div>

      <div class="field">
      <label for="age">Select age</label>
      <div class="input">
      <select id="age" class="select" required aria-required="required" tabindex="5" accesskey="y">
      <option value disabled>Years of age</option>
      <option value="1">Under 1</option>
      <option value="2">1</option>
      <option value="3">2</option>
      <option value="4">3</option>
      <option value="5">4</option>
      <option value="6">5</option>
      <option value="7">6</option>
      <option value="7">7</option>
      <option value="9">8</option>
      <option value="10">9</option>
      <option value="11">10</option>
      <option value="12">11</option>
      <option value="13">12</option>
      <option value="14">13</option>
      <option value="15">14</option>
      <option value="16">15</option>
      <option value="17">16</option>
      <option value="17">17</option>
      <option value="19">18</option>
      <option value="20">19</option>
      <option value="21">20</option>
      <option value="22">21</option>
      <option value="23">22</option>
      <option value="24">23</option>
      <option value="25">24</option>
      <option value="26">25</option>
      <option value="27">26</option>
      <option value="27">27</option>
      <option value="29">28</option>
      <option value="30">29</option>
      <option value="31">30</option>
      </select>
      </div>
      </div>

      <div class="field inline">
      <p class="label">Has your pet ever been diagnosed with or shown symptoms of Diabetes, Cushing’s Disease, or FeLV/FIV?</p>
      <div class="input">
      <div class="group">
      <input type="radio" id="yes" name="q" tabindex="6" required aria-required="required" accesskey="h">
      <label for="yes" class="radio-label">Yes</label>
      <input type="radio" id="no" name="q">
      <label for="no" class="radio-label">No</label>
      </div>
      </div>
      </div>

      <div class="field">
      <label for="email">Email address</label>
      <div class="input">
      <input id="email" value type="text" placeholder="e.g. name@address.co" pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$" tabindex="7" accesskey="e">
      </div>
      </div>

      <button type="submit" tabindex="8" accesskey="n">Next</button>
      <button type="reset" tabindex="0" accesskey="r">Reset</button>

      </form>






      javascript jquery validation form html5






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 2 days ago









      200_success

      128k15152413




      128k15152413










      asked Jan 31 '15 at 13:48









      darcher

      482215




      482215






















          1 Answer
          1






          active

          oldest

          votes


















          2














          Some of the variable names seem misleading. For example, input is actually a jQuery collection of elements with the radio inputs excluded, so perhaps nonRadioInputs would be more appropriate. Similarly, radio might be better named as radioInputs, select might be better named as selectInputs, etc.



          Also, some of the method names are confusing. For example, when I read isValid(input) I would expect such a funtion to return a boolean about whether the input is valid or not. The function appears to actually remove a class name and add a class name. A name that would make more sense to me would be something like addValidClassName(). The same is true for inValid(input) and isEmpty(input).





          The function delay() does not appear to be used, though there is a commented line utilizing it. It can be removed unless you plan to use it, in which case it might be advisable to only assign timer within that function.





          The variable windowHeight appears to be assigned a value but never used. It can be safely removed.





          The variable windowWidth is declared without the var keyword, this it is considered a global variable - actually all the variables outside a function are considered global, so you could limit the scope of all those by moving the whole code into an IIFE.





          The registration of the callback for the window resize event can be simplified from




          $(window).resize(function () {
          windowSize();
          });



          To:



          $(window).resize(windowSize);




          The exclusion of radio inputs could be incorporated into the CSS selector using the :not() CSS pseudo-class instead of the jQuery .not() filter - i.e. instead of




          input = $('input').not('[type=radio]'),



          Use this:



          input = $('input:not([type=radio])'),




          In the isEmpty() method, the statement within the conditional block can be simplified:




          $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');



          Because .removeClass() accepts "One or more space-separated classes to be removed from the class attribute of each matched element."1 the three calls can be simplified to a sing call:



          $(input).removeClass('invalid valid invalid-radio');




          The change handlers for the radio inputs within AddValidationClasses() could be abstracted into a function that accepts a class name for the closest element and made into partial functions via .bind().



          1http://api.jquery.com/removeClass/#removeClass-className






          share|improve this answer























            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f79175%2fhtml5-css-live-validation-w-jquery%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            Some of the variable names seem misleading. For example, input is actually a jQuery collection of elements with the radio inputs excluded, so perhaps nonRadioInputs would be more appropriate. Similarly, radio might be better named as radioInputs, select might be better named as selectInputs, etc.



            Also, some of the method names are confusing. For example, when I read isValid(input) I would expect such a funtion to return a boolean about whether the input is valid or not. The function appears to actually remove a class name and add a class name. A name that would make more sense to me would be something like addValidClassName(). The same is true for inValid(input) and isEmpty(input).





            The function delay() does not appear to be used, though there is a commented line utilizing it. It can be removed unless you plan to use it, in which case it might be advisable to only assign timer within that function.





            The variable windowHeight appears to be assigned a value but never used. It can be safely removed.





            The variable windowWidth is declared without the var keyword, this it is considered a global variable - actually all the variables outside a function are considered global, so you could limit the scope of all those by moving the whole code into an IIFE.





            The registration of the callback for the window resize event can be simplified from




            $(window).resize(function () {
            windowSize();
            });



            To:



            $(window).resize(windowSize);




            The exclusion of radio inputs could be incorporated into the CSS selector using the :not() CSS pseudo-class instead of the jQuery .not() filter - i.e. instead of




            input = $('input').not('[type=radio]'),



            Use this:



            input = $('input:not([type=radio])'),




            In the isEmpty() method, the statement within the conditional block can be simplified:




            $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');



            Because .removeClass() accepts "One or more space-separated classes to be removed from the class attribute of each matched element."1 the three calls can be simplified to a sing call:



            $(input).removeClass('invalid valid invalid-radio');




            The change handlers for the radio inputs within AddValidationClasses() could be abstracted into a function that accepts a class name for the closest element and made into partial functions via .bind().



            1http://api.jquery.com/removeClass/#removeClass-className






            share|improve this answer




























              2














              Some of the variable names seem misleading. For example, input is actually a jQuery collection of elements with the radio inputs excluded, so perhaps nonRadioInputs would be more appropriate. Similarly, radio might be better named as radioInputs, select might be better named as selectInputs, etc.



              Also, some of the method names are confusing. For example, when I read isValid(input) I would expect such a funtion to return a boolean about whether the input is valid or not. The function appears to actually remove a class name and add a class name. A name that would make more sense to me would be something like addValidClassName(). The same is true for inValid(input) and isEmpty(input).





              The function delay() does not appear to be used, though there is a commented line utilizing it. It can be removed unless you plan to use it, in which case it might be advisable to only assign timer within that function.





              The variable windowHeight appears to be assigned a value but never used. It can be safely removed.





              The variable windowWidth is declared without the var keyword, this it is considered a global variable - actually all the variables outside a function are considered global, so you could limit the scope of all those by moving the whole code into an IIFE.





              The registration of the callback for the window resize event can be simplified from




              $(window).resize(function () {
              windowSize();
              });



              To:



              $(window).resize(windowSize);




              The exclusion of radio inputs could be incorporated into the CSS selector using the :not() CSS pseudo-class instead of the jQuery .not() filter - i.e. instead of




              input = $('input').not('[type=radio]'),



              Use this:



              input = $('input:not([type=radio])'),




              In the isEmpty() method, the statement within the conditional block can be simplified:




              $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');



              Because .removeClass() accepts "One or more space-separated classes to be removed from the class attribute of each matched element."1 the three calls can be simplified to a sing call:



              $(input).removeClass('invalid valid invalid-radio');




              The change handlers for the radio inputs within AddValidationClasses() could be abstracted into a function that accepts a class name for the closest element and made into partial functions via .bind().



              1http://api.jquery.com/removeClass/#removeClass-className






              share|improve this answer


























                2












                2








                2






                Some of the variable names seem misleading. For example, input is actually a jQuery collection of elements with the radio inputs excluded, so perhaps nonRadioInputs would be more appropriate. Similarly, radio might be better named as radioInputs, select might be better named as selectInputs, etc.



                Also, some of the method names are confusing. For example, when I read isValid(input) I would expect such a funtion to return a boolean about whether the input is valid or not. The function appears to actually remove a class name and add a class name. A name that would make more sense to me would be something like addValidClassName(). The same is true for inValid(input) and isEmpty(input).





                The function delay() does not appear to be used, though there is a commented line utilizing it. It can be removed unless you plan to use it, in which case it might be advisable to only assign timer within that function.





                The variable windowHeight appears to be assigned a value but never used. It can be safely removed.





                The variable windowWidth is declared without the var keyword, this it is considered a global variable - actually all the variables outside a function are considered global, so you could limit the scope of all those by moving the whole code into an IIFE.





                The registration of the callback for the window resize event can be simplified from




                $(window).resize(function () {
                windowSize();
                });



                To:



                $(window).resize(windowSize);




                The exclusion of radio inputs could be incorporated into the CSS selector using the :not() CSS pseudo-class instead of the jQuery .not() filter - i.e. instead of




                input = $('input').not('[type=radio]'),



                Use this:



                input = $('input:not([type=radio])'),




                In the isEmpty() method, the statement within the conditional block can be simplified:




                $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');



                Because .removeClass() accepts "One or more space-separated classes to be removed from the class attribute of each matched element."1 the three calls can be simplified to a sing call:



                $(input).removeClass('invalid valid invalid-radio');




                The change handlers for the radio inputs within AddValidationClasses() could be abstracted into a function that accepts a class name for the closest element and made into partial functions via .bind().



                1http://api.jquery.com/removeClass/#removeClass-className






                share|improve this answer














                Some of the variable names seem misleading. For example, input is actually a jQuery collection of elements with the radio inputs excluded, so perhaps nonRadioInputs would be more appropriate. Similarly, radio might be better named as radioInputs, select might be better named as selectInputs, etc.



                Also, some of the method names are confusing. For example, when I read isValid(input) I would expect such a funtion to return a boolean about whether the input is valid or not. The function appears to actually remove a class name and add a class name. A name that would make more sense to me would be something like addValidClassName(). The same is true for inValid(input) and isEmpty(input).





                The function delay() does not appear to be used, though there is a commented line utilizing it. It can be removed unless you plan to use it, in which case it might be advisable to only assign timer within that function.





                The variable windowHeight appears to be assigned a value but never used. It can be safely removed.





                The variable windowWidth is declared without the var keyword, this it is considered a global variable - actually all the variables outside a function are considered global, so you could limit the scope of all those by moving the whole code into an IIFE.





                The registration of the callback for the window resize event can be simplified from




                $(window).resize(function () {
                windowSize();
                });



                To:



                $(window).resize(windowSize);




                The exclusion of radio inputs could be incorporated into the CSS selector using the :not() CSS pseudo-class instead of the jQuery .not() filter - i.e. instead of




                input = $('input').not('[type=radio]'),



                Use this:



                input = $('input:not([type=radio])'),




                In the isEmpty() method, the statement within the conditional block can be simplified:




                $(input).removeClass('invalid').removeClass('valid').removeClass('invalid-radio');



                Because .removeClass() accepts "One or more space-separated classes to be removed from the class attribute of each matched element."1 the three calls can be simplified to a sing call:



                $(input).removeClass('invalid valid invalid-radio');




                The change handlers for the radio inputs within AddValidationClasses() could be abstracted into a function that accepts a class name for the closest element and made into partial functions via .bind().



                1http://api.jquery.com/removeClass/#removeClass-className







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 2 days ago

























                answered Jan 2 at 21:20









                Sᴀᴍ Onᴇᴌᴀ

                8,42261854




                8,42261854






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f79175%2fhtml5-css-live-validation-w-jquery%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Список кардиналов, возведённых папой римским Каликстом III

                    Deduzione

                    Mysql.sock missing - “Can't connect to local MySQL server through socket”