SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Zealot
    Join Date
    Oct 2010
    Posts
    167
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Form Date Validation Help

    Hi there,

    I have a HTML Form which needs to be submitted to an order page so a user can order a personalized product. I have everything working except for the date validation for the form. I need to be able to check the Date of Birth they are entering is a valid date. That means I need to check for Leap Years so they can't enter 29th Feb on a non leap and I also need to check for the month so they cannot enter more than 30 for months where there is no 31.

    I have the following piece of javascript:

    Code JavaScript:
    <script type="text/javascript"> 
     
    var month = document.validateDate.month.value;
    var day = document.validateDate.day.value;
    var year = document.validateDate.year.value;
     
     
     
    function validDate( month, day, year) 
    { 
       // Test for leap year 
        if ((year % 400 == 0) || (year % 4 == 0) &&                 
           !(year % 100 == 0)) 
              leap = true; 
        else 
              leap = false; 
     
        // Validate date                              // Assume a valid date-test otherwise
        if (year < 1900 || year > 2050)               // year must be four digits and      
            return false;                             //     within reasonable range 
        else if ((month < 1) || (month > 12) ||       // test general date and month range 
                 (day < 1) || (day > 31)) 
            return false;      
        else if (((month == 4) || (month == 6) ||     // test 30 Day months 
                  (month == 9) || (month == 11)) && (day == 31)) 
            return false;      
        else if (month == 2 && leap && day > 29)      // test February leap years 
            return false;          
        else if (month == 2 &&  !leap && day > 28)    // test February NON-leap years 
            return false;          
        else 
            return true;                              // otherwise, date is OK 
     
    } 
    </script>

    Now I need to invoke it. And this is where the problem lies... I actually have 2 dates of birth to collect and I need to validate both of them when I submit the form.

    This is the form:

    Code HTML4Strict:
    <form name="customize_report" action="/community/user/astro-cr-payment" method="post">
    <div class="first-name-1">
    <label class="first-name-1">Your First Name</label> <input type="text" id="first_name_1" name="first_name_1" size="20" style="margin-left:15px;" />
    </div>
    <div class="last-name-1">
    <label class="last-name-1">Your Last Name</label> <input type="text" id="last_name_1" name="last_name_1" size="20" />
    </div>
    <br />
    <div class="dob1">
    <label class="dob1">Your Date of Birth</label>
    <label style="margin-left:20px;">Day</label>
    <select id="day1" name="day1">
    	<option>01</option> <option>02</option> <option>03</option> <option>04</option> <option>05</option>	<option>06</option>
        <option>07</option> <option>08</option> <option>09</option> <option>10</option> <option>11</option> <option>12</option>
        <option>13</option> <option>14</option> <option>15</option> <option>16</option> <option>17</option> <option>18</option>
        <option>19</option> <option>20</option>	<option>21</option> <option>22</option> <option>23</option> <option>24</option>
        <option>25</option>	<option>26</option> <option>27</option> <option>28</option> <option>29</option> <option>30</option>
        <option>31</option> 
    </select>
     
    <label>Month</label>
    <select id="month1" name="month1">
    	<option>01</option> <option>02</option> <option>03</option> <option>04</option> <option>05</option>	<option>06</option>
        <option>07</option> <option>08</option> <option>09</option> <option>10</option> <option>11</option> <option>12</option>
    </select>
     
    <?php // Make the years array. 
    $currentYear = date("Y");
    $oldYear = $currentYear - '120';
    $years = range ($currentYear, $oldYear);
     
    // Make the years pull-down menu. 
    echo '<label>Year: </label><select id="year1" name="year1">';
    foreach ($years as $value) { 
    echo "<option value=\"$value\">$value</option>\n"; 
    } 
    echo '</select>';
    ?>
     
    </div>
    <br /><br />
    <div class="first-name-2">
    <label class="first-name-2">Partner's First Name</label> <input type="text" id="first_name_2" name="first_name_2" size="20" style="margin-left:15px;" />
    </div>
    <div class="last-name-2">
    <label class="last-name-2">Partner's Last Name</label> <input type="text" id="last_name_2" name="last_name_2" size="20" />
    </div>
    <br />
    <div class="dob2">
    <label class="dob2">Partner's Date of Birth</label>
    <label style="margin-left:20px;">Day</label>
    <select id="day2" name="day2">
    	<option>01</option> <option>02</option> <option>03</option> <option>04</option> <option>05</option>	<option>06</option>
        <option>07</option> <option>08</option> <option>09</option> <option>10</option> <option>11</option> <option>12</option>
        <option>13</option> <option>14</option> <option>15</option> <option>16</option> <option>17</option> <option>18</option>
        <option>19</option> <option>20</option>	<option>21</option> <option>22</option> <option>23</option> <option>24</option>
        <option>25</option>	<option>26</option> <option>27</option> <option>28</option> <option>29</option> <option>30</option>
        <option>31</option> 
    </select>
     
    <label>Month</label>
    <select id="month2" name="month2">
    	<option>01</option> <option>02</option> <option>03</option> <option>04</option> <option>05</option>	<option>06</option>
        <option>07</option> <option>08</option> <option>09</option> <option>10</option> <option>11</option> <option>12</option>
    </select>
     
    <?php // Make the years array. 
    $currentYear = date("Y");
    $oldYear = $currentYear - '120';
    $years = range ($currentYear, $oldYear);
     
    // Make the years pull-down menu. 
    echo '<label>Year: </label><select id="year2" name="year2">';
    foreach ($years as $value) { 
    echo "<option value=\"$value\">$value</option>\n"; 
    } 
    echo '</select>';
    ?>
     
    </div>
    <br /><br />
    <input name="Submit"  type="submit" value="Proceed to Payment"/>
    </form>

    Please forgive the PHP - That is the easiest way of creating the "Years" for the dropdown. You can view the form live at http://togevi.com/community/user/astro-cr if you need to.

    What I need to be able to do is check "day1, month1, year1" as one date and then "day2. month2, year2" as another date and if either one of them return invalid(false) I need to display an alert to tell them to correct it when the Submit button is pushed. I don't want the form to submit unless both dates are valid.

    Can somebody please help me modify the above javascript and form to accommodate this requirement?

    Thanks.

  2. #2
    SitePoint Enthusiast
    Join Date
    Oct 2012
    Posts
    41
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    The way I used to do it in the past was as follows:

    1. Create a date based on the selected values (year, month, day)
    2. Check if the DAY of the newly created date is the same as the selected day and if the MONTH of the newly created date is the same as the selected month (keep in mind: zero-based!)

    If they are, then the date is valid
    If they aren't, then the date is invalid

    I'm explaining it in words, because that way you can try it for yourself.

  3. #3
    SitePoint Zealot
    Join Date
    Oct 2010
    Posts
    167
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry Denk but I'm not sure that actually solves my problem.

    I don't see how your solution would tell me if 29th February 2009 was a valid date? Or if 31st November was a valid date? The function I have got does just that, I just need to know how to run it on BOTH date fields before the form submits rather than just running it on one of them.

    Any other ideas?

  4. #4
    SitePoint Enthusiast
    Join Date
    Oct 2012
    Posts
    41
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Hi CBResources

    I made an example, based on your HTML:

    I have changed the way you populate your "day" and "month", using PHP (in your example, the day and month options didn't have a value and it was easier for me to write it this way

    So what have I changed in your HTML?
    - The way day and month options are created
    - Added the attribute, onsubmit on the form element. ==> onsubmit="return validateForm()"

    Code HTML4Strict:
    <form name="customize_report" action="/community/user/astro-cr-payment" method="post" onsubmit="return validateForm()">
    <div class="first-name-1">
    <label class="first-name-1">Your First Name</label> <input type="text" id="first_name_1" name="first_name_1" size="20" style="margin-left:15px;" />
    </div>
    <div class="last-name-1">
    <label class="last-name-1">Your Last Name</label> <input type="text" id="last_name_1" name="last_name_1" size="20" />
    </div>
    <br />
    <div class="dob1">
    <label class="dob1">Your Date of Birth</label>
    <label style="margin-left:20px;">Day</label>
    <select id="day1" name="day1">
    	<?php
    		for($i = 1; $i <= 31; $i++) { 
    			echo "<option value=\"$i\">$i</option>\n"; 
    		} 
    	?>
    </select>
     
    <label>Month</label>
    <select id="month1" name="month1">
    	<?php
    		for($i = 1; $i <= 12; $i++) { 
    			echo "<option value=\"$i\">$i</option>\n"; 
    		} 
    	?>
    </select>
     
    <?php // Make the years array. 
    $currentYear = date("Y");
    $oldYear = $currentYear - '120';
    $years = range ($currentYear, $oldYear);
     
    // Make the years pull-down menu. 
    echo '<label>Year: </label><select id="year1" name="year1">';
    foreach ($years as $value) { 
    echo "<option value=\"$value\">$value</option>\n"; 
    } 
    echo '</select>';
    ?>
     
    </div>
    <br /><br />
    <div class="first-name-2">
    <label class="first-name-2">Partner's First Name</label> <input type="text" id="first_name_2" name="first_name_2" size="20" style="margin-left:15px;" />
    </div>
    <div class="last-name-2">
    <label class="last-name-2">Partner's Last Name</label> <input type="text" id="last_name_2" name="last_name_2" size="20" />
    </div>
    <br />
    <div class="dob2">
    <label class="dob2">Partner's Date of Birth</label>
    <label style="margin-left:20px;">Day</label>
    <select id="day2" name="day2">
    	<?php
    		for($i = 1; $i <= 31; $i++) { 
    			echo "<option value=\"$i\">$i</option>\n"; 
    		} 
    	?>
    </select>
     
    <label>Month</label>
    <select id="month2" name="month2">
    	<?php
    		for($i = 1; $i <= 12; $i++) { 
    			echo "<option value=\"$i\">$i</option>\n"; 
    		} 
    	?>
    </select>
     
    <?php // Make the years array. 
    $currentYear = date("Y");
    $oldYear = $currentYear - '120';
    $years = range ($currentYear, $oldYear);
     
    // Make the years pull-down menu. 
    echo '<label>Year: </label><select id="year2" name="year2">';
    foreach ($years as $value) { 
    echo "<option value=\"$value\">$value</option>\n"; 
    } 
    echo '</select>';
    ?>
     
    </div>
    <br /><br />
    <input name="Submit"  type="submit" value="Proceed to Payment"/>
    </form>


    Then I created the JavaScript function(s), which you need to validate it

    So in "validateForm", I just get the values and pass them onto the "checkDate" function.
    The "checkDate" function creates a new Date object and then checks if the selected DAY and the selected MONTH match with the day and month of the newly created Date object.
    Code JavaScript:
    	function validateForm(){
    		var day1 = document.getElementById( "day1" ).value;	
    		var month1 = document.getElementById( "month1" ).value;	
    		var year1 = document.getElementById( "year1" ).value;	
     
    		var day2 = document.getElementById( "day2" ).value;	
    		var month2 = document.getElementById( "month2" ).value;	
    		var year2 = document.getElementById( "year2" ).value;
     
    		return checkDate( day1, month1, year1 ) && checkDate( day2, month2, year2 );
    	}
     
    	function checkDate( day, month, year ){
    		var d = new Date( year, month - 1, day ); // month is zero-based!
    		return ( ( d.getDate() == day ) && ( d.getMonth() == month - 1 ) );
    	}

    It all seems to work fine for me - let me know!

  5. #5
    SitePoint Zealot
    Join Date
    Oct 2010
    Posts
    167
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great.

    That works I just need one more thing now... Where do I set the error message so I can tell people why their form is not submitting if they have an incorrect date?
    I'm happy to use a JS Alert.

  6. #6
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,788
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by CBResources View Post
    Sorry Denk but I'm not sure that actually solves my problem.

    I don't see how your solution would tell me if 29th February 2009 was a valid date? Or if 31st November was a valid date? ?
    If you enter 29th February 2009 then the date set would be 1st march 2009 - day 1 does not = 29 so the original date is invalid

    With 31 Nov the date would be set to 1 December - again 1 not = 31 so invalid.

    The following function provides the same return value as your function but with far fewer statements.

    Code:
    function validDate( month, day, year)  { 
      var vatdate = new Date(year, month, day);
    return (day === valdate.getDate())
    }
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  7. #7
    SitePoint Zealot
    Join Date
    Oct 2010
    Posts
    167
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi felgall,

    Thanks for your reply, but as you can see above - we already resolved that question I didn't understand the function properly but denk has kindly given me an example so now that is working. What I am trying to do now is add in an alert somewhere so the user can get some feedback on why the form doesn't submit if they do enter an invalid date. At the moment, all it does is stay on the page without any feedback to the user. Do you know where in the above code I would place the alert so the user can be told they have entered an invalid date?

  8. #8
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,788
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by CBResources View Post
    What I am trying to do now is add in an alert somewhere so the user can get some feedback on why the form doesn't submit if they do enter an invalid date.
    Don't use an alert for client messages - alerts are intended for debugging and display additional options in some browsers - such as an option to turn off JavaScript for the current page.

    You should be inserting the message into the HTML in the page itself - the easiest way is to use innerHTML.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  9. #9
    SitePoint Zealot
    Join Date
    Oct 2010
    Posts
    167
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I see...

    Well I got the error message to work with an alert using the following javascript code:

    Code JavaScript:
    <script type="text/javascript">
    function formValidate() {
    	if (!validateForm()) { alert("You have entered an incorrect date.");
    	 return false;
    		} else { return true; }
     
    		function validateForm(){
    			var day1 = document.getElementById( "day1" ).value;	
    			var month1 = document.getElementById( "month1" ).value;	
    			var year1 = document.getElementById( "year1" ).value;	
     
    			var day2 = document.getElementById( "day2" ).value;	
    			var month2 = document.getElementById( "month2" ).value;	
    			var year2 = document.getElementById( "year2" ).value;
     
    				return checkDate( day1, month1, year1 ) && checkDate( day2, month2, year2 );
    		}
     
    					function checkDate( day, month, year ){
    					var d = new Date( year, month - 1, day ); // month is zero-based!
    					return ( ( d.getDate() == day ) && ( d.getMonth() == month - 1 ) );
     
    		} 
    	}
     
    </script>

    Could you tell me which part I need to change to make it an InnterHTML Message instead of an Alert?

  10. #10
    SitePoint Enthusiast
    Join Date
    Oct 2012
    Posts
    41
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Hi CBResources

    The code example fellgall posted is slightly better than mine, so feel free to use that ( with the exception of a small bug in his code and a typo )

    Code JavaScript:
    function validDate( month, day, year)  { 
      var valdate = new Date(year, month - 1, day); // minus one because month is zero-based (januari = 0, februari = 1, ...)
      return (day === valdate.getDate());
    }

    In regards to your error message:
    - You should create an empty error-div somewhere on your page
    HTML Code:
    <div id="form_error" style="display:none"></div>
    - Change the alert to add a message to "form_error" and to make it appear. Complete JavaScript-code below (untested though). Read it first and see if you understand what is written. If you don't, then just ask what's troubling you
    Code JavaScript:
    function formValidate() {
    	var form_error = document.getElementById( "form_error" );
     
    	if( !validateForm() ){ 
    		form_error.innerHTML = "You have entered an incorrect date.";
    		form_error.style.display = "block";
    		return false;
    	} else { 
    		form_error.innerHTML = "";
    		form_error.style.display = "none";
    		return true; 
    	}	
    }
     
    function validateForm(){
    	var day1 = document.getElementById( "day1" ).value;	
    	var month1 = document.getElementById( "month1" ).value;	
    	var year1 = document.getElementById( "year1" ).value;	
     
    	var day2 = document.getElementById( "day2" ).value;	
    	var month2 = document.getElementById( "month2" ).value;	
    	var year2 = document.getElementById( "year2" ).value;
     
    	return checkDate( day1, month1, year1 ) && checkDate( day2, month2, year2 );
    }
     
    function checkDate( day, month, year ){
    	var valdate = new Date(year, month - 1, day); // minus one because month is zero-based (januari = 0, februari = 1, ...)
    	return (day === valdate.getDate());
    }


    OFFTOPIC: You guys post early! ;-)


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •