0

This seems like a problem I just cant fix, I'm working on a form that needs to validate the field on change, If a field isn't valid I want the wrap to display red and add a red border around the inupt field so the user is aware what section of the form is currently invalid and what input isn't correct.

If anyone can help me I'd truly appreciate it. I've attached my js,html and screen shots, I'm working on woocommerce and wordpress. If anyone can help me fix this i'll be more than happy to help return the favour.

JS

$('form.cart')

        /* start ! This section adds & removes red backgroud and border */
        .on( 'blur change', '.input-text', function() {
                $(".single-attendee-wrapper .input-text").each(function(){
                        var $this = $(this);
                        var validated = true;

                        if ( $(this) ) {
                                if ( $this.val() == '' ) {
                                        $(".single-attendee-wrapper .count").css('background','#ED616A');
                                        $(".single-attendee-wrapper .count").css('color','#fff');
                                        validated = false;
                                }
                        }
                        if ( validated ) {
                                        $(".single-attendee-wrapper .count").css('background','#D1D3D4');
                                        $(".single-attendee-wrapper .count").css('color','#808285');
                        }

                });
        } )
        /* This section adds & removes red backgroud and border ! Finish */




        .on( 'blur change', '.input-text, select', function() {
                var $this = $(this);
                var $parent = $this.closest('.form-row');
                var validated = true;

                if ( $parent.is( '.validate-required' ) ) {
                        if ( $this.val() == '' ) {
                                $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-required-field' );
                                validated = false;
                        }
                }

                if ( $parent.is( '.validate-email' ) ) {
                        if ( $this.val() ) {

                                /* http://stackoverflow.com/questions/2855865/jquery-validate-e-mail-address-regex */
                                var pattern = new RegExp(/^((([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+(.([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+)*)|((")(((( |   )*(
))?( |  )+)?(([--]|!|[#-[]|[]-~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(\([-     
-]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))))*((( |       )*(
))?( |  )+)?(")))@((([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))).)+(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))).?$/i);

                                if ( ! pattern.test( $this.val()  ) ) {
                                        $parent.removeClass( 'woocommerce-validated' ).addClass( 'woocommerce-invalid woocommerce-invalid-email' );
                                        validated = false;
                                }
                        }
                }

                if ( validated ) {
                        $parent.removeClass( 'woocommerce-invalid woocommerce-invalid-required-field' ).addClass( 'woocommerce-validated' );
                }
        } )

HTML

<form enctype="multipart/form-data" method="post" class="cart" action="/hardy-group/product/manual-handling-3/?add-to-cart=414" style="background: none repeat scroll 0% 0% transparent;">
<h3 class="addon-name">One Attendee </h3>
                <p class="form-row form-row-wide addon-wrap-414-one-attendee woocommerce-validated validate-required">
                        <label>Candidate Name </label> <input type="text" value="" name="addon-414-one-attendee-candidate-name" data-price="" class="input-text addon addon-custom" style="border-top: 0px none;">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-one-attendee woocommerce-validated validate-required">
                        <label>Address </label> <input type="text" value="" name="addon-414-one-attendee-address" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-one-attendee validate-required woocommerce-validated">
                        <label>Candidate Email </label> <input type="text" value="" name="addon-414-one-attendee-candidate-email" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-one-attendee validate-required woocommerce-invalid woocommerce-invalid-required-field">
                        <label>Phone </label> <input type="text" value="" name="addon-414-one-attendee-phone" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-one-attendee validate-required woocommerce-invalid woocommerce-invalid-required-field">
                        <label>N.I Number </label> <input type="text" value="" name="addon-414-one-attendee-n-i-number" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-one-attendee validate-required woocommerce-invalid woocommerce-invalid-required-field">
                        <label>EUSR Number </label> <input type="text" value="" name="addon-414-one-attendee-eusr-number" data-price="" class="input-text addon addon-custom">
                </p>

        <div class="clear"></div>
</div>
<div class="count item1" style="background: none repeat scroll 0% 0% rgb(237, 97, 106); color: rgb(255, 255, 255);">1</div></div><div class="single-attendee-wrapper item2"><div class=" product-addon product-addon-two-attendees" style="display: block;">

<h3 class="addon-name">Two Attendees </h3>
                <p class="form-row form-row-wide addon-wrap-414-two-attendees validate-required woocommerce-validated">
                        <label>Candidate Name </label> <input type="text" value="" name="addon-414-two-attendees-candidate-name" data-price="" class="input-text addon addon-custom" style="border-top: 0px none;">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-two-attendees validate-required woocommerce-validated">
                        <label>Address </label> <input type="text" value="" name="addon-414-two-attendees-address" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-two-attendees woocommerce-validated validate-required">
                        <label>Candidate Email </label> <input type="text" value="" name="addon-414-two-attendees-candidate-email" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-two-attendees validate-required woocommerce-validated">
                        <label>Phone </label> <input type="text" value="" name="addon-414-two-attendees-phone" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-two-attendees woocommerce-validated validate-required">
                        <label>N.I Number </label> <input type="text" value="" name="addon-414-two-attendees-n-i-number" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-two-attendees woocommerce-validated validate-required">
                        <label>EUSR Number </label> <input type="text" value="" name="addon-414-two-attendees-eusr-number" data-price="" class="input-text addon addon-custom">
                </p>
        <div class="clear"></div>
</div><div class="count item2" style="background: none repeat scroll 0% 0% rgb(237, 97, 106); color: rgb(255, 255, 255);">2</div></div><div class="single-attendee-wrapper item3"><div class=" product-addon product-addon-three-attendees" style="display: block;">

<h3 class="addon-name">Three Attendees </h3>
                <p class="form-row form-row-wide addon-wrap-414-three-attendees woocommerce-validated validate-required">
                        <label>Candidate Name </label> <input type="text" value="" name="addon-414-three-attendees-candidate-name" data-price="" class="input-text addon addon-custom" style="border-top: 0px none;">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-three-attendees woocommerce-validated validate-required">
                        <label>Address </label> <input type="text" value="" name="addon-414-three-attendees-address" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-three-attendees woocommerce-validated validate-required">
                        <label>Candidate Email </label> <input type="text" value="" name="addon-414-three-attendees-candidate-email" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-three-attendees woocommerce-validated validate-required">
                        <label>Phone </label> <input type="text" value="" name="addon-414-three-attendees-phone" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-three-attendees woocommerce-validated validate-required">
                        <label>N.I Number </label> <input type="text" value="" name="addon-414-three-attendees-n-i-number" data-price="" class="input-text addon addon-custom">
                </p>
                <p class="form-row form-row-wide addon-wrap-414-three-attendees validate-required woocommerce-invalid woocommerce-invalid-required-field">
                        <label>EUSR Number </label> <input type="text" value="" name="addon-414-three-attendees-eusr-number" data-price="" class="input-text addon addon-custom">
                </p>

        <div class="clear"></div>
</div><div class="count item3" style="background: none repeat scroll 0% 0% rgb(237, 97, 106); color: rgb(255, 255, 255);">3</div></div><div class=" product-addon product-addon-four-attendees" style="display: none;">

</div><div data-price="29.99" data-type="simple" id="product-addons-total"></div>
                <div class="quantity buttons_added"><input type="button" class="minus" value="-"><div class="quantity-wrapper" style="display: none;"><label>Number of attendees</label><input type="number" class="input-text qty text" title="Number of attendees" value="1" name="quantity" min="1" step="1"></div><input type="button" class="plus" value="+"></div>

                <button class="single_add_to_cart_button button alt" type="submit" style="display: inline-block;">Place Booking</button>        
        </form>

enter image description here

Delete
  • 429
  • 1
  • 6
  • 25

2 Answers2

1

Basically u can use jQuery Plugin http://jqueryvalidation.org/

But if you want you own validation.. Create a separe function that will be called on key up that you will pass the .val() and id or class check it you can read more here: http://www.w3schools.com/jsref/event_onkeyup.asp

So when you pass the .val() in function you will have if state check the value and after add clas to that id:

if(value == true){
   id.addClass('green);
}else{
   id.addClass('red');
}

css

.green{border: 1px solid green;}
.red {border: 1px solid red;}

Example:

<input type="password" id="pass" name="pass" class="vpb" onkeyup="return return check_password_safety(this.value);">
function check_password_safety(safe){
var msg = "";
var pas_safe = $("#pass").val();
var points = pas_safe.length;
var password_info = document.getElementById('password_info'); //output message div


var has_letter      = new RegExp("[a-z]");
var has_caps        = new RegExp("[A-Z]");
var has_numbers     = new RegExp("[0-9]");
var has_symbols     = new RegExp("\\W");

if(has_letter.test(pas_safe))    { 
    points += 4; }
if(has_caps.test(pas_safe))      { 
    points += 4; }
if(has_numbers.test(pas_safe))   {
 points += 4; }
if(has_symbols.test(pas_safe))   {
 points += 4; }


if( points >= 24 ) {
    msg = '<span style="color: rgb(7, 134, 27);"><b>Strong!</b></span>';
} else if( points >= 16 ) {
    msg = '<span style="color: rgb(0, 112, 255);"><b>Good!</b></span>';
} else if( points >= 12 ) {
    msg = '<span style="color: #fa0;"><b>Not Safe!</b></span>';
}
else if(pas_safe == ''){
    msg ='';
}
 else {
    msg = '<span style="color: #f00;"><b>Very poor!</b></span>';
}


password_info.innerHTML = msg ;
}

I pass only the value but you can pass also ID of element.

SergkeiM
  • 3,934
  • 6
  • 36
  • 69
  • Would you be able to advice me on how to write this into my js ? I'm just struggling with this problem... – Delete Sep 09 '13 at 09:48
0

As far as I can see, there are a few issues with your code. I will go through some of the main ones.

You have two event listeners

.on( 'blur change', '.input-text', function(){} 

and

.on( 'blur change', '.input-text, select', function() {}

This is binding a listener on blur/change of .input-text twice. Not so much of a problem but potentially not needed. Also there are no selects in your example, not sure if this is a mistake or just not included in your example code. Also the first field group is not contianed within a wrapper with the single-attendee-wrapper class (not sure if intended or not but will not work with your current selectors in first listener).

First event listener

As far as I can tell the first event listener you have is trying to loop over all fields and check if empty, if there are any empty fields, you are wanting to show the count field in in a grey-ish colour, otherwise if all filled in, show in a red colour.

The first problem with this is that you are using jQuery selectors $(".single-attendee-wrapper .count").css() multiple times in each loop. This selector is matched twice for every field in the form, this should be cached as it won't change, then you can mass add CSS to the selector, or it is better to just use .addClass, even if you have 1 or more CSS rules. More maintainable and readable, just add the class style to your CSS.

Second issue is that, as you are applying the CSS to every $(".single-attendee-wrapper .count").css() in every cycle of the .each loop, it will only actually work against the last field in the whole form, as this is the last one that is checked in the .each loop. Try it with your code and only the empty validation if statement and you'll see it only validates it against the last EUSR Number field.

Also it does it for all single-attendee-wrapper blocks together not separately, assuming you want to validate the blocks separately. You can do this by selecting the current fields closest parent single-attendee-wrapper then the each loop can be run only for those fields in that block.

For the actual validation, what you want to do is loop through all the fields and check if valid, if not set the border of the individual field to red $(this).css('border', 'red 1px solid') say and if valid set it back to its default grey $(this).css('border', 'grey 1px solid'). or better $(this).addClass('itemError');

.itemError{
    border: red 1px solid;
}

As well as this you want to use your validated flag and then set it to false if any one of the fields is not valid, then you apply the styles to the block AFTER the .each loop. This way if any of the fields are invalid, the groupValid flag will trigger this (not just for the last field).

Second event listener

As there are no selects in your code, this is simply doing the same as the first event listener in theory, perhaps consider combining the two. You can split out the processing of these into separate functions and call the functions to keep it clean and clear.

for example:

.on( 'blur change', '.input-text, select', function() {
  validationFunction1();
  validationFunction2($this);
}

The second event listener as far as I can tell is trying to then check the validation of the individual field. And from testing your code, seems to work, except you do not have a .validate-email class on your email fields. Also chromes inspector is complaining about your regex function, so you may need to review that once you get it working.

As your first event listener is triggering for an individual field anyway you could combine here adding this functionality to the first event listener by running a validation function for the field if it has a certain class, that way it is tied to the first validation function. say using the .hasClass jQuery function.

Solution for first event listener

I have quickly addressed the issues I raised about the first event listener and created a fiddle with my recommended changes:

Fiddle

Hopefully my suggestions for the second event listener can help you re-factor to complete the second stage of validation you require.

lee_gladding
  • 1,090
  • 6
  • 10