0

I am trying to validate a form before submitting. The following are the validation constraints:

  • Name, address should not be empty
  • Phone number should be any 10 digit number
  • email should be a valid email address
  • One preference should be selected from the dropdown
  • At-least one hobby should be selected
  • As soon as the user selects a date, His age should be displayed in years and months, right beside the input field

If there are errors in validation, the data should not be submitted and error messages should come up right beside the respective input fields and whatever the user has entered should still be visible (the page should not refresh) so that the user can modify the entry. This is my form.

<form name="f1" action="#" onsubmit="return validateForm()">
  <div class="container">
    <div class="row my-1">
      <div class="col-md-2">
        Name :
      </div>
      <div class="col-md-10">
        <input type="text" name="name" id="name"/>
        <span id="namevald"></span>
      </div>
    </div>
    <div class="row my-1">
      <div class="col-md-2">
        Address :
      </div>
      <div class="col-md-10">
        <textarea name="address" id="address"></textarea>
        <span id="addressvald"></span>
      </div>
    </div>
    <div class="row my-1">
      <div class="col-md-2">
        Phone :
      </div>
      <div class="col-md-10">
        <input type="tel" name="phone" id="phone"/>
        <span id="phonevald"></span>
      </div>
    </div>
    <div class="row my-1">
      <div class="col-md-2">
        Email :
      </div>
      <div class="col-md-10">
        <input type="text" name="email" id="email"/>
        <span id="emailvald"></span>
      </div>
    </div>
    <div class="row my-1">
      <div class="col-md-2">
        Preferences :
      </div>
      <div class="col-md-10">
        <select name="preferences" id="preferences">
          <option value="" selected>Select a preference..</option>
          <option value="pref1">Preference 1</option>
          <option value="pref2">Preference 2</option>
          <option value="pref3">Preference 3</option>
          <option value="pref4">Preference 4</option>
          <option value="pref5">Preference 5</option>
          <option value="pref6">Preference 6</option>
          <option value="pref7">Preference 7</option>
          <option value="pref8">Preference 8</option>
          <option value="pref9">Preference 9</option>
          <option value="pref10">Preference 10</option>
        </select>
        <span id="preferencesvald"></span>
      </div>
    </div>
    <div class="row my-1">
      <div class="col-md-2">
        Hobbies :
      </div>
      <div class="col-md-10">
        <ul>
          <li><label for="chk1"><input type="checkbox" name="chk" id="chk1">First</label></li>
          <li><label for="chk2"><input type="checkbox" name="chk" id="chk2">Second</label></li>
          <li><label for="chk3"><input type="checkbox" name="chk" id="chk3">Third</label></li>
          <li><label for="chk4"><input type="checkbox" name="chk" id="chk4">Fourth</label></li>
          <li><label for="chk5"><input type="checkbox" name="chk" id="chk5">Fifth</label></li>
        </ul>
        <span id="hobbiesvald"></span>
      </div>
    </div>
    <div class="row my-1">
      <div class="col-md-2">
        DOB :
      </div>
      <div class="col-md-10">
        <input type="date" name="date" id="date" onchange="ageCalculate()"/>
        <span id="datevald"></span>
      </div>
    </div>
    <div class="row my-1">
      <div class="col-md-12">
        <input type="submit" value="Submit.."/>
      </div>
    </div>
  </div>
</form>

and this is my javascript

function validateHobbies(){
            var chklist = document.getElementsByName('chk');
            var n = chklist.length;
            for(var i = 0; i < n; i++){
                if(chklist[i].checked) return true;
            }
            return false;
        }
        function validatePreferences(){
            var e = document.getElementByID('preferences');
            return (e.options[e.selectedIndex].value == "")? false : true;              
        }
        function validatePhone(){
            var pat = /\d+$/;
            return (pat.test(document.getElementByID('phone').value))? true : false;
        }
        function validateAddress(){
            return (document.getElementByID('address').value.trim() == "")? false : true;
        }
        function validateName(){
            return (document.getElementByID('name').value.trim() == "")? flase : true;
        }
        function validateEmail(){
            var pat = /^[a-z0-9!#$%&*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
            return (pat.test(document.getElementByID('email').value))? true : false;
        }
        function validateForm(){
            var isNameValid = validateName();
            var isAddressValid = validateAddress();
            var isPhoneValid = validatePhone();
            var isPreferencesValid = validatePreferences();
            var isHobbiesValid = validateHobbies();
            var isEmailValid = validateEmail();
            document.getElementByID('namevald').innerHTML = (isNameValid)? "" : "Name shouldn't be empty";
            document.getElementByID('addressvald').innerHTML = (isAddressValid)? "" : "Address shouldn't be empty";
            document.getElementByID('phonevald').innerHTML = (isPhoneValid)? "" : "Enter valid mobile no";
            document.getElementByID('preferencesvald').innerHTML = (isPreferencesValid)? "" : "Select a preference";
            document.getElementByID('hobbiesvald').innerHTML = (isHobbiesValid)? "" : "Select atleast 1 hobby";
            document.getElementByID('emailvald').innerHTML = (isEmailValid)? "" : "Enter a valid email";
            return (isNameValid && isAddressValid && isPhoneValid && isPreferencesValid && isHobbiesValid && isEmailValid);
        }
        function ageCalculate(){
            var dob = document.getElementByID('date').value.split("-");
            var by = parseInt(dob[0],10);
            var bm = parseInt(dob[1],10);
            var today = new Date();
            var cy = today.getFullYear();
            var cm = today.getMonth();
            var months = (cy-by)*12-bm+cm;
            document.getElementByID('datevald').innerHTML = "" + months/12 + "Years" + months%12 + "Months";
        }

The validation isn't working. Irrespective of the inputs, the form just submits and refreshes. No validation error messages as well. I suspected that the mistake might be either in the onsubmit attribute in the form opening tag or the submit type input at the end, so I've tried event.preventDefault() and multiple other solutions for the form tag and the submit button that i found online but none seem to be working. What exactly is the problem here? Thanks in advance.

Tomasz Mularczyk
  • 34,501
  • 19
  • 112
  • 166
Bhargav Raju
  • 161
  • 1
  • 2
  • 16

3 Answers3

0

So, firstly, you've got a couple of typos in your JavaScript, i.e. getElementByID, be careful with this, it should be getElementById, notice the lowercase D, secondly, you’ve done another typo ‘flase’, it should be false. Here’s the solution I’ve done, I haven't actually changed any of the logic you've implemented, only correct the very minor issues that you had with your code.

I'd personally suggest that whenever submitting a form and doing some stuff in JS, for testing, use preventDefault(). Purely because it doesn't submit the form then, that's why you couldn't see any console errors, it's because it would refresh the page, and you can see that via the url, it would go from (something.html) to (something.html#).

Finally I hope this helps!

function validateHobbies(){
        var chklist = document.getElementsByName('chk');
        var n = chklist.length;
        for(var i = 0; i < n; i++){
            if(chklist[i].checked) return true;
        }
        return false;
    }
    function validatePreferences(){
        var e = document.getElementById('preferences');
        return (e.options[e.selectedIndex].value == "")? false : true;
    }
    function validatePhone(){
        var pat = /\d+$/;
        return (pat.test(document.getElementById('phone').value))? true : false;
    }
    function validateAddress(){
        return (document.getElementById('address').value.trim() == "")? false : true;
    }
    function validateName(){
        return (document.getElementById('name').value.trim() == "")? false : true;
    }
    function validateEmail(){
        var pat = /^[a-z0-9!#$%&*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
        return (pat.test(document.getElementById('email').value))? true : false;
    }
    function validateForm(){
        var isNameValid = validateName();
        var isAddressValid = validateAddress();
        var isPhoneValid = validatePhone();
        var isPreferencesValid = validatePreferences();
        var isHobbiesValid = validateHobbies();
        var isEmailValid = validateEmail();
        document.getElementById('namevald').innerHTML = (isNameValid)? "" : "Name shouldn't be empty";
        document.getElementById('addressvald').innerHTML = (isAddressValid)? "" : "Address shouldn't be empty";
        document.getElementById('phonevald').innerHTML = (isPhoneValid)? "" : "Enter valid mobile no";
        document.getElementById('preferencesvald').innerHTML = (isPreferencesValid)? "" : "Select a preference";
        document.getElementById('hobbiesvald').innerHTML = (isHobbiesValid)? "" : "Select atleast 1 hobby";
        document.getElementById('emailvald').innerHTML = (isEmailValid)? "" : "Enter a valid email";
        return (isNameValid && isAddressValid && isPhoneValid && isPreferencesValid && isHobbiesValid && isEmailValid);
    }
    function ageCalculate(){
        var dob = document.getElementById('date').value.split("-");
        var by = parseInt(dob[0],10);
        var bm = parseInt(dob[1],10);
        var today = new Date();
        var cy = today.getFullYear();
        var cm = today.getMonth();
        var months = (cy-by)*12-bm+cm;
        document.getElementById('datevald').innerHTML = "" + months/12 + "Years" + months%12 + "Months";
    }

    window.onload = function (){
        var frm = document.getElementById("form");
        frm.addEventListener("submit", function(e) {e.preventDefault(); validateForm();});
    };
<form id="form" name="f1" action="#" method="POST">
      <div class="container">
          <div class="row my-1">
              <div class="col-md-2">
                  Name :
              </div>
              <div class="col-md-10">
                  <input type="text" name="name" id="name"/>
                  <span id="namevald"></span>
              </div>
          </div>
          <div class="row my-1">
              <div class="col-md-2">
                  Address :
              </div>
              <div class="col-md-10">
                  <textarea name="address" id="address"></textarea>
                  <span id="addressvald"></span>
              </div>
          </div>
          <div class="row my-1">
              <div class="col-md-2">
                  Phone :
              </div>
              <div class="col-md-10">
                  <input type="tel" name="phone" id="phone"/>
                  <span id="phonevald"></span>
              </div>
          </div>
          <div class="row my-1">
              <div class="col-md-2">
                  Email :
              </div>
              <div class="col-md-10">
                  <input type="text" name="email" id="email"/>
                  <span id="emailvald"></span>
              </div>
          </div>
          <div class="row my-1">
              <div class="col-md-2">
                  Preferences :
              </div>
              <div class="col-md-10">
                  <select name="preferences" id="preferences">
                      <option value="" selected>Select a preference..</option>
                      <option value="pref1">Preference 1</option>
                      <option value="pref2">Preference 2</option>
                      <option value="pref3">Preference 3</option>
                      <option value="pref4">Preference 4</option>
                      <option value="pref5">Preference 5</option>
                      <option value="pref6">Preference 6</option>
                      <option value="pref7">Preference 7</option>
                      <option value="pref8">Preference 8</option>
                      <option value="pref9">Preference 9</option>
                      <option value="pref10">Preference 10</option>
                  </select>
                  <span id="preferencesvald"></span>
              </div>
          </div>
          <div class="row my-1">
              <div class="col-md-2">
                  Hobbies :
              </div>
              <div class="col-md-10">
                  <ul>
                     <li><label for="chk1"><input type="checkbox" name="chk" id="chk1">First</label></li>
                     <li><label for="chk2"><input type="checkbox" name="chk" id="chk2">Second</label></li>
                     <li><label for="chk3"><input type="checkbox" name="chk" id="chk3">Third</label></li>
                     <li><label for="chk4"><input type="checkbox" name="chk" id="chk4">Fourth</label></li>
                     <li><label for="chk5"><input type="checkbox" name="chk" id="chk5">Fifth</label></li>
                  </ul>
                  <span id="hobbiesvald"></span>
              </div>
          </div>
          <div class="row my-1">
              <div class="col-md-2">
                  DOB :
              </div>
              <div class="col-md-10">
                  <input type="date" name="date" id="date" onchange="ageCalculate()"/>
                  <span id="datevald"></span>
              </div>
          </div>
          <div class="row my-1">
              <div class="col-md-12">
                  <input type="submit" value="Submit.."/>
              </div>
          </div>
      </div>
  </form>
JO3-W3B-D3V
  • 2,124
  • 11
  • 30
0

The issues were that you were incorrectly getting the ids with:

document.getElementByID

instead of:

document.getElementById

If you had your Developer's Tools (F12 in any browser) and were looking at the Console tab, you would have seen errors pointing this out. Always check the Console first when your JavaScript isn't working.

And, you had a typo with false in the validateName function where you wrote flase instead.

But, beyond that, your overall code is more involved than it needs to be and it needs to be brought into the 21st century, so....

First, stop using the 25+ year old inline HTML event attribute (onclick, onsubmit, etc.) technique for setting up event handlers. There are many reasons not to use this ancient technique that just will not die. Instead, follow modern standards and do all event handling in JavaScript with .addEventListner(). This means that you will cancel events differently that you have been doing.

All DOM event handling functions are automatically passed a reference to the event that triggered them, so your validateForm() function should be set up to receive that reference like this:

function validateForm(evt){

Then, during your validation code, if you come to a point where you know the form is invalid, you would cancel that event:

evt.preventDefault();

We can clean up the code a bit by not bothering to give most of the span elements that will show error messages an id and just access them via code by their position next to the element being validated with nextElementSibling. Also, we can clean up the code even more by getting rid of the trailing slashes on your input elements as that is also an ancient syntax that gives you no benefits and often leads to bugs in the code.

Now, you did use label elements next to your checkboxes, but they really should be used next to all elements for accessibility.

Lastly, your code for calculating the age is much more involved than needed.

I've cleaned up the HTML and the JavaScript quite a bit, so take a look at the comments for explanations:

// Get the DOM references you'll need just once:
var frm = document.querySelector("form[name='f1']")   
var dob = document.querySelector("input[type=date]"); 
var userName = document.getElementById('userName');
var address = document.getElementById('address');
var phone = document.getElementById('phone');
var email = document.getElementById('email');
var preferences = document.getElementById('preferences');
var hobbies = document.getElementById('hobbiesvald');
var dateValid = document.getElementById('datevald');

// We will want to loop over these later and to be sure the .forEach loop
// works in all browsers, we convert the node list into an Array
var errorMessages = Array.prototype.slice.call(document.querySelectorAll(".error"));

// Set up event handlers:
frm.addEventListener("submit", validateForm); 
dob.addEventListener("change", ageCalculate);

// You really don't need separate functions to validate each form field given
// how simple those validations were:
function validateForm(evt){
  // Reset all error messages:
  errorMessages.forEach(function(msg){
    msg.textContent = "";
  });
  hobbies.textContent = "";

  var valid = true;  // Assume that everything is valid to start with
  
  if(userName.value.trim() === ""){
    // Since the error message should appear in the next element that comes after
    // the form field, we can reference it with: nextElementSibling
    userName.nextElementSibling.textContent = "Name shouldn't be empty";
    valid = false;
  }
  
  if(address.value.trim() === ""){
    address.nextElementSibling.textContent = "Address shouldn't be empty";
    valid = false;
  }
  
  if(!/\d+$/.test(phone.value)){
    phone.nextElementSibling.textContent = "Enter valid mobile no";
    valid = false;  
  }

  var pat = /^[a-z0-9!#$%&*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;

  if(!pat.test(email.value)){
    email.nextElementSibling.textContent = "Enter a valid email";
    valid = false;    
  }  
  
  if(preferences.value === ""){
    preferences.nextElementSibling.textContent = "Select a preference";
    valid = false;  
  }
  
  // Just get the checked checkboxes
  var chklist = document.querySelectorAll('input[type=checkbox]:checked');    
  
  // And if none were found, validation fails  
  if (chklist.length === 0){
   hobbies.textContent = "Select atleast 1 hobby";
   valid = false;
  }  

  // If any of the tests failed, cancel the submit
  if(!valid){ evt.preventDefault(); }
}

function ageCalculate(evt){
  if(this.value){
    var ddif = new Date(new Date() - new Date(this.value));
    var message = 
      (ddif.toISOString().slice(0, 4) - 1970) + " Years " + 
      (ddif.getMonth()+1) + " Months " + ddif.getDate() + " Days old";
  
    dateValid.textContent = message;
  } else {
    dateValid.textContent = "";
  }
}
.error { color:red; font-weight:bold; }
<form name="f1" action="#">            
  <div class="container">
    <div class="row my-1">
      <div class="col-md-2"><label for="userName">Name :</label></div>
        <div class="col-md-10">
           <input type="text" name="userName" id="userName"><span class="error"></span>
         </div>
      </div>
      <div class="row my-1">
        <div class="col-md-2"><label for="address">Address :</label></div>
        <div class="col-md-10">
          <textarea name="address" id="address"></textarea><span class="error"></span>
        </div>
        </div>
        <div class="row my-1">
          <div class="col-md-2"><label for="phone">Phone :</label>
        </div>
        <div class="col-md-10">
          <input type="tel" name="phone" id="phone"><span class="error"></span>
        </div>
      </div>
      <div class="row my-1">
        <div class="col-md-2"><label for="email">Email :</label></div>
        <div class="col-md-10">
          <input type="text" name="email" id="email"><span class="error"></span>
        </div>
      </div>
      <div class="row my-1">
        <div class="col-md-2"><label for="preferences">Preferences :</label></div>
        <div class="col-md-10">
          <select name="preferences" id="preferences">
            <option value="" selected>Select a preference..</option>
            <option value="pref1">Preference 1</option>
            <option value="pref2">Preference 2</option>
            <option value="pref3">Preference 3</option>
            <option value="pref4">Preference 4</option>
            <option value="pref5">Preference 5</option>
            <option value="pref6">Preference 6</option>
            <option value="pref7">Preference 7</option>
            <option value="pref8">Preference 8</option>
            <option value="pref9">Preference 9</option>
            <option value="pref10">Preference 10</option>
          </select><span  class="error"></span>
        </div>
      </div>
      <div class="row my-1">
        <div class="col-md-2">Hobbies :</div>
           <div class="col-md-10">
              <ul>
                <li><label for="chk1"><input type="checkbox" name="chk" id="chk1">First</label></li>
                <li><label for="chk2"><input type="checkbox" name="chk" id="chk2">Second</label></li>
                <li><label for="chk3"><input type="checkbox" name="chk" id="chk3">Third</label></li>
                <li><label for="chk4"><input type="checkbox" name="chk" id="chk4">Fourth</label></li>
                <li><label for="chk5"><input type="checkbox" name="chk" id="chk5">Fifth</label></li>
              </ul>
              <span id="hobbiesvald" class="error"></span>
            </div>
          </div>
          <div class="row my-1">
             <div class="col-md-2"><label for="date">DOB :</label></div>
              <div class="col-md-10">
                <input type="date" name="date" id="date"><span id="datevald"></span>
              </div>
            </div>
            <div class="row my-1">
              <div class="col-md-12">
                <input type="submit" value="Submit..">
              </div>
            </div>
        </div>
    </form>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Thank you for the detailed explanation. A couple of questions. Why is .textContent preferred over innerHTML? When exactly should one use the label tag and how is it different from and

    tags?

    – Bhargav Raju Feb 05 '18 at 17:51
  • @BhargavRaju `.innerHTML` is for when the string you are setting contains HTML that needs to be parsed by the browser. If there is no HTML in the string (as is the case here), it's more efficient to use `.textContent`, which just sets the text without having the HTML parser parse the string. – Scott Marcus Feb 05 '18 at 18:17
  • @BhargavRaju I found an omission and a small typo in my solution and have updated the answer to address it. – Scott Marcus Feb 05 '18 at 18:30
-2

You can use HTML5 to validate the form. Just add required to the input tags. For email validation you have to add the type attribute with "email" as value.

<input type="email" name="email" required />
Alex
  • 1
  • The OP has said that he wants error message to appear next to the fields that are not valid, so custom JavaScript will be required. – Scott Marcus Feb 05 '18 at 13:32
  • The most browsers returning error messages if the field isn't valid. You can also customize it. – Alex Feb 05 '18 at 13:36
  • But, the message does not appear directly next to the element and, if you want to customize the message, then you need JavaScript. – Scott Marcus Feb 05 '18 at 13:37