[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2345
  • Last Modified:

Smart Textbox Date Mask and ASP.NET

I've scoured the Web, figuring this would be a common question, but I cannot find a solution...so if your answer is a link that provides everything I need, great!

I'm developing in ASP.NET (Whidbey) and need to use JavaScript to "mask" a textbox for a date.

Here are the requirements:

1.  Must only allow numeric and "/"
2.  Must be in the format mm/dd/yyyy
3.  Must be "smart" enough to advance from mm to dd if 2 thru 9 entered
4.  Must insert "/" in the appropriate places as the user types
5.  Must insert trailing zeros if not entered (ex., if the first character entered is 2 then the script will, probably on keydown, return "02/" to the textbox)
6.  Must not exhibit strange behavior if the user is editing numbers within the string (like disallowing entry if editing the day and will still allow the slash)

The point value is based on the fact that I would like a complete solution and not just bits and pieces.

Thank you!
0
sjd0103
Asked:
sjd0103
  • 9
  • 6
  • 2
  • +1
1 Solution
 
sjd0103Author Commented:
Any comments about why no one is answering?
0
 
T-DubCommented:
That's quite a function. Would be fun to write if I had the time. I might set aside some time later for fun but I can't make any promises. Usually in the circumstance I would simply use 3 seperate text fields and shift focus to the next box when necessary. Your solution would obvioulsy be a superior user experience though. Unless they are a user like me though and they quickly type in the date with the keypad without noticing that the javascript is automatically inserting slashes for me.
0
 
ThaSmartUnoCommented:
http://dcwml.ath.cx:8081/test/Q_21388209.html

I think this could work ...
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
T-DubCommented:
Close ThaSmartUno but not quite. The field seems to be too short and it acts funny if you don't enter a full year. Great work though.
0
 
ThaSmartUnoCommented:
yea ... it had a maxlength of 9 ... i fixed that =)
0
 
sjd0103Author Commented:
that's sweet.  so far looks great.  I'll play with it tonight and get back to you before monday.  Thank you!
0
 
sjd0103Author Commented:
ok, it is a bit flaky...entering:

1/25/2005 results in 01/025/2005
01/25/2005 results in 01//2/5/20

two major flaws.  it has to account for users that want to enter their own slash.  also, that extra zero in the day just doesn't cut it.

I'm still hopeful for a complete solution.
0
 
ThaSmartUnoCommented:
for 1/25/2005 I'm actually getting 01//25/200 .... I will not be able to work on it until monday also, have a good weekend
0
 
ThaSmartUnoCommented:
k, let me know how that works for you
0
 
ThaSmartUnoCommented:
so what do you think about the 3 fields? ... since I'm having technical difficulties with the single box
0
 
sjd0103Author Commented:
The 3 fields are not an option - personally prefer them, but we're not in a position to change that.  What are your technical difficulties with the single textbox?  When I tried earlier today it was looking good.  I don't need the date validation (Feb 29th logic, etc.) if that helps.
0
 
ThaSmartUnoCommented:
Sorry I had a really long day today, anyways ... I'll take a look at my code ... I remember there being a problem with the regular text box.
0
 
ThaSmartUnoCommented:
k so it actually looks like it works ... i cant see to make it fail ... let me know what you think and I will post the code in here so it will be on the ee site
0
 
sjd0103Author Commented:
I'm plugging the code in tonight.  I should have an answer tomorrow.  Again, it looks good so far.  Thank you TheSmartUno!
0
 
ThaSmartUnoCommented:
<script type="text/javascript">
    <!--

    // days In Months
    var dim=[0,31,29,31,30,31,30,31,31,30,31,30,31],inalert=false;

    // this function used for both methods
    function ly(y) {
      return !((y%4)!=0 || (
        (y%100)==0 &&
        (y%400)==0));
    }

    // this function used for single text box method
    function validDate(e,txt){
      if(inalert)return false;
      // ignore backspace(8), tab(9), shift(16), control(17),
      // alt(18), end(35), home(36), delete(46), arrows(37-40), F5(116)
      switch(e.keyCode){case 8:case 9:case 16:case 17:case 18:case 35:
                        case 36:case 37:case 38:case 39:case 40:case 46:
                        case 116:return}

      if((e.keyCode<96||e.keyCode>105)&& // number pad
         (e.keyCode<48||e.keyCode>57)&& // number top row
         (e.keyCode!=191&&e.keyCode!=111)){  // the slash & (number pad slash)
        txt.value=txt.value.replace(/[^0-9\/]/,'');
        // alert("Invalid key pressed."+e.keyCode);
        return false;
      }
      var isslash=(e.keyCode==191||e.keyCode==111),
        l=txt.value.length,
        s=txt.value;


      if(!l)return false;

      if(l==1&&s=='/'){
        txt.value='';
        return false;
      }
      // check for single-digit
      if(l==1&&s!='1'&&s!='0'){
        txt.value='0'+s+'/';
        return false;
      }
      if(isslash&&l==2)s='0'+s;
      s=s.replace('//','/');
      l=s.length;

      if(l==2&&s.charAt(1)!='/')s+='/';
      if(l==5&&s.charAt(4)!='/')s+='/';

      if(isslash){
        // validate slash position
        for(var i=0;i<s.length;i++)
          if(s.charAt(i)=='/'&&i>5)
            s=s.substr(0,i)+s.substr(i+1);

      }


      // in case they changed
      txt.value=s;
      l=s.length;

      var dt=s.split('/');
      if(s.charAt(4)=='/'){
        // ex. 12/3/
        dt[1]='0'+parseInt(dt[1]);

        txt.value=dt.join('/');
      }

      // validate the month
      if((isNaN(parseInt(dt[0])))||((parseInt(dt[0])<1||parseInt(dt[0])>12)&&(dt.length>1))){
        txt.value='';
        inalert=true;
        alert('Invalid month.');
        inalert=false;
        return false;
      }

      // validate the days
      if(parseInt(dt[1])==0&&dt.length==3){
        inalert=true;
        alert('Invalid days in month.  Between 1 and '+dim[parseInt(dt[0])]+'.');
        inalert=false;
        txt.focus();
        return false;
      }else if(parseInt(dt[1])!=0){
        if(parseInt(dt[1])<1||parseInt(dt[1])>dim[parseInt(dt[0])]){
          inalert=true;
          alert('Invalid days in month.  Between 1 and '+dim[parseInt(dt[0])]+'.');
          inalert=false;
          txt.focus();
          return false;
        }
      }

      if(l==10)DateBlur(txt);
    };

    // this function used for single text box method
    function DateBlur(txt){
      if(inalert)return false;
      var tst;
      if(!txt.value){
        txt.value='mm/dd/yyyy';
        return;
      }

      if(txt.value.indexOf('/')!=-1){
        var dt=txt.value.split('/');
        // check month
        if(dt.length>0){
          tst=parseInt(dt[0]);
          if(isNaN(tst)||tst<1||tst>12){
            inalert=true;
            alert('Invalid month, can only be between 1 and 12.');
            inalert=false;
            txt.focus();
            return false;
          }
          if(tst<10)dt[0]='0'+tst.toString();
        }
        // check date
        if(dt.length>1&&dt[1]!=''){
          tst=parseInt(dt[1]);
          if(isNaN(tst)||tst<1||tst>dim[parseInt(dt[0])]){
            inalert=true;
            alert('Invalid date, can only be between 1 and '+dim[parseInt(dt[0])]+'.');
            inalert=false;
            txt.focus();
            return false;
          }
          if(tst<10)dt[1]='0'+tst.toString();
        }
        // check year
        if(dt.length==3&&dt[2]!=''){
          tst=parseInt(dt[2],10);
          if(tst<70)    // between 0-69 convert to 2000-2069 respectively
            tst+=2000;
          else if(tst<100) // conver 70-99 to 1970-1999 respectively
            tst+=1900;

          dt[2]=tst.toString();
          if(tst<1000)dt[2]='0'+tst.toString();

          if(!ly(parseInt(dt[2]))&&dt[0]=='02'&&dt[1]=='29'){
            inalert=true;
            alert("Invalid date, February in this year only has 28 days.");
            inalert=false;
            txt.focus();
            return false;
          }
        }

        txt.value=dt.join('/');
      }
    }

    //-->
    </script>

in body have a text box something like
<input type="text" name="d1" value="mm/dd/yyyy"
    onfocus="if(this.value=='mm/dd/yyyy')this.value='';"
    onblur="DateBlur(this);"
    id="d1" maxlength="10"
    disabled="disabled" />

and this anytime after this input box
<script type="text/javascript">
  <!--
    var a;

    if(document.getElementById){
      a=document.getElementById("d1");
    }else if(document.all){
      a=document.all["d1"];
    }else if(document.d1){
      a=document.d1;
    }else
      alert("Cannot set onkeydown to validate the date text field.");

    if(a){
      a.onkeyup=function(e){if(!e)e=window.event;validDate(e,this)};
      a.disabled=false;
    }
  //-->
  </script>
0
 
sjd0103Author Commented:
I'm really sorry this got past me for so long.  ThaSmartUno, thanks very much for the input.  It's close, but still not 100%...I appreciate the effort.
0
 
ThaSmartUnoCommented:
well at least it helped a bit.

Thanks for the points
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 9
  • 6
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now