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;
}
}
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;
}
}
Comment