3
\$\begingroup\$

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.mon)[0]);
 this.value = this.value.replace(/([a-zA-Z]){3}/g, currentMonth);
 return true;
 }
 else if (this.mode && this.value.length !== 6) {
 this.errorHandler(this.digitLengthMsg + '6');
 return false;
 }
 else if (!this.mode && this.value.length !== 7) {
 this.errorHandler(this.digitLengthMsg + '7');
 return false;
 }
 else {
 this.errorHandler(true);
 return true;
 }
 },
 DateIsOk:function() {
 if(this.isNotEmpty() && this.isValidData()) {
 var verifyDate = this.value.match(/.{1,2}/g);
 return isValidDate(verifyDate);
 }
 }
};
var dateValidator = function (e) {
 var value = e.target.value;
 sandBox.init({
 value : value, 
 element : e.target,
 num : true //set month status true means validation by digits, false means digits with string
 });
 var fieldValue = sandBox.DateIsOk();
 if(fieldValue) {
 console.log(fieldValue);
 }
};
var dateField = $('input');
dateField.on('keyup focusout', dateValidator);

Live Demo

200_success
146k22 gold badges190 silver badges479 bronze badges
asked Jul 3, 2014 at 10:49
\$\endgroup\$
4
  • \$\begingroup\$ After a quick glance it's not immediately obvious what this.mode represents. I assume it's a toggle between validating 220875 and 22AUG75. You should probably rename the variable. If for some reason it is imperative that it stay named like that, please document its behaviour. Also, this.value.match(/.{1,2}/g) doesn't seem intuitive at all. What exactly do you want to achieve by doing this? \$\endgroup\$ Commented Jul 3, 2014 at 16:27
  • \$\begingroup\$ The fiddle says '20BUH74' is valid.. \$\endgroup\$ Commented Jul 3, 2014 at 18:53
  • \$\begingroup\$ Yes. corrected the issues. thanks for you suggestion. And any simplification approach please? \$\endgroup\$ Commented Jul 4, 2014 at 5:12
  • \$\begingroup\$ User can input the date like "220875" or "22AUG75" -- why these formats rather than a standard format that people are already familiar with and Date will recognize? \$\endgroup\$ Commented Jul 7, 2014 at 23:30

1 Answer 1

2
\$\begingroup\$

Can this be simplified ? Most certainly.

  • You can take advantage of the fact that new Date( 'APR 04 1977' ) and new Date( '04 04 1977' ) both work, so you don't need getMonthFromString
  • 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 value if you have element ( simply call val() )
  • isValidDate seems overkill, if you ask for 30 feb 2014, then testDate.getTime() will be NaN

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/

answered Jul 7, 2014 at 21:30
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.