principlejavascriptMinor
Can this date-validation function can be simplified further or is it the correct approach?
Viewed 0 times
thissimplifiedcanthefunctionvalidationdatefurthercorrectapproach
Problem
I am doing a date validation. I have no. of pages, which have the date field. User can input the date like "220875" or "22AUG75" - I need to test both and check the length as well.
```
function isValidDate(newDate) {
newDate[1] = newDate[1]-1;
newDate[2] = (parseInt(newDate[2]) < 50) ? 2000 + parseInt(newDate[2]) : 1900 + parseInt(newDate[2]);
var testDate = new Date(newDate[2], newDate[1], newDate[0]);
if (testDate.getDate()!=newDate[0] || testDate.getMonth()!=newDate[1] || testDate.getFullYear()!=newDate[2]) {
return false;
} else {
return {valid : true, date : testDate};
}
}
var sandBox = {
init:function(params){
this.element = $(params.element),
this.value = params.value,
this.mode = params.num;
},
isNotEmpty:function(){
if(!this.value.length) {
this.errorHandler(this.emptyMsg);
} else {
this.errorHandler(true);
return true;
}
},
errorHandler: function (msg) {
var errorHolder = this.element.siblings('span');
if(msg !== true)
errorHolder.html(msg).show();
else errorHolder.html("").hide();
},
emptyMsg : "Date field should not be empty",
digitLengthMsg : "The Length of the value should be ",
onlyNumber : {
num : /\D/,
str : /^\d{2}[a-zA-Z]{3}\d{2}$/,
mon : /[a-zA-Z]{3}/,
msg : "Only Digits allowed"
},
getMonthFromString : function(mon){
var month = new Date(Date.parse(mon +" 01, 12")).getMonth()+1;
month = month < 10 ? '0'+ month : month;
return month;
},
isValidData : function () {
var result = this.onlyNumber.str.test(this.value);
if(this.mode && result) {
this.errorHandler(this.onlyNumber.msg)
return false;
}
else if (!this.mode && result) {
var currentMonth = this.getMonthFromString(this.value.match(this.onlyNumber
```
function isValidDate(newDate) {
newDate[1] = newDate[1]-1;
newDate[2] = (parseInt(newDate[2]) < 50) ? 2000 + parseInt(newDate[2]) : 1900 + parseInt(newDate[2]);
var testDate = new Date(newDate[2], newDate[1], newDate[0]);
if (testDate.getDate()!=newDate[0] || testDate.getMonth()!=newDate[1] || testDate.getFullYear()!=newDate[2]) {
return false;
} else {
return {valid : true, date : testDate};
}
}
var sandBox = {
init:function(params){
this.element = $(params.element),
this.value = params.value,
this.mode = params.num;
},
isNotEmpty:function(){
if(!this.value.length) {
this.errorHandler(this.emptyMsg);
} else {
this.errorHandler(true);
return true;
}
},
errorHandler: function (msg) {
var errorHolder = this.element.siblings('span');
if(msg !== true)
errorHolder.html(msg).show();
else errorHolder.html("").hide();
},
emptyMsg : "Date field should not be empty",
digitLengthMsg : "The Length of the value should be ",
onlyNumber : {
num : /\D/,
str : /^\d{2}[a-zA-Z]{3}\d{2}$/,
mon : /[a-zA-Z]{3}/,
msg : "Only Digits allowed"
},
getMonthFromString : function(mon){
var month = new Date(Date.parse(mon +" 01, 12")).getMonth()+1;
month = month < 10 ? '0'+ month : month;
return month;
},
isValidData : function () {
var result = this.onlyNumber.str.test(this.value);
if(this.mode && result) {
this.errorHandler(this.onlyNumber.msg)
return false;
}
else if (!this.mode && result) {
var currentMonth = this.getMonthFromString(this.value.match(this.onlyNumber
Solution
Can this be simplified ? Most certainly.
My counter proposal code is about 1/3rd of yours:
I tested this fairly well on JsFiddle: http://jsfiddle.net/konijn_gmail_com/985ut/
- You can take advantage of the fact that
new Date( 'APR 04 1977' )andnew Date( '04 04 1977' )both work, so you don't needgetMonthFromString
- You can take more out of regexes with capturing groups
- You can get rid of the whole Sandbox construct which does not make a lot of sense to me
- You can write it so that the validator can accept but num:true and num:false, it can only make the user happier ;)
- Not too excited by YY, we spent billions fixing Y2K, and here you come creating more trouble ;)
- You don't need
valueif you haveelement( simply callval())
isValidDateseems overkill, if you ask for 30 feb 2014, thentestDate.getTime()will beNaN
My counter proposal code is about 1/3rd of yours:
function DateHandler(elementId, _mandatory) {
this.$dateField = $('#' + elementId);
this.mandatory = _mandatory || false;
this.$dateField.on('keyup focusout', this.validate.bind(this));
}
DateHandler.prototype.validate = function () {
this.error('');
var text = this.$dateField.val().toUpperCase(), matches;
if (text.length === 0) {
if (mandatory) {
this.error('Field should not be empty');
}
return;
} else if (text.length == 6) {
matches = /([0-3][0-9])([0-1][0-9])(\d\d)/.exec(text);
} else if (text.length == 7) {
matches = /([0-3][0-9])(\w\w\w)(\d\d)/.exec(text);
}
if (!matches) {
return this.error('Field should be of format DDMMYY or DDMMMYY');
}
value = new Date(matches[2] + ' ' + matches[1] + " " + (matches[3] < 50 ? 20 : 19) + matches[3]);
if (isNaN(value.getTime())) {
return this.error('Not a valid date');
}
console.log(value);
};
DateHandler.prototype.error = function (message) {
var label = this.$dateField.siblings('span');
message ? label.html(message).show() : label.hide();
};
var dateHandler1 = new DateHandler('d1');
var dateHandler2 = new DateHandler('d2');I tested this fairly well on JsFiddle: http://jsfiddle.net/konijn_gmail_com/985ut/
Code Snippets
function DateHandler(elementId, _mandatory) {
this.$dateField = $('#' + elementId);
this.mandatory = _mandatory || false;
this.$dateField.on('keyup focusout', this.validate.bind(this));
}
DateHandler.prototype.validate = function () {
this.error('');
var text = this.$dateField.val().toUpperCase(), matches;
if (text.length === 0) {
if (mandatory) {
this.error('Field should not be empty');
}
return;
} else if (text.length == 6) {
matches = /([0-3][0-9])([0-1][0-9])(\d\d)/.exec(text);
} else if (text.length == 7) {
matches = /([0-3][0-9])(\w\w\w)(\d\d)/.exec(text);
}
if (!matches) {
return this.error('Field should be of format DDMMYY or DDMMMYY');
}
value = new Date(matches[2] + ' ' + matches[1] + " " + (matches[3] < 50 ? 20 : 19) + matches[3]);
if (isNaN(value.getTime())) {
return this.error('Not a valid date');
}
console.log(value);
};
DateHandler.prototype.error = function (message) {
var label = this.$dateField.siblings('span');
message ? label.html(message).show() : label.hide();
};
var dateHandler1 = new DateHandler('d1');
var dateHandler2 = new DateHandler('d2');Context
StackExchange Code Review Q#55981, answer score: 2
Revisions (0)
No revisions yet.