• (cs) in reply to WhoaNelly...
    Anonymous:

    You're kidding, right?  Seriously, dude.  That's funny...

    I mean, I hope you're kidding.  Right?



    Are you questioning Gene's sincerity?
  • (cs) in reply to John Bigboote

    At least they didn't use a Word document...

  • (cs) in reply to :-O
    Anonymous:
    Anonymous:

    How's this?

      [I]function isDate(testDate) { return (new Date(testDate)!='NaN' || 'moose'); }

      alert(isDate("04/01/2006")); // returns true.

      alert(isDate("0X/01/2006")); // returns moose.

     




    Unfortunately, this solution works for IE, but it does not work for browsers that properly implement the ECMAScript specification.

    <FONT face="Courier New" color=#ff0000 size=1>// Corrected code (wtf v2.0)
    // Only works in internet exploder.
    // I hope to fix this later.
    // If this function returns a moose in the
    // forest, does it make a sound?
    // I hope this doesn't end up on that wtf site I keep hearing
    // whispers and giggles about in the cubicles next to me.
    </FONT>

    <FONT face="Courier New" color=#ff0000 size=1>function isDateVersion2(testDate)
    </FONT><FONT face="Courier New" color=#ff0000 size=1>{
      return ( new Date(testDate)!='NaN' || 'Moose 2.0' );
    }
    </FONT>

    [:P]

  • (cs) in reply to asdf

    Anonymous:
    " All I'd have to do is turn off javascript and I can put 4@A5$)(W¤Õß+45n for my birthday!" Client side validation is for YOUR benifit, not the web-devs. It means we don't have to send 10 transactions back and forth just to figure out that, yes, some people are as stupid as dilbert implies. For instance, if this @#$(*&(* msg board did client side enabling of the post method, I wouldn't have to re-enter the worthless CAPTCHA everytime I forget to bang on the keyboard to create a name.

    How exactly do we avoid server round-trips in a client-side validatator that CALLS THE FUCKING SERVER?

    Eh?

     

  • (cs) in reply to John Bigboote
    John Bigboote:
    Anonymous:

    You're kidding, right?  Seriously, dude.  That's funny...

    I mean, I hope you're kidding.  Right?



    Are you questioning Gene's sincerity?

    Now that's funny.

    Sincerely,

    John Smallberries
  • Arnold Daniels (unregistered)

    Or you could simply use a regulair expression, which are perfect (as long as you don't have to write them yourself :D )
    http://regexlib.com/DisplayPatterns.aspx?cattabindex=4&categoryId=5

  • Tim (unregistered)
    Alex Papadimoulis:


    .... a call to IIS to call the .NET Runtime which calls the VisualBasic runtime to run it's built-in IsDate function.



    you mean it uses asp.net to shell a windows app written in vb6 with the date as a parameter and then capturing the result via stdio, or did they come up with a method to invoke the isdate method in VBRUN600.DLL that's amazingly dumb.

    Now Ive got the sarcasm out of the way. Why do dumb-asses always say the Microsoft.VisualBasic assembly/namespace in .Net  is a VB runtime, its pure .Net code that simulate the common methods and objects found in VB6 to ease porting large applications.

    Having said that, it doesn't excuse the code, but the submitter certainly belongs in the hall of stupid people talking about things that they don't have a clue about (unless i was right in the first paragraph and it does shell to vb6 or invoke the IsDate method in the vbrun600.dll, which would be the biggest WTF in the whole code block, since there is a perfectly good native .Net version available)
  • (cs)

    Oh god, I think I hurt myself laughing at that one....

  • maht (unregistered) in reply to Brian Kemp
    Anonymous:
    All client side is good for is an extra layer of convenience

    yeah, what kind of moron wants that !?

  • (cs) in reply to John Bigboote
    John Bigboote:

    I take it that you've never actually TRIED to return moose in a production environment. Even with the original store receipt, it's a cast-iron bitch.

    Well, if you will try to return a cast-iron sculpture of a bitch with a receipt for a moose, you're bound to have problems...
  • (cs) in reply to Stevie
    Anonymous:
    quite true, there is no isDate() function, but...

    <font style="font-weight: bold;" size="4">function isDate(testDate){
      if(testDate.constructor == Date){
        return true;
      } else {
        return false;
      }
    }</font>
    doesn't seem to hard...


    If that works, then so should:
        return (testDate.constructor == Date);
  • (cs)

    <font size="1">I have an application where I only accept ISO formatted date strings, and a handy way to validate them is:

    function validate_iso_date_format(objDateText)
    {
        if (objDateText.value == '') {
            return true; // an empty string is valid, for this app
        }
        
        // set 'invalid format' error message
        var strFormatErrMsg = "Date must be entered in 'YYYY-MM-DD' format.";
        
        var strPattern = /^(\d{4})-(\d{2})-(\d{2})$/;
        var objResult = strPattern.exec(objDateText.value );
        if (objResult == null) {
            alert(strFormatErrMsg);
            return false;
        } else {
            var nYear, nMonth, nDay;
            nYear = objResult[1];
            nMonth = objResult[2] - 1;
            nDay = objResult[3];
            var objDate = new Date(nYear, nMonth, nDay, 0, 0, 0, 0);
            if ((objDate.getFullYear() != nYear) || (objDate.getMonth() != nMonth) || (objDate.getDate() != nDay)) {
                alert('Invalid date entered. Please enter a valid date.');
                return false;
            }
        }
        return true;
    }
    </font>

  • Rob Garrett (unregistered)

    Admittedly, this is an overkill for checking for date validity, but calling web services from JS is what AJAX and ATLAS are all about.

  • (cs) in reply to Rob Garrett
    Anonymous:
    Admittedly, this is an overkill for checking for date validity, but calling web services from JS is what AJAX and ATLAS are all about.


    In this case, the WTF is where the user has a very naughty implementation of this concept.  The logic really needs to rest on the server side while the js just sends the date parameter from the form to the XHR.  A simple "true" return from the server is adequate instead of constructing a quasi-xml whateverthehell 
  • rabbit (unregistered)

    So. Are the dates from the server GMT or local time ?

    Just wonderin'

    »:*´`´`*:«© Rabbit ©»:*´`´`*:«

     

  • (cs) in reply to Tim
    Anonymous:
    Alex Papadimoulis:


    .... a call to IIS to call the .NET Runtime which calls the VisualBasic runtime to run it's built-in IsDate function.



    you mean it uses asp.net to shell a windows app written in vb6 with the date as a parameter and then capturing the result via stdio, or did they come up with a method to invoke the isdate method in VBRUN600.DLL that's amazingly dumb.

    Now Ive got the sarcasm out of the way. Why do dumb-asses always say the Microsoft.VisualBasic assembly/namespace in .Net  is a VB runtime, its pure .Net code that simulate the common methods and objects found in VB6 to ease porting large applications.

    Having said that, it doesn't excuse the code, but the submitter certainly belongs in the hall of stupid people talking about things that they don't have a clue about (unless i was right in the first paragraph and it does shell to vb6 or invoke the IsDate method in the vbrun600.dll, which would be the biggest WTF in the whole code block, since there is a perfectly good native .Net version available)

    I personally call it the VB Runtime because, even if you write a VB.NET application that doesn't explictly call anything in it, there is a dependency on functionality in that DLL. Things that are simply operators or language features end up as calls to functions in Microsoft.VisualBasic.dll. To me, that makes it a runtime, in the same way that JScript and J# both use their own runtime on top of .NET. This is why it took a while for Mono to run even the simplest of VB applications (and still has a few problems with more complicated ones).

    Furthermore, early verisons of VB.NET's IsDate method were simply a try/catch around DateTime.Parse, which did indeed call COM functions for parsing the date (while DateTime.ParseExact did not). And a large part of the VB6 runtime was COM, so in my mind it's like .NET is calling VB6 code (even though that's not entirely true).

    Things are better in .NET 2.0, where IsDate calls TryParseDate. I'm not sure if that still involves a COM call (I can't find one easily in Reflector, but the code is also pretty hard to follow). Either way, I still try to use ParseExact and TryParseExact in order to have more consistent parsing of dates. Serialized dates should be saved in something like "yyyy-MM-ddTHH:mm:ssZ" format anway, or else you'll have big problems when loading data (like CSV and Quicken QIF files).

    Dates from the user should be more flexible, and the web makes that hard since writing a good calendar control involves a lot of Javascript, but hitting the web server to validate a date on the client seems pretty WTFish to me.

  • Matthias (unregistered) in reply to :-O

    The only thing that is more stupid than today's WTF are the clueless people that need to bash on it because, hey, it's today's WTF and even though I know nothing about software development, I'm entitled to aimless ranting.

    I'm actually pretty impressed by this javascript solution. A great way to reduce code duplication. Wo cares if you make a few extra connections. Bandwidth is cheap.

  • (cs) in reply to Rob Garrett
    Anonymous:
    Admittedly, this is an overkill for checking for date validity, but calling web services from JS is what AJAX and ATLAS are all about.


    Absolutely right!

    Imagine this scenario: a user registration form. It should be a nice AJAX-y form without lots of reloading the whole page.
    You have a number of fields to verify:
    * Username (check if exists / acceptable)
    * Password (strength, if applicable)
    * Email (send verification)
    * Birthdate (must be a date . . .)
    * Various other things

    The date you can (obviously) check client-side. The username you can not. There's no way of avoiding the web app call here. The other items are debatable, however for any that end up being checked on the client, you have to DUPLICATE the verification logic on the serverside. Duplicate code means (unless your backend is written in JavaScript!) they will sooner or later do different things if you're not extra careful.

    I think checking all values on the serverside is the only way to go.

    Of course, the design could use some work. The whole form should be submitted for validation, and not individual fields. If instant-validation of each field is in the design spec, you will have to do something like this anyway.

    As for the XML, that also makes sense when you assume that multiple fields are being validated at once. You'd really want something like
    <username>valid</username>
    <password>valid</username>
    <birthdate>invalid</username>
    ...


  • Bob (unregistered) in reply to Nand

    Alright! Nothing like the fun world of perl-python-css-javascript-html-xml-ajax-soap-asp-j2ee-xhtml-php-vba-sql-dhtml-xslt integration!

    Real men write device drivers for IBM/360 mainframes in FORTRAN on punch cards.

  • BlueEagle (unregistered)

    Now this is a Rube Goldberg machine (http://rubegoldberg.com/html/gallery.htm) if I ever saw one...

  • Stas (unregistered)

    I see no WTF here. This approach is good.

  • marcos (unregistered)

    the real wtf is that it causes a postback anyways. It's just Standard ASP postback crap.

  • Robert (unregistered) in reply to Colin

    >[cliche]The real WTF here[/cliche]

    >is that he didn't do client-side VB in javascript to do date validation.

     

    Colin has it right!

     

  • ape_x (unregistered) in reply to Robert

    From now on, I'm going to have users fill in <FONT color=#000000>time_in_millis. Until people stop using idiotic non-ANSI date/time formats, that is [:)]</FONT>

  • 57451 (unregistered) in reply to ape_x
    Anonymous:

    From now on, I'm going to have users fill in <font color="#000000">time_in_millis. Until people stop using idiotic non-ANSI date/time formats, that is [:)]</font>




    WTF, why should people conform to U.S. Standards? ISO FTW.
  • (cs) in reply to mrsticks1982
    Anonymous:
    Free:

    T hereby give this to everyone, free as in beer, not free as in speech.

    Cool sig ... I never stopped and thought about the W.T.F. cause that is always how my week ends!!! I should really only work two days a week, that is the only time my work has my interest! [8-|]

    at least those two days are not (MT) empty ;)

     

  • Anti-Tim (unregistered)

    >> Why do dumb-asses always say the Microsoft.VisualBasic assembly/namespace in .Net  is a VB runtime, its pure .Net code that simulate the common methods and objects found in VB6 to ease porting large applications.

    Tim,

    Myself and, I imagine, quite a few other people, have this misconception. I went looking through the MSDN site and googling generally, and found very little information about this. (Yes, I could figure it out myself, but I have better things to do). I did, after about 20 minutes of searching, find an article on MSDN where, buried about 2/3 of the way through, is a an explanation that the Microsoft.VisualBasic assembly is in fact managed code.

    Calling someone a "dumbass" for not knowing this doesn't say much for your professionalism or common sense. I can think of plenty of reasons to call some people in this business "dumbasses", but this isn't one of them. You should get back on the board and apologize.

    Regarding the original post, a number of people seem to think there is no WTF here. I cannot alway tell if people are being saracastic or not, but I will come to Alex's defense and say, that this is, unreservedly, a WTF. The whole point of doing client side validation of the date is just to spare the user a postback if he types it in wrong. What are all the reasons not to do this with a web service? It doesn't buy the user anything. You're now mixing 2 types of APIs on the client (it's bad enough client and server models are completely different). You're adding another component that can break, must be maintained, must be kept in source code database, must be documented.

    Correct line of thinking here would be "If it's that important to me, I will figure out how to do in in JS. If it's not, skip it and let it postback to the server, where I will have final validation anyway. 90%+ of the time people are going to type in the correct date."

    If I saw this in my shop, I would probably something like "Get that crap out of here". Though maybe I'd be professional enough not call someone a "dumbass".

     

  • (cs) in reply to Anita Tinkle
    Anonymous:
    This is not a WTF.  It's stupid, but not a WTF.
    If the web service is down, most likely the web server that also served the crappy Javascript code is also down.

    You're sorta missing the point here, methinks.

    This is a webpage, which presumably has a form on it. That form wants a date. When you hit submit, the form contents are sent to a web server somewhere and action is taken based on the content you put into the form.

    But, there's javascript code to do some checking before it's actually sent to a web server. This is generally meant as a convience measure only, because you cannot rely on javascript to be enabled. The server code should always be checking the input *anyway*, since it cannot depend on the client to behave itself.

    So, if we assume that the server is already checking said date, the only point of the javascript to check said date is speed. It checks client side in order to avoid a server hit.

    Thus, making the javascript do a server hit in order to validate the input of the form is a WTF because the whole point of client side validation is to AVOID hitting a server. The form submission will hit a bloody server. Why make two server hits, both of which are validating the input, when you can only hit one server?

  • The Anonymous Coward (unregistered)

    I see a number of people defending this WTF on the grounds of code reuse.  As a proponant of code reuse, I hate seeing it maligned in this way.

    First, the most important reason we avoid code duplication is insulation against change.  How important is it to insulate against change in teh date validation algorithm?  Well, I guess you'll have to settle that in the context of your own application; but generally it's not something that would worry me.

    But ok, you've decided that there must not be two date validation routines.  You have to have a server-side validation routine.  What options do you have?

    First, ask yourself why you want a client-side validation.  Two possible answers:  (1) avoid annoying the user with a network round-trip that fails; (2) avoid spending server resources figuring out that the user entered a bad date.  As others have pointed out, these are BOTH DEFEATED if you implement the client-side validation with a web service call.  Maybe one or both of the above apply in your app; maybe not.  You need to figure out the requirements for your app.  But logically, there is no set of requirements that justify a client-side validation backed by a server round-trip.

    So you have a need for client-side validation, but you just can't bring yourself to duplicate the code.  Well, you're painting yourself into a corner, and you may just have to decide what to give up.  I suppose you could find a way for the server to encapsulate the validation logic it intends to use into the initial web page sent to the browser...

    And again, part of what makes this so bad is that it's validation for a DATE.  Use a more intelligent set of input controls and you won't need client side convenience validation.

  • (cs) in reply to Tim

    Anonymous:
    Alex Papadimoulis:


    .... a call to IIS to call the .NET Runtime which calls the VisualBasic runtime to run it's built-in IsDate function.

    Now Ive got the sarcasm out of the way. Why do dumb-asses always say the Microsoft.VisualBasic assembly/namespace in .Net  is a VB runtime, its pure .Net code that simulate the common methods and objects found in VB6 to ease porting large applications.

    Having said that, it doesn't excuse the code, but the submitter certainly belongs in the hall of stupid people talking about things that they don't have a clue about (unless i was right in the first paragraph and it does shell to vb6 or invoke the IsDate method in the vbrun600.dll, which would be the biggest WTF in the whole code block, since there is a perfectly good native .Net version available)

    I oftentimes write "it's" when I should have used "its." It's not that I don't understand the difference between the two, I'm just a poor proofreader. You shouldn't assume that mistakenly using the word "runtime" for "assembly" implies a fundamental misunderstanding.

    Should we make the same mistake with your statement ("to ease porting large applications") and assume that you are clueless about the fundamental purpose of VB.Net: to provide simple methods for common things to make them more english-readable (such as IsDate vs. DateTime.Parse).

  • Matthias (unregistered) in reply to Otto
    Anonymous:
    Thus, making the javascript do a server hit in order to validate the input of the form is a WTF because the whole point of client side validation is to AVOID hitting a server.

    Wrong, the point of clientside validation is to be able to give the user feedback without having to submit the form. Since this feedback validation has to be identical to the one made on the server, actually using the same code as on the server for the validation is the best of two worlds: Servervalidation, on the client.

    I'm not kidding when I say that I'll look into this for my next application. Hey, laugh all you want but the fact that I can now stop writing duplicated code in Javascript, arguably one of the worst languages ever, makes me very happy.

  • (cs)

    <FONT face="Courier New" size=2><FONT color=#008000>/// ******************************************
    /// **** CheckDate ***************************
    /// <summary>
    /// Validates user entered Data in Date field
    /// </summary>
    /// <param name="elm">id attribute of form Html Input element to validate[required]</param>
    /// <param name="CutOffYear">2-digit integer [00-99] representing Cutoff to use
    ///  between last century and current century when century is not provided[defaults to 85]</param>
    /// <param name="bWeekEndOk">true or false to allow entry of dates on weekends (Sat/Sunday)[defaults to true (allows weekends)]</param>
    /// <param name="bCanBeFuture">true or false to allow entry of dates  in the future[defaults to true (allows future dates)]</param>
    /// <returns>bool true (if data passes validation), or false otherwise.</returns>
    /// <comments>If data passes validation, the date entered is formatted as MM/DD/CCYY
    ///           and redisplayed into the elm.
    ///     Otherwise, an alert message box is displayed to the user, and
    ///      the input box pointed to by elm is erased.
    ///           -----------------------------------------------
    ///           Function also allows passing of "Shortcut Keys"
    ///           to indicate commonly intended dates:
    ///             T-  Today - Current Date
    ///             B-  Beginning (first day) of current month
    ///             N-  Next - 1st of Next month
    ///             E-  End - (Last Day) of current month
    ///             Y - Yesterday
    ///</comments>
    </FONT> function CheckDate (elm, CutOffYear, bWeekEndOk, bCanBeFuture)  {
      var iCOY = (arguments.length == 1)? 85: CutOffYear;
      var bWEOk = (arguments.length < 3)? true: bWeekEndOk;
      var bCBF =  (arguments.length < 4)? true: bCanBeFuture;
      var sDate = elm.value;
      var frm = elm.form;
      var now = new Date();
      if (sDate.length == 0) return true; <FONT color=#008000>// accept blank date ...
    </FONT>  
      if (sDate.toUpperCase() == "T") { <FONT color=#008000>// Todays date</FONT>
          sDate = (now.getMonth()+1).toString() + '/' + 
                now.getDate().toString() + '/' +
                </FONT><FONT face="Courier New" size=2>now.getFullYear().toString();
          elm.value = formatShortDate(sDate);
          return((bWEOk)? true: CheckIfWeekDay(elm));
      }
      
      if (sDate.toUpperCase() == "B") { <FONT color=#006400><FONT color=#008000>// Beginning (1st) of month date</FONT>
    </FONT>   sDate = (now.getMonth()+1).toString() + '/1/' + now.getFullYear().toString();
       elm.value = formatShortDate(sDate);
       return((bWEOk)? true: CheckIfWeekDay(elm));
      }
      
      if (sDate.toUpperCase() == "N") { <FONT color=#008000>// 1st of Next month</FONT>
       sDate = ((now.getMonth()==11)? '1':
           (now.getMonth()+2).toString()) + '/1/' +
            now.getFullYear().toString();
       if (!bCBF) return (false);
       elm.value = formatShortDate(sDate);
       return((bWEOk)? true: CheckIfWeekDay(elm));
      }
      
      if (sDate.toUpperCase() == "E") { <FONT color=#008000>// End of month
    </FONT>     var bonm = Date.parse(((now.getMonth()==11)? '1':
            (now.getMonth()+2).toString()) + '/1/' +
             now.getFullYear().toString());
         var newDate = (new Date(bonm - 86400000));
         sDate = (newDate.getMonth()+1).toString() + '/' + 
                newDate.getDate().toString() + '/' + 
                newDate.getFullYear().toString();
         if (!bCBF) return (false);
         elm.value = formatShortDate(sDate);
         return((bWEOk)? true: CheckIfWeekDay(elm));
      }
      
      if (sDate.toUpperCase() == "Y") { <FONT color=#008000>// Yesterday
    </FONT>      var newDate = (new Date(now - 86400000));
          sDate = (newDate.getMonth()+1).toString() + '/' + 
                  newDate.getDate().toString() + '/' +
                  newDate.getFullYear().toString();
          elm.value = formatShortDate(sDate);
          return((bWEOk)? true: CheckIfWeekDay(elm));
      }
      
      <FONT color=#008000>// with 2 digit year, use Cutoff to determine Century
    </FONT>  if (sDate.search(/^(\d{1,2}\/){2}\d\d$/) != -1) { 
          var sYr = sDate.substr(sDate.lastIndexOf('/') + 1,2);
          var sMonDay = sDate.substring(0, sDate.lastIndexOf('/'));
          <FONT color=#008000>//alert ('sYr = ' + sYr + '\nsMonDay = ' + sMonDay);
    </FONT>      sYr = ((parseInt(sYr) < iCOY)? '20': '19') + sYr;
          elm.value = sDate = formatShortDate(sMonDay + '/' + sYr);
      }
      
      <FONT color=#008000>// ***** Check for CCYY-MM-DD Pattern and parse out date if found *****</FONT>
      if (sDate.search(/^(19|20)\d\d-(0?[1-9]|1[0-2])-(0?\d|[1-2]\d|3[0-1])$/) != -1) {  
       var sYr = parseInt(sDate.substring(0,4));
       var bIsLeapYr = (((sYr % 4) == 0) && ((sYr % 400) != 0));
       var sMon = parseInt(sDate.substring(5,sDate.indexOf('-',5)));
       var sDom = parseInt(sDate.substring(sDate.indexOf('-',5) + 1));
     <FONT color=#008000>  /****************************************
    </FONT> <FONT color=#008000>  alert ('2nd dash @ ' + sDate.indexOf('-',5) +
              '\nYear = ' + sYr + '\nMon = ' +
               sMon + '\nDay = ' + sDom);
       *****************************************/
    </FONT><FONT color=#008000>   // ----- Don't allow more than 30 days in Sep, Apr, Jun or Nov ----------
    </FONT>   if ((sMon == 4 || sMon == 6 ||
            sMon == 9 || sMon == 11) 
             &&(sDom > 30)) {    
        switch (sMon) {
         case (4): sMonName = 'April'; break;
         case (6): sMonName = 'June'; break;
         case (9): sMonName = 'September'; break;
         case (11): sMonName = 'November'; break;
        }
        alert( 'There are only thirty days in ' + sMonName + '\nPlease try again.');
        elm.value = '';
        elm.select();
        elm.focus();
        return(false);
       }
    <FONT color=#008000>   // ----- Don't allow more than 31 days in the rest, except for Feb ----------
    </FONT>   if ((sMon == 1 || sMon == 3 ||
            sMon == 5 || </FONT><FONT face="Courier New" size=2>sMon == 7 ||  
            sMon == 8 || sMon == 10 || 
            sMon == 12 ) && (sDom > 31))   {
        alert( 'There are only thirty-one days in a month.' + '\nPlease try again.');
        elm.value = '';
        elm.select();
        elm.focus();
        return(false);
       }
    <FONT color=#008000>   // ----- Don't allow more than 28/29 days in Feb ----------
    </FONT>   if ((sMon == 2) && (sDom > ((bIsLeapYr)? 29: 28))) {
        var sMsg = 'There are only twenty-';
        sMsg += ((bIsLeapYr)? 'nine': 'eight');
        sMsg +=  ' days in February ' + sYr.tostring() + '.';
        sMsg +=  '\nPlease try again.';
        alert(sMsg);
        elm.value = '';
        elm.select();
        elm.focus();
        return(false);
       }   
       elm.value = sDate = formatShortDate(new Date(sYr, sMon - 1, sDom));
      } 
     
    <FONT color=#008000>  // Next check again if can recognize as date,
      // if not, may just be absent year as in '3 Jul' or 'Jul 13'
      // if so, try to attach current Year (No Year implies current Year)
    </FONT>  if (isNaN(Date.parse(sDate))) {
       var sYear = now.getFullYear().toString();
     <FONT color=#008000>  // --- If still not recognizeable with Year appended, Give up....
    </FONT>   if (isNaN(Date.parse(sDate + ' ' + sYear))) {
        alert ('[' + sDate + '] is not a recognizable date.\nPlease try again.');
        elm.value = '';
        elm.select();
        elm.focus();
        return(false);
       }
       else { <FONT color=#008000>// It is recognizeable with current Year attached....
    </FONT>    sDate += ' ' + sYear;
       }
      <FONT color=#008000> //alert ('sDate = ' + sDate);
    </FONT>  }
         
      
      <FONT color=#008000>// Is recognizeable as date, but may have trailing characters
    </FONT>  elm.value = sDate = formatShortDate(sDate);
      <FONT color=#008000>// but if IS recognizeable as date...  test for limits... (Confirm Only)
    </FONT>  if ((!bCBF) && (Date.parse(sDate) > Date.parse(now))) {
       alert("Dates in the future are not permissible here.");
       elm.value = '';
       elm.select();
       return(false);
      }
     <FONT color=#008000> // Other passed in Limits
    </FONT>  if (Date.parse(sDate) > Date.parse('12/31/2099')) {
       var sMsgHi = 'You entered the date: [ ' + sDate + ' ].';
       sMsgHi += '\nAre you sure this is the correct date?';
       if (!confirm(sMsgHi)) {
        elm.value = '';
        elm.select();
        return(false);
       }
      }
      
      if (Date.parse(sDate) < Date.parse('01/01/19' + iCOY.toString())) {
       var sMsgLo = 'You entered the date: [ ' + sDate + ' ].';
       sMsgLo += '\nAre you sure this is the correct date?';
       if (!confirm(sMsgLo)) {
        elm.value = '';
        elm.select();
        return(false);
       }
      }</FONT>

    <FONT face="Courier New" size=2>  elm.value = formatShortDate(sDate);
      <FONT color=#008000>// If Sat/Sun not Ok, Test for that...
    </FONT>  return((bWEOk)? true: CheckIfWeekDay(elm));
     }
    <FONT color=#008000>// *******************************************************************
    // **** End of CheckDate ********************************************</FONT></FONT>

  • (cs) in reply to Bullet

    <FONT face="Courier New"> function CheckIfWeekDay(elm) {
        var dDate = new Date(elm.value);
        var dow = dDate.getDay();
        if (dow == 0 || dow == 6) {
           var sMsg = "That date falls on a " +
                      (dow == 0)? 'Sunday.': 'Saturday.';
           sMsg += "\nPlease select a weekday.";
           alert (sMsg);
           elm.value='';
           return(false);
         }
       else
          return(true);
     }
    </FONT>

  • (cs) in reply to Bullet
    Bullet:
    /// ******************************************

    <font face="Courier New" size="2"><font color="#008000">/// **** CheckDate ***************************
    ///


    /// Validates user entered Data in Date field
    ///

    ///</font></font>

    Sweet Lord! Shoot me now?! Please?!?! Reminds me of the wonderful php-ism of switching one parameter (?op=blah) and then having a hundred different branches ALL IN ONE FILE depending on that parameter! Yuck!

  • Anti-Tim (unregistered) in reply to Matthias

    >>Wrong, the point of clientside validation is to be able to give the user feedback without having to submit the form.

    Yes, because submitting the form hits the server.

    [^o)]

  • (cs) in reply to Matthias
    Anonymous:
    Wrong, the point of clientside validation is to be able to give the user feedback without having to submit the form.


    But that's my point. Why don't you want to submit the form? Answer: Submitting the form = a server hit, and server hits take time. There's really no other reason to do client side validation. The "instant feedback" is the whole point of client side validation. If it has to hit a server, then why not simply submit the form? It's the same time to validate, really, if your server code is doing validation (which it had better be doing anyway).

    Anonymous:
    Since this feedback validation has to be identical to the one made on the server


    Says who? The feedback validation is to try to make the user enter valid data in the field, not to make the user enter valid data in the context of the application. For example, this date check could verify that the user entered a real date, even if the date makes no sense in the context of the range you're expecting. It's unlikely that the user is going to enter

    Anonymous:
    actually *using* the same code as on the server for the validation is the best of two worlds


    No, it's the worst of two worlds. Not only does your client now have to hit the server for a validation, making the client wait for a server response, but the server now has to validate twice when you actually submit the form with a valid input. Once for the fake client side validation, and again for the actual submission (since you cannot count on the javascript code executing at all).

  • (cs) in reply to Otto

    Dangit. Silly thing cut out part of my post.

    ...It's unlikely that the user is going to enter a date from the year 1000AD for getting a report, for example. But he might enter a date in the wrong format you wanted, which your client side validation would check for. You don't have to check everything in the javascript, just that the input makes sense in the more obvious ways.

  • (cs) in reply to Matthias
    Anonymous:
    I'm not kidding when I say that I'll look into this for my next application. Hey, laugh all you want but the fact that I can now stop writing duplicated code in Javascript, arguably one of the worst languages ever, makes me very happy.


    Agreed on both counts.  It's worth it to minimize the need to use Javascript (which I consider the BASIC of the 21st century), and it's worth it to avoid duplicating code.
  • Anti-Tim (unregistered) in reply to VGR

    Well you guys have convinced me, I'm now going to replace all my javascript with web services.

     

    [N]

  • (cs) in reply to marvin_rabbit

    marvin_rabbit:

    I'm sure that we could do a Vector of moosen.

    Moosen? Come now. Everyone knows the plural of moose is meese.

  • (cs) in reply to The Anonymous Coward

    With regard to the OP:

    Anonymous:

    I see a number of people defending this WTF on the grounds of code reuse.  As a proponant of code reuse, I hate seeing it maligned in this way.

    I think it makes perfect sense, see below.

    First, ask yourself why you want a client-side validation.  Two possible answers:  (1) avoid annoying the user with a network round-trip that fails; (2) avoid spending server resources figuring out that the user entered a bad date.  As others have pointed out, these are BOTH DEFEATED if you implement the client-side validation with a web service call. 

    Not quite. It's all about responsiveness of the UI. It doesn't have to be instantaneous, but instead it should be "fairly quickly".

    Now, we now that a page reload sucks in terms of responsiveness. But the time it takes to reload a webpage doesn't consist of the server roundtrip alone. The roundtrip itself is actually rather fast (100ms or so). But the roundtrip is not the only factor in the responsiveness: the site has to transmit the webpage (takes time), and the client has to render the page, which also takes some nontrivial amount of time.

    Compare that scenario with a small AJAX post: the roundtrip will be the same. Packet body: much smaller. Render time: none.

    Yes, it won't be as instantaneous as a full client-side check, but it will be a heck of a lot faster than a full page reload. So: you get a better user experience and remove code duplication. What's the downside again?

    (Note: This is all under the proviso that it's implemented intelligently. I'm not defending the original post)

  • (cs) in reply to Bullet
    Bullet:
    <font face="Courier New" size="2"><font color="#008000">
    /// </font></font><param name="CutOffYear"><font face="Courier New" size="2"><font color="#008000">2-digit integer [00-99] representing Cutoff to use
    ///  between last century and current century when century is not provided[defaults to 85]
    </font></font><font face="Courier New" size="2"> var iCOY = (arguments.length == 1)? 85: CutOffYear;
    </font>


    This sounds good, and it is good for now, but come 2060 or so it's going to be horribly wrong.

    A better approach is to take the last two digits of the current year as a guide, and have CutOffYear be the last two digits of fifty years from now.

    So now, two digit years will lie from 1957 to 2056.

    In 2060, two digit years will lie from 2011 to 2110.

    This isn't perfect, but it's about as good as you can get without requiring years to be spelled out in full.
  • rponton (unregistered) in reply to Otto

    Otto, your fundamental assumption, "There's really no other reason to do client side validation" is false, and the rest of your argument is therefore false as well.

    This is a valid approach for an overworked developer developing an intranet app in ASP.NET.

    You see, "server hit" and "PostBack" are not the same thing.  PostBack implies "server hit", but not vice versa.  A PostBack not only causes the user's screen to flicker, but it also causes all of the page logic to fire, click events, onchange events, etc.

    For an intranet app, the extra server hit from the web service call is not likely to be a performance concern.  But the extra usability of having client-side pre-validation before a PostBack is great.  For instance, all Password fields are cleared on PostBack.  Client-side validation will prevent the user from having to reenter his or her password again due to some other field being invalid.

    However, client-side validation is extremely frustrating when it doesn't match the server-side validation.  A simple date regexp is not going to match the server-side .NET DateTime.TryParse() functionality.  Furthermore, having a simple pattern of "all client-side validations call a web service which runs the exact same code as the server-side validation" makes things simple.

    I'll grant you that performance is worse.  But buying a faster server is a lot cheaper than having your developer waste time writing javascript validation functions and testing that they match the behavior of the server-side code.


    That said, ASP.NET 2.0 has validation controls with cross-browser client-side validation for things like this already.

  • (cs) in reply to Maurits

    Maurits:
    Bullet:
    <FONT face="Courier New" size=2><FONT color=#008000>
    /// </FONT></FONT><PARAM name="CutOffYear"><FONT face="Courier New" size=2><FONT color=#008000>2-digit integer [00-99] representing Cutoff to use
    ///  between last century and current century when century is not provided[defaults to 85]
    </FONT></FONT><FONT face="Courier New" size=2>var iCOY = (arguments.length == 1)? 85: CutOffYear;
    </FONT>


    This sounds good, and it is good for now, but come 2060 or so it's going to be horribly wrong.

    A better approach is to take the last two digits of the current year as a guide, and have CutOffYear be the last two digits of fifty years from now.

    So now, two digit years will lie from 1957 to 2056.

    In 2060, two digit years will lie from 2011 to 2110.

    This isn't perfect, but it's about as good as you can get without requiring years to be spelled out in full.

     

    good idea, thank you!

  • (cs) in reply to Anti-Tim
    Anonymous:
    Myself and, I imagine, quite a few other people, have this misconception. I went looking through the MSDN site and googling generally, and found very little information about this. (Yes, I could figure it out myself, but I have better things to do). I did, after about 20 minutes of searching, find an article on MSDN where, buried about 2/3 of the way through, is a an explanation that the Microsoft.VisualBasic assembly is in fact managed code.

    And yes, even though it's managed code does not make it any less of a runtime. In fact, the description on the DLL is "Visual Basic Runtime Library", so at least one person at Microsoft agrees.

    Granted, it doesn't control the execution of the code at every step, but it does implement several of the language features. Only if a language compiles all of its features into the final executable will it not need a runtime (like C with static linking to the standard libraries).

    There are several "managed runtimes." IKVM is (at least mostly) managed code, and it's a Java runtime written in C#. They even go so far as to have a "IKVM.Runtime.dll".

  • Muse (unregistered)

    function howMuchWoodCouldAWoodchuckChuck(bool AWoodchuckCouldChuckWood)

    {

       if (AWoodchuckCouldChuckWood)

       {

          return true;

       }

       else

       {

          return false;

       }

    }

  • grammar nazi (unregistered)

    This way, as the anonymous submitter discovered in a system he was maintaining, you can simply make a call over Ethernet to make a call over IP to make a call over TCP to make a call over HTTP to make a call over XML to make a call to IIS to call the .NET Runtime which calls the VisualBasic runtime to run it's built-in IsDate function.

    That was a rather amusing sentence built just to remind me that you don't know how to use an apostrophe. WTF?!

  • RichNFamous (unregistered)

    This is true Enterprise thinking, and should be encouraged. Give this man a tie and a company jacket!

  • Rob (unregistered) in reply to Gene Wirchenko

    I can see lots of reasonable uses for this style of validation in an intranet environment where network performance can be less of an issue. For one it allows for the same code to be used for validating business rules on both the server and the client, giving one place for maintaining those rules, oh i forgot we like to duplicate that code in both places, silly me.

    In isolation, yes using a web service to perform an isDate style validation is a huge hammer for a little old peanut but the principle is sound and as part of a larger validation scheme it could make sense for consistency.

    Not really a wtf moment for me though.

  • (cs)

    Not really a WTF as has been mentioned.

    But this sort of thing is why I always say never let people enter free form dates. Dates are confusing and people put them in wrong and mess up your data. Thats even before you get to different locale settings. Use a date picker control.

Leave a comment on “The Long Road to Validation”

Log In or post as a guest

Replying to comment #:

« Return to Article