Reputation: 894
I have few months java experience, but now I am trying to write my first javascript to validate a date input. I am not sure what is wrong in the code.
<label for="Start-date" class="label">Available start date</label>
<input type="text" onsubmit="isValidDate()" class="w-input" maxlength="256" name="Start-date" data-name="Start date" placeholder="dd/mm/yyyy" id="Start-date" th:value="${possibleStartDate}" />
<script>
var validDate = true;
function isValidDate(){
var dateString = document.getElementById("Start-date");
// First check for the pattern
if(!/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(dateString)){
validDate = false;
return;
}
// Parse the date parts to integers
var parts = dateString.split("/");
var day = parseInt(parts[1], 10);
var month = parseInt(parts[0], 10);
var year = parseInt(parts[2], 10);
// Check the ranges of month and year
if(year < 1000 || year > 3000 || month == 0 || month > 12){
validDate = false;
return;
}
var monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
// Adjust for leap years
if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)){
monthLength[1] = 29;
}
// Check the range of the day
if (!(day > 0 && day <= monthLength[month - 1])){
validDate = false;
return;
}else{
return;
}
};
if(!validDate){
alert("Invalid date!");
}
</script>
Also what is the better alternative to alert ? Something like a red small message under the textfield that the input is incorrect when submit button is pressed. I know it is better to have separate file for the javascript, but I am not sure where in the html to put the tags to link the file.
Upvotes: 0
Views: 176
Reputation: 4830
There were quite a few things which needed a little tweak:
var dateString = document.getElementById("Start-date")
should be var dateString = document.getElementById("Start-date").value;
var day = parseInt(parts[1], 10);
should be var day = parseInt(parts[0], 10);
and var month = parseInt(parts[0], 10);
should be var month = parseInt(parts[1], 10);
to support dd/mm/yyyy
Inputs don't fire onsubmit
unless they are a part of a form you can try onblur
instead
I have wrapped the input with div with children indicating success/error to show the message better. (The messages are hidden shown using classes on the root div and supporting styles)
I have spearated out the validation of a date string from DOM manipulation so you can reuse the validation across multiple places
NOTES:
date
(the browser will open up a date picker if it supports it)/**
* Function which takes a string as an input and validates if it
* is a date in the dd/mm/yyyy format
* @param {string} dateString - The string representation of the date to validate
8 @returns {boolean} value indicating if the date is valid (true) or not (false)
*/
function isValidDate(dateString) {
var validDate = true;
// First check for the pattern
if (!/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(dateString)) {
return false;
}
// Parse the date parts to integers
var parts = dateString.split("/");
var day = parseInt(parts[0], 10);
var month = parseInt(parts[1], 10);
var year = parseInt(parts[2], 10);
if(isNaN(day) || isNaN(month) || isNaN(year)){
return false;
}
// Check the ranges of month and year
if (year < 1000 || year > 3000 || month < 1 || month > 12) {
return false;
}
var monthLength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// Adjust for leap years
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
monthLength[1] = 29;
}
// Check the range of the day
if (!(day > 0 && day <= monthLength[month - 1])) {
return false;
}
return true;
};
/**
* Function which executes each time the input loses focus (onblur)
*/
function validateDate() {
// Get a reference to the container
var container = document.querySelector('.date');
// Clear stale error/success messages
container.className = container.className.replace('success', '');
container.className = container.className.replace('error', '');
// Get current value of input
var dateString = document.getElementById("Start-date").value;
// Test if the string is a valid date
var isValid = isValidDate(dateString);
// Update classess of container to show success/error
if (!isValid) {
container.className += ' error';
} else {
container.className += ' success';
}
}
div.date .error {
display: none;
background: red;
color: white;
}
div.date .success {
display: none;
background: darkgreen;
color: white;
}
div.date.success .success {
display: block;
}
div.date.error .error {
display: block;
}
<div class="date">
<label for="Start-date" class="label">Available start date</label>
<input type="text" onblur="validateDate()" class="w-input" maxlength="256" name="Start-date" data-name="Start date" placeholder="dd/mm/yyyy" id="Start-date" th:value="${possibleStartDate}" />
<div class="error">Please enter a valid date</div>
<div class="success">Date is valid</div>
</div>
Upvotes: 1
Reputation: 6597
If you're using the EcmaScript Date Time String Format, you can use the Date
constructor. (Info
var dateString = document.getElementById("Start-date").value;
var validDate = !(isNaN( new Date(dateString) )
HTML5 also supports a type="date"
in the <input>
tag. This will prevent the browser from submitting the form if the date is invalid.
Also, I think you meant
var dateString = document.getElementById("Start-date").value;
Instead of
var dateString = document.getElementById("Start-date");
Because document.getElementById("Start-date")
is an object.
Upvotes: 0