Date validation using onkeydown in Javascript and ASP

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Rob

    Date validation using onkeydown in Javascript and ASP

    I have a date text box (input type = text) in an ASP.NET/Javascript
    environment. I wanted to force the users to enter dates in a
    "__/__/____", "dd/mm/yyyy" or similar format. The textbox needs to
    support normal copy/paste/delete format. There wasn't much on Google
    to help so (after a bit of toil) though I'd post my suggested solution
    here. No guarantees I'm afraid; just hope it helps somebody out there.

    Rob

    Here's the ASP source code:

    <%@ Page Language="vb" AutoEventWireup ="false"
    Codebehind="Web Form2.aspx.vb" Inherits="WebAp plication1.WebF orm2"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
    <head>
    <script language="Javas cript" src="DateMask.j s"></script>
    </head>
    <body>
    <form id="frmMain">
    <b>Date TextBox</b><p></p>
    Enter Date:
    <input type="text" name="txtDate" id="txtDate" size="10"
    maxlength="10" onkeydown="date OnKeyDown()"
    onpaste="dateOn Paste(this)" value="__/__/____">
    <p></p>
    </form>
    </body>
    </html>

    And the contents of DateMask.js:

    function dateOnKeyDown() {
    /* Purpose : Formats date text field so it adheres to
    * the dd/mm/yyyy format
    *
    * Effects : Sets the value of the text field
    *
    * Inputs : None
    *
    * Returns : None
    */

    var DATE_DIVIDER = "/";
    var SPACE_CHARACTER = "_";

    var objTextBox = window.event.sr cElement;
    var iKeyCode = window.event.ke yCode;
    var bSelectedText = false;

    // Exit if field is read-only
    if (window.event.s rcElement.readO nly) return;

    // Allow key presses of <cursor arrow> or <Home> or <End>
    if ((iKeyCode > 36 && iKeyCode < 41) || (iKeyCode > 34 && iKeyCode <
    37)) {
    return 1;
    }

    // Allow <Ctrl+C>, <Ctrl+V>, <Ctrl+X> and <Ctrl+Z>
    if (window.event.c trlKey && (iKeyCode == 67 || iKeyCode == 86 ||
    iKeyCode == 88 || iKeyCode == 90)) {
    return 1;
    }

    // Get the position of the cursor
    var iCaretPosition = getCaretPositio n(objTextBox);

    // Get the selected text
    var objSelectedText = document.select ion.createRange ();

    // Determine if some text has been selected
    if (objSelectedTex t.parentElement () == objTextBox &&
    objSelectedText .text.length > 0)
    {
    bSelectedText = true;
    }

    // Get the element next to the cursor (to be used later)
    var sFirstElement = objTextBox.valu e.substring(iCa retPosition,
    iCaretPosition-1);

    // Do not enter number if there's no space for it
    if ((sFirstElement != SPACE_CHARACTER ) && !(iKeyCode == 8 || iKeyCode
    == 46) && objSelectedText .text == 0) {
    return 0;
    }

    // If key pressed is <0-9>
    if ((iKeyCode > 47 && iKeyCode < 58) ||
    (iKeyCode > 95 && iKeyCode < 106)) {
    if (iKeyCode > 95) iKeyCode -= (95-47);

    // Do not update text/move cursor if it is at the end of the textbox
    if (iCaretPosition != 11) {

    // Only write the character if it's filling an empty gap
    // ie don't overwrite existing number or '/' characters
    var sNextElement = objTextBox.valu e.substring(iCa retPosition-1,
    iCaretPosition) ;

    if (!bSelectedText && sNextElement == SPACE_CHARACTER ) {
    // Get the text before the cursor
    var sElement1 = objTextBox.valu e.substring(0, iCaretPosition-1);
    // Get the text after the cursor
    var sElement2 = objTextBox.valu e.substring(iCa retPosition +
    objSelectedText .text.length, objTextBox.valu e.length);
    // Append the new character
    sElement1 += String.fromChar Code(iKeyCode);
    // Append the text from after the cursor
    sElement1 += sElement2;
    objTextBox.valu e = sElement1;

    // Move the cursor position on one for "/" charcters
    switch (iCaretPosition ) {
    case 2:
    case 5:
    iCaretPosition = iCaretPosition+ 1;
    default:
    }
    }

    // Handle selected text
    if (bSelectedText) {

    // Get the text before the selected text
    var sElement1 = objTextBox.valu e.substring(0, iCaretPosition-1);

    // We need to keep "/" characters
    if (sFirstElement == DATE_DIVIDER) {
    sElement1 += DATE_DIVIDER;
    }

    // Append the new character
    sElement1 += String.fromChar Code(iKeyCode);

    // Replace the remaining selected text with blank spaces
    for (var i=1; i<objSelectedTe xt.text.length; i++) {
    var sDeletedChar = objSelectedText .text.substring (i, i+1);
    if (sDeletedChar == DATE_DIVIDER) {
    // Keep the slash characters
    sElement1 += DATE_DIVIDER;
    } else {
    // Do not insert extra space if the first selected character is
    a "/"
    if (!(i==1 && sFirstElement == DATE_DIVIDER)) {
    // Replace numbers with a space
    sElement1 += SPACE_CHARACTER ;
    }
    }
    }

    // Get the text after the selected text and append
    var sElement2 = objTextBox.valu e.substring(iCa retPosition +
    objSelectedText .text.length-1, objTextBox.valu e.length);
    sElement1 += sElement2;
    objTextBox.valu e = sElement1;
    }

    // Put the cursor in the correct position
    objSelectedRang e = objTextBox.crea teTextRange();

    // Move cursor on 1 if the first selected character is a "/"
    if (bSelectedText && sFirstElement == DATE_DIVIDER) iCaretPosition
    = iCaretPosition+ 1;
    objSelectedRang e.move("charact er", iCaretPosition)
    objSelectedRang e.select();

    }
    } // End if key pressed is <0-9>

    // If key pressed is <Del>
    if (iKeyCode == 8 || iKeyCode == 46) {

    // Handle selected text
    if (bSelectedText) {

    // Get the text before the selected text
    var sElement1 = objTextBox.valu e.substring(0, iCaretPosition-1);

    // We need to keep "/" characters
    if (sFirstElement == DATE_DIVIDER) {
    sElement1 += DATE_DIVIDER;
    }

    // Append the new character
    sElement1 += SPACE_CHARACTER ;

    // Replace the remaining selected text with blank spaces
    for (var i=1; i<objSelectedTe xt.text.length; i++) {
    var sDeletedChar = objSelectedText .text.substring (i, i+1);
    if (sDeletedChar == DATE_DIVIDER) {
    // Keep the slash characters
    sElement1 += DATE_DIVIDER;
    } else {
    // Do not insert extra space if the first selected character is a
    "/"
    if (!(i==1 && sFirstElement == DATE_DIVIDER)) {
    // Replace numbers with a space
    sElement1 += SPACE_CHARACTER ;
    }
    }
    }

    // Get the text after the selected text and append
    var sElement2 = objTextBox.valu e.substring(iCa retPosition +
    objSelectedText .text.length-1, objTextBox.valu e.length);
    sElement1 += sElement2;
    objTextBox.valu e = sElement1;

    iCaretPosition = iCaretPosition+ 1;

    } else {
    // We need to delete character by character
    if (iCaretPosition != 11 || iKeyCode != 46) {

    if (iKeyCode == 46) iCaretPosition = iCaretPosition+ 1;

    if (iCaretPosition != 1 && iCaretPosition != 4 && iCaretPosition
    != 7){
    var sElement1 = objTextBox.valu e.substring(0, iCaretPosition-2);
    var sElement2 = objTextBox.valu e.substring(iCa retPosition-1,
    objTextBox.valu e.length);
    sElement1 += SPACE_CHARACTER ;
    sElement1 += sElement2;
    objTextBox.valu e = sElement1;
    }
    }
    }

    // Put the cursor in the correct position
    objRange = objTextBox.crea teTextRange();
    // Move cursor on 1 if the first selected character is a "/"
    if (bSelectedText && sFirstElement == DATE_DIVIDER) iCaretPosition =
    iCaretPosition+ 1;
    objRange.move(" character", iCaretPosition - 2)
    objRange.select ();

    } // End if key pressed is <Del>

    // If key pressed is <Tab>
    if (iKeyCode != 9) {
    event.returnVal ue = false;
    }
    }


    function getCaretPositio n(objTextBox){
    /* Purpose : Returns the caret position of the cursor
    * in the text box
    *
    * Effects : None
    *
    * Inputs : objTextBox - a text box
    *
    * Returns : Integer indicating the caret position
    * in the text box
    */

    var i = objTextBox.valu e.length+1;

    if (objTextBox.cre ateTextRange){
    objCaret = document.select ion.createRange ().duplicate();
    while (objCaret.paren tElement()==obj TextBox &&
    objCaret.move(" character",1)== 1) --i;
    }

    return i;
    }

    function dateOnPaste(obj TextBox) {
    /* Purpose : Handles paste event
    *
    * Effects : Copies the clipboard value to the text field
    *
    * Inputs : None
    *
    * Returns : None
    */

    var sClipboard = window.clipboar dData.getData(' Text');

    // Validate that the pasted text is in nn/nn/nnnn format
    if (sClipboard.mat ch(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/)) {
    objTextBox.valu e = sClipboard;
    } else {
    // Do not allow paste
    window.event.re turnValue = 0;
    }
    }
  • Dr John Stockton

    #2
    Re: Date validation using onkeydown in Javascript and ASP

    JRS: In article <3591b285.04111 50625.33cf7bf8@ posting.google. com>,
    dated Mon, 15 Nov 2004 06:25:53, seen in news:comp.lang. javascript, Rob
    <rob_tong@hotma il.com> posted :
    [color=blue]
    >Lines: 290[/color]
    [color=blue]
    >I have a date text box (input type = text) in an ASP.NET/Javascript
    >environment. I wanted to force the users to enter dates in a
    >"__/__/____", "dd/mm/yyyy" or similar format. The textbox needs to
    >support normal copy/paste/delete format. There wasn't much on Google
    >to help so (after a bit of toil) though I'd post my suggested solution
    >here. No guarantees I'm afraid; just hope it helps somebody out there.[/color]

    Those paid by the yard, perhaps.

    ISTM better to allow anything to be put in the box and to check it for
    being the right format, /^\d\d\/\d\d\/\d\d\d\d$/, when appropriate. Why
    not do a proper check of the date value, including rejection of day too
    big for month and test within plausible year range? It takes rather
    little code - see newsgroup FAQ & sig below, then js-date4.htm.

    You have apparently allowed your posting agent to wrap code lines. That
    is bad; code for News should be written not to exceed about 72
    chars/line, with line-breaks and indentation added judiciously.
    [color=blue]
    >Here's the ASP source code:
    >
    ><%@ Page Language="vb" AutoEventWireup ="false"
    >Codebehind="We bForm2.aspx.vb" Inherits="WebAp plication1.WebF orm2"%>
    ><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">[/color]

    [color=blue]
    > if (sClipboard.mat ch(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/)) {[/color]

    For [0-9] write \d.
    For dd/mm/yyyy, /^[0-3]\d\/[01]\d\/\d{4}$/ would, for example, reject
    12/25/2004; but if a proper check is done there is no need to RegExp
    specific digits.


    BTW, your
    // Allow key presses of <cursor arrow> or <Home> or <End>
    if ((iKeyCode > 36 && iKeyCode < 41) || (iKeyCode > 34 && iKeyCode <
    37))

    seems odd; does it mean 36 36 37 38 39 40 ?


    Also, it's trivial to be more liberal with the separator; some prefer
    space, dot, or minus. /^\d\d(\D)\d\d\1 \d\d\d\d$/ should allow any
    repeated separator.


    --
    © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
    <URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
    <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
    <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

    Comment

    Working...