Birdlady9604
Birdlady9604

Reputation: 207

Form validation not displaying message

I am trying to get my javascript to validate the phone number input and display messages when user enters information incorrectly. I have two other inputs set up that do this so I copied one of them and just replaced the name with phoneNumber but no result. No HTML alternatives please it is compulsory for me to use this for my assessment.

Here I have included code for only the phone number input. http://jsfiddle.net/29ZNV/

HTML

    <form>
        <label for="phoneNumber"><span class="textStyle">Phone Number*</span>
        <input type="text" id="phoneNumber"><br>
        <span id="phoneMessage" class="message">You must have a valid phone number</span>
         </label>
<input type="submit" id="submit" value="Submit"/>
</form>

JAVASCRIPT

var phoneInput = document.querySelector ('#phoneNumber');
var submitButton = document.querySelector('#submit');

function displayError(fieldname, message) {
    var input_field = document.querySelector('#' + fieldname);
    var error_box = document.querySelector('#' + fieldname + 'Message');

    addClass (input_field, 'error');
    error_box.style.display = 'block';

    error_box.innerHTML = message;
}

function hideError(fieldname){
    var input_field = document.querySelector('#'+fieldname);
    var error_box = document.querySelector('#'+fieldname+'Message');
    removeClass (input_field, 'error');
    error_box.style.display = 'none';
}

function addClass(html_element,class_str) {
    if(html_element.className.indexOf(class_str) == -1){
        html_element.className += ' '+class_str;
    }
}

function removeClass(html_element, class_str){
    if(html_element.className.indexOf(class_str) != -1){
        html_element.className = html_element.className.replace(class_str, '');
    }
}

  phoneInput.onblur = function(){
    if(!phoneNumberInput.value){
     valid = false;        
    displayError('phoneNumber', 'Please enter your number');
    }else if(!isValidPhoneNumber(phoneNumberInput.value)){
    valid = false; 
    displayError('phoneNumber', 'The phone number field is invalid');
    }else{
        hideError('phoneNumber');
    }
}


submitButton.onclick = function(){
    var nameIsValid = checkName();
    var emailIsValid = checkEmail();
    var phoneNumberIsValid = checkphoneNumber();

    var valid = nameIsValid && emailIsValid && phoneNumberIsValid;
    return valid;
 }

function isValidPhoneNumber(str){
    var phoneNumberPattern = new RegExp('^[a-zA-Z \s\'-]{1,}$');
}

Upvotes: 0

Views: 667

Answers (3)

wvandaal
wvandaal

Reputation: 4295

You've got quite a lot going on in your code. I've taken the liberty of cleaning it up some and simplifying your validation logic to allow for greater extensibility. You can view the entire working code here, but the gist is as follows:

HTML:
Rather than showing and hiding an error message for each field, consider using an unordered list to display error messages. This practice is quite common and can greatly simplify both you HTML and JS:

<form>
  <ul class="errors"></ul>
  <label for="phone_number">*Phone Number
    <input name="phone_number" type="text"/>
  </label>
  <br>
  <input type="submit"/>
</form>

JavaScript:
This is where the heart of your validation logic lies. You can, as others have mentioned, use HTML5 attributes to validate your data, but this lacks cross-browser compatibility and is vulnerable to manipulation by the user (although the latter point is also true of JS validations; you should always validate on the server side too to be safe)

window.onload = function() {
  var form = document.querySelector('form');

  // listen for the form submission
  form.addEventListener('submit', validate, false);

  function validate(e) {
    var errors  = {},
        valid   = true,
        errorUL = document.querySelector('.errors'),
        node;

    // clear the errors list
    errorUL.innerHTML = '';

    // iterate through the inputs and validate each one using
    // a case statement
    [].forEach.call(e.target, function(input) {
      switch (input.name){
        case 'phone_number':
          if (!validPhoneNumber(input.value)) {
            // add the appropriate error message to the errors object
            errors[input.name] = "Phone number is not valid";
            valid = false; // set the 'valid' flag to false
          }
        // Add more case statements as you need them
        // Example:
        // case 'home_address': 
        // ...
      }
    });

    // if the form is invalid
    if (!valid) {
      // prevent the submission
      e.preventDefault();

      // loop through the errors and add the messages to the errorUL
      for (e in errors) {
        node = document.createElement('li');
        node.innerHTML = errors[e];
        errorUL.appendChild(node);
      }
    }
  }

  // This function will return the validated phone number or null
  // You may want to use this function to convert your phone number
  // string to an integer. This function will accept phone numbers 
  // in the following forms:
  //
  // 123.456.7890
  // 1234567890
  // (123)456-7890
  // (123)-456-7890
  // 123-456-7890
  // 123 456 7890
  function validPhoneNumber(n) {
    var r = /^\(?(\d{3})\W{0,2}(\d{3})\W?(\d{4})$/,
        match = r.exec(n);

    // if the phone number is valid, return the number as an int
    // if the number is invalid, return null
    return match ? match.slice(1).join('')|0 : null;
  }
}

The above JS does several things:

  1. It queries the <form> element and adds an event listener for the 'submit'. This is preferable to listening to using the onclick listener because it allows you to access the form directly, as well as the inputs and their values.
  2. The event listener attaches the validate function as your event handler. This function will serve to iterate over the various inputs in your form (assuming you have multiple inputs) and validate each one. You will notice that I have used a switch statement to process the various inputs by their name attribute. This allows you to add additional validations easily as you add new inputs. For more information about how a switch statement works, check out the documentation.
  3. After all of the inputs have been validated, the validate function will check to see if the valid flag is true or false. If the form is invalid (i.e. valid = false), each error message will be wrapped in an <li> tag and appended to <ul class='errors'>.
  4. The validPhoneNumber(n) function takes the user's inputted phone number and checks to see if it is valid using a RegEx. If the number is valid, it will be returned in integer form; if not, the function will return null instead. You can choose to use this function to standardize the format of your users' phone numbers as integers if you so choose.

Hopefully this will give you a sense of a good way to validate HTML forms with JS. Always keep in mind however that no amount of client-side validation is a substitute for validations on your server.

Upvotes: 0

Joeytje50
Joeytje50

Reputation: 19112

Note: This answer is purely intended as an alternative solution to form validation

It is very easy to do this with HTML5 input types. In this case, you could very easily use the following:

<form>
    <label for="phoneNumber">
        <span class="textStyle">Phone Number*</span>
        <input type="tel" pattern="((\+|00)[0-9]{2}|0)[ -]*[1-9]([ -]*[0-9]){8}" id="phoneNumber">
    </label>
    <button id="submit">Submit</button>
</form>

That's everything. No JavaScript required. Just look at this demo (which also has CSS highlighting for validity included).

That pattern will permit 10 numbers with or without spaces or dashes between them, or the country code prefix with either +10 or 0010 when trying to enter an example country code 10. test this regex.

This will work in all modern browsers, but not in some older browsers. MDN says this is only supported in IE10+, and it's not supported in Safari. Other browsers support it, except for their older versions which are barely used anymore.

Upvotes: 0

Josh M
Josh M

Reputation: 992

It looks like you just put phoneMessage instead of phoneNumberMessage in this line:

<span id="phoneNumberMessage" class="message">You must have a valid phone number</span>

Upvotes: 1

Related Questions