6
\$\begingroup\$

I have a really bad habit at the moment with writing global specific functions to handle data and feel like I could reduce my work load by stop copying the same.

Basically I have a registration form that performs in line validation and didn't want to use an external library like jQuery Validate. My validation performs as the user has focused out the box and flags an error if there is one.

So here's some HTML form data:

 <div class="inputs"> 
 <input class="required" type="text" name="first_name" id="register_first_name" />
 <input class="required" type="text" name="last_name" id="register_last_name" />
 <input class="required" type="text" name="email" id="register_email" />
 <input class="required" type="text" name="telephone" id="register_telephone" />
 </div>

Javascript that clears errors:

/** Remove red error_show borders **/
jQuery(document).on('blur keypress change autocompletechange', '#register_first_name', function() {
 jQuery(this).removeClass("error_show");
});
jQuery(document).on('blur keypress change autocompletechange', '#register_last_name', function() {
 jQuery(this).removeClass("error_show");
});
jQuery(document).on('blur keypress change autocompletechange', '#register_email', function() {
 jQuery(this).removeClass("error_show");
});
jQuery(document).on('blur keypress change autocompletechange', '#register_telephone', function() {
 jQuery(this).removeClass("error_show");
});

Javascript that runs functions when data has been entered:

jQuery(document).on( 'blur change autocompletechange', '#register_first_name', function() {
 formatHyphenatedLastname('#register_first_name');
 validFirstname(jQuery("#register_first_name").val());} );
jQuery(document).on( 'blur change autocompletechange', '#register_last_name', function() {
 formatHyphenatedLastname('#register_last_name');
 validLastname(jQuery("#register_last_name").val())
 } ); 
jQuery(document).on( 'blur autocompletechange change', '#register_telephone', function() { 
 uppercaseField('#register_telephone'); 
 collapseSpaces('#register_telephone')
 validTelephone(jQuery("#register_telephone").val());
});
jQuery(document).on( 'blur', '#register_email', function() { lowercaseField('#register_email');
 checkEmail(jQuery("#register_email").val());
 });

Register.js:

function validFirstname(firstname)
{
jQuery(".firstname.input").find(".required").removeClass("valid");
 if(!firstname || firstname.length === 0 )
 }
 else{
 jQuery(".firstname.input").find(".required").addClass("valid");
 }
}
function validLastname(lastname)
{
 jQuery(".lastname.input").find(".required").removeClass("valid");
 if(!lastname || lastname.length === 0 )
 {
 }
 else{
 jQuery(".lastname.input").find(".required").addClass("valid");
 }
}
function formatHyphenatedLastname(field)
{
f=trim(jQuery(field).val());
// first sentance case it
f=sentenceCase(f);
// no sort double barrelled names
if(f.indexOf("-"))
 {
 p=f.indexOf("-");
 f=f.substring(0,p+1)+f.substring(p+1,p+2).toUpperCase()+f.substring(p+2);
 }
// sort mcs and macs
if(f.indexOf("Mc")==0 || (f.indexOf("Mc")==f.indexOf("-Mc")+1) )
 {
 p=f.indexOf("Mc");
 f=f.substring(0,p+2)+f.substring(p+2,p+3).toUpperCase()+f.substring(p+3);
 }
jQuery(field).val(f);
}
function validTelephone(phone)
{
 pattern = /^((\(?0\d{4}\)?\s?\d{3}\s?\d{3})|(\(?0\d{3}\)?\s?\d{3}\s?\d{4})|(\(?0\d{2}\)?\s?\d{4}\s?\d{4}))(\s?\#(\d{4}|\d{3}))?$/i;
 jQuery(".telephone.input").children(".sidetip").find(".active").removeClass("active");
 jQuery(".telephone.input").find(".required").removeClass("valid");
 if(!pattern.test(phone))
 {
 jQuery(".telephone.input").children(".sidetip").children(".invalid").addClass("active");
 }
 else{
 //jQuery(".telephone.input").children(".sidetip").children(".ok").addClass("active");
 jQuery(".telephone.input").find(".required").addClass("valid");
 }
}

As you can see, I'm sort of writing the same function over and over again but checking against different parameters and it's just making the code look really messy and difficult to debug.

I've looked into a module pattern but I just don't know how this can implemented on such individual and specific inputs.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jun 28, 2017 at 10:52
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

By quickly glancing at the code, I think Register.js file is kinda allright. You have lot of code duplication in the first two examples that can be solved with general wrapping function.

You want the shared functionality for the inputs you need to be targeted by class rather than by id's.

You could create general function for removing errors:

function removeError() {
 this.removeClass('error_show');
}

and then just pass this function as callback to all the inputs:

$('input.required').each(function(el, index) {
 el.on('blur keypress change autocompletechange', removeError);
});
answered Jun 28, 2017 at 18:22
\$\endgroup\$
1
  • \$\begingroup\$ With the .each function, can that be ran on document.ready? \$\endgroup\$ Commented Jun 30, 2017 at 9:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.