LanguagesJavaScriptValidating Date Entries in Forms

Validating Date Entries in Forms

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

This article is brought to you by Hungry Minds, Inc.
publisher of Danny Goodman’s JavaScript Bible

You may wonder how you can ever perform data entry validation for dates in forms. The problem is not so much in the calculations as it is in the wide variety of acceptable date formats around the world. No matter how well you instruct users to enter dates in a particular format, many will follow their own habits and conventions. Moreover, how can you know whether an entry of 03/04/2002 is the North American March 4, 2002, or the European April 3, 2002? The answer: You can’t.

My recommendation is to divide a date field into three components: month, day, and year. Let the user enter values into each field and validate each field individually for its valid range. Listing 1 shows an example of how this is done. The page includes a form that is to be validated before it is submitted. Each component field does its own range checking on the fly as the user enters values. But because this kind of validation can be defeated, the page includes one further check triggered by the form’s onSubmit event handler. If any field is out of whack, the form submission is canceled.

Listing 1: -Date Validation in a Form

<HTML>
<HEAD>
<TITLE>Date Entry Validation</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
// **BEGIN GENERIC VALIDATION FUNCTIONS**
// general purpose function to see if an input value 
// has been entered at all
function isEmpty(inputStr) {
  if (inputStr == "" || inputStr == null) {
    return true
  }
  return false
}

// function to determine if value is in acceptable range 
//for this application
function inRange(inputStr, lo, hi) {
  var num = parseInt(inputStr, 10)
  if (num < lo || num > hi) {
    return false
  }
  return true
}
// **END GENERIC VALIDATION FUNCTIONS**

function validateMonth(field, bypassUpdate) {
  var input = field.value
  if (isEmpty(input)) {
    alert("Be sure to enter a month value.")
    select(field)
    return false
  } else {
    input = parseInt(field.value, 10)
    if (isNaN(input)) {
      alert("Entries must be numbers only.")
      select(field)
      return false
    } else {
      if (!inRange(input,1,12)) {
         alert("Enter a number between 1 (January) and 12 (December).")
         select(field)
         return false
      }
    }
  }
  if (!bypassUpdate) {
      calcDate()
  }
  return true
}

function validateDate(field) {
  var input = field.value
  if (isEmpty(input)) {
    alert("Be sure to enter a date value.")
    select(field)
    return false
  } else {
    input = parseInt(field.value, 10)
    if (isNaN(input)) {
      alert("Entries must be numbers only.")
      select(field)
      return false
    } else {
      var monthField = document.birthdate.month
      if (!validateMonth(monthField, true)) return false
      var monthVal = parseInt(monthField.value, 10)
      var monthMax = new Array(31,31,29,31,30,31,30,31,
                               31,30,31,30,31)
      var top = monthMax[monthVal]
      if (!inRange(input,1,top)) {
        alert("Enter a number between 1 and " + top + ".")
        select(field)
        return false
      }
    }
  }
  calcDate()
  return true
}

function validateYear(field) {
  var input = field.value
  if (isEmpty(input)) {
    alert("Be sure to enter a year value.")
    select(field)
    return false
  } else {
    input = parseInt(field.value, 10)
    if (isNaN(input)) {
      alert("Entries must be numbers only.")
      select(field)
      return false
    } else {
      if (!inRange(input,1900,2005)) {
        alert("Enter a number between 1900 and 2005.")
        select(field)
        return false
      }
    }
  }
  calcDate()
  return true
}

function select(field) {
  field.focus()
  field.select()
}

function calcDate() {
  var mm = parseInt(document.birthdate.month.value, 10)
  var dd = parseInt(document.birthdate.date.value, 10)
  var yy = parseInt(document.birthdate.year.value, 10)
  document.birthdate.fullDate.value = mm + "/" + dd + "/" + yy
}

function checkForm(form) {
  if (validateMonth(form.month)) {
    if (validateDate(form.date)) {
      if (validateYear(form.year)) {
        return true
      }
    }
  }
  return false
}
//-->
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="birthdate" ACTION="mailto:fun@dannyg.com" METHOD=POST 
    onSubmit="return checkForm(this)">
Please enter your birthdate...<BR>
Month:<INPUT TYPE="text" NAME="month" VALUE=1 SIZE=2 
    onChange="validateMonth(this)">
Date:<INPUT TYPE="text" NAME="date" VALUE=1 SIZE=2 
    onChange="validateDate(this)">
Year:<INPUT TYPE="text" NAME="year" VALUE=1900 SIZE=4 
    onChange="validateYear(this)">
<P>
Thank you for entering:<INPUT TYPE="text" NAME="fullDate" SIZE=10><P>
<INPUT TYPE="submit"> <INPUT TYPE="Reset">
</FORM>
</BODY>
</HTML>

The page shows the three entry fields as well as a field that is normally hidden on a form to be submitted to a CGI program. On the server end, the CGI program responds only to the hidden field with the complete date, which is in a format for entry into, for example, an Informix database.

Not every date entry validation must be divided in this
way. For example, an intranet application can be more demanding in the way users
are to enter data. Therefore, you can have a single field for date entry, but
the parsing required for such a validation is quite different from that shown in
Listing 1. See Chapter 43 of my book, JavaScript Bible, for an example of such a one-field date validation routine, as well as Leap Year and other industrial-strength validation features.



About the Author


Danny Goodman is the author of numerous critcally acclaimed and best-selling books. In
addition to his consulting and designing in the San Francisco area, he is also a renowned
authority and expert teacher of computer scripting languages.



This article is brought to you by Hungry Minds, Inc.
publisher of Danny Goodman’s JavaScript Bible
© Copyright Hungry Minds, All Rights Reserved

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories