Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

How do I enable my submit button? WARNING: Messy code

Hi there,

I am currently building a contact form's client side validation using jQuery. I started this straight after I finished the jQuery Basics course to try and retain the knowledge a little, but the code is not great so please forgive me :P.

So basically I am trying to enable a form's submit button after all form fields have been entered correctly. Here is all of the code for the validation form:

/*************************
  CONTACT FORM VALIDATION
*/////////////////////////

// Check Length of Name and Message Fields
function checkLength() {
  if($(this).val().length < 1) {
    $(this).next().show();
  } else {
    $(this).next().hide();
  }
}

// Check if email is valid
function validateEmail(email) {
   var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
   return emailReg.test(email);
}

$('#email').keyup(function() {
  if(validateEmail($('#email').val())) {
    $(this).next().hide();
  } else {
    $(this).next().show();
  }
});

// Length Check Calls
$('#name').keyup(checkLength);
$('#message').keyup(checkLength);
// $('#email').keyup(checkLength);

function checkIfHidden() {
  return $("#errorname").is(':hidden');
}

function enableSubmitEvent() {
  if(checkIfHidden()) {
    $('#submit').prop('disabled', false);
  } else {
    $('#submit').prop('disabled', true);
  }
}

enableSubmitEvent();

... and here is the snippet I am working on so far:

function checkIfHidden() {
  return $("#errorname").is(':hidden');
}

function enableSubmitEvent() {
  if(checkIfHidden()) {
    $('#submit').prop('disabled', false);
  } else {
    $('#submit').prop('disabled', true);
  }
}

enableSubmitEvent();

Basically what I am trying to say here is that if the #errorname id (which is just an error message span I have created in the HTML) is hidden, return true and make the submit button false (which makes it clickable) and if not make the button true.

Incase you are wondering why I haven't included both the email and message field on the return statement in the checkIfHidden() function, it was just because I wanted to test the #errorname first, so it seemed pretty pointless to add them in too if I can't get past the first part.

I have been stuck on this bug for so long and I am unsure how to solve it (which actually leads onto my next question, does debugging JS/jQuery covered at the end of the Front End track?)

Please let me know where I am going wrong and how I should mitigate it. Or if I need to provide more information let me know.

I look forward to the answers!

Thanks, James.

Steven Parker
Steven Parker
243,331 Points

A complete working model would help greatly in identifying the issue. Do you have a codepen, jsfiddle, or snapshot of a Treehouse workspace?

BTW, your code is cleaner than average, PLUS it's properly formatted for the forum! :+1:

Hi Steven,

Thanks for the reply. I have put everything into this JS Fiddle for you:

https://jsfiddle.net/k2m7s774/

Thanks, James.

2 Answers

Steven Parker
Steven Parker
243,331 Points

:point_right: It looks like you're missing a call to enableSubmitEvent().

It always helps to see the whole picture. I would not have guessed that "$(this).next()" in checkLength was the same thing as "$("#errorname")".

The enableSubmitEvent() function in your snippet is fine, but it isn't called on any events. In this case, it should be called at the end of checkLength to set the button status according to the (potentially changed) state of the error message. You'll probably want to call it at the end of the email keyup handler at some point also.

Also, I found it helpful to be able to see the state of the button, so I added this to the CSS:

button:disabled {
    background-color: gray;
    border-color: gray;
}

And unless you intend to change enableSubmitEvent, it could be made more compact like this:

function enableSubmitEvent() {
  $('#submit').prop('disabled', !checkIfHidden());
}

Happy coding!   -sp:sparkles:

Awesome! Thanks so much for the answer. I had another problem too, which I fixed but I am not really sure why, view my other answer for the code!

function validateEmail(email) {
   var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
   if(emailReg.test(email)) {
     $('#erroremail').hide();
     console.log("hi");
   } else {
     $('#erroremail').show();
   }
}

$('#email').keyup(validateEmail($('#email').val())).focus(validateEmail($('#email').val()));

This was my original code. Which didn't work for some reason. the console.log() would trigger TWICE every time the page had loaded. So I tried this:

$('#email').keyup(function(){
    validateEmail(
      $('#email').val()
    ).focus(
      validateEmail($('#email').val()
    ));
  });

...which worked fine. But I am not sure why? Why does creating an anonymous keyup function before the function call work?

Thanks, James.

Steven Parker
Steven Parker
243,331 Points

In the first example, you are calling the validateEmail function twice, once to pass its result to keyup and again to pass the result to focus.

It looks like you realized part of the issue and corrected the argument to keyup by wrapping it with an anonymous function. You still need to apply that same correction to focus, and you probably want to establish the focus handler at the same time as the keyup hander (instead of cascading it from validateEmail inside the keyup handler):

$('#email').keyup(function() {
    validateEmail($('#email').val())
  }).focus(function() {
    validateEmail($('#email').val())
  });