R
Rob
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="WebForm2.aspx.vb" Inherits="WebApplication1.WebForm2"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script language="Javascript" src="DateMask.js"></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="dateOnKeyDown()"
onpaste="dateOnPaste(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.srcElement;
var iKeyCode = window.event.keyCode;
var bSelectedText = false;
// Exit if field is read-only
if (window.event.srcElement.readOnly) 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.ctrlKey && (iKeyCode == 67 || iKeyCode == 86 ||
iKeyCode == 88 || iKeyCode == 90)) {
return 1;
}
// Get the position of the cursor
var iCaretPosition = getCaretPosition(objTextBox);
// Get the selected text
var objSelectedText = document.selection.createRange();
// Determine if some text has been selected
if (objSelectedText.parentElement() == objTextBox &&
objSelectedText.text.length > 0)
{
bSelectedText = true;
}
// Get the element next to the cursor (to be used later)
var sFirstElement = objTextBox.value.substring(iCaretPosition,
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.value.substring(iCaretPosition-1,
iCaretPosition);
if (!bSelectedText && sNextElement == SPACE_CHARACTER) {
// Get the text before the cursor
var sElement1 = objTextBox.value.substring(0, iCaretPosition-1);
// Get the text after the cursor
var sElement2 = objTextBox.value.substring(iCaretPosition +
objSelectedText.text.length, objTextBox.value.length);
// Append the new character
sElement1 += String.fromCharCode(iKeyCode);
// Append the text from after the cursor
sElement1 += sElement2;
objTextBox.value = 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.value.substring(0, iCaretPosition-1);
// We need to keep "/" characters
if (sFirstElement == DATE_DIVIDER) {
sElement1 += DATE_DIVIDER;
}
// Append the new character
sElement1 += String.fromCharCode(iKeyCode);
// Replace the remaining selected text with blank spaces
for (var i=1; i<objSelectedText.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.value.substring(iCaretPosition +
objSelectedText.text.length-1, objTextBox.value.length);
sElement1 += sElement2;
objTextBox.value = sElement1;
}
// Put the cursor in the correct position
objSelectedRange = objTextBox.createTextRange();
// Move cursor on 1 if the first selected character is a "/"
if (bSelectedText && sFirstElement == DATE_DIVIDER) iCaretPosition
= iCaretPosition+1;
objSelectedRange.move("character", iCaretPosition)
objSelectedRange.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.value.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<objSelectedText.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.value.substring(iCaretPosition +
objSelectedText.text.length-1, objTextBox.value.length);
sElement1 += sElement2;
objTextBox.value = 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.value.substring(0, iCaretPosition-2);
var sElement2 = objTextBox.value.substring(iCaretPosition-1,
objTextBox.value.length);
sElement1 += SPACE_CHARACTER;
sElement1 += sElement2;
objTextBox.value = sElement1;
}
}
}
// Put the cursor in the correct position
objRange = objTextBox.createTextRange();
// 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.returnValue = false;
}
}
function getCaretPosition(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.value.length+1;
if (objTextBox.createTextRange){
objCaret = document.selection.createRange().duplicate();
while (objCaret.parentElement()==objTextBox &&
objCaret.move("character",1)==1) --i;
}
return i;
}
function dateOnPaste(objTextBox) {
/* Purpose : Handles paste event
*
* Effects : Copies the clipboard value to the text field
*
* Inputs : None
*
* Returns : None
*/
var sClipboard = window.clipboardData.getData('Text');
// Validate that the pasted text is in nn/nn/nnnn format
if (sClipboard.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/)) {
objTextBox.value = sClipboard;
} else {
// Do not allow paste
window.event.returnValue = 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="WebForm2.aspx.vb" Inherits="WebApplication1.WebForm2"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script language="Javascript" src="DateMask.js"></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="dateOnKeyDown()"
onpaste="dateOnPaste(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.srcElement;
var iKeyCode = window.event.keyCode;
var bSelectedText = false;
// Exit if field is read-only
if (window.event.srcElement.readOnly) 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.ctrlKey && (iKeyCode == 67 || iKeyCode == 86 ||
iKeyCode == 88 || iKeyCode == 90)) {
return 1;
}
// Get the position of the cursor
var iCaretPosition = getCaretPosition(objTextBox);
// Get the selected text
var objSelectedText = document.selection.createRange();
// Determine if some text has been selected
if (objSelectedText.parentElement() == objTextBox &&
objSelectedText.text.length > 0)
{
bSelectedText = true;
}
// Get the element next to the cursor (to be used later)
var sFirstElement = objTextBox.value.substring(iCaretPosition,
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.value.substring(iCaretPosition-1,
iCaretPosition);
if (!bSelectedText && sNextElement == SPACE_CHARACTER) {
// Get the text before the cursor
var sElement1 = objTextBox.value.substring(0, iCaretPosition-1);
// Get the text after the cursor
var sElement2 = objTextBox.value.substring(iCaretPosition +
objSelectedText.text.length, objTextBox.value.length);
// Append the new character
sElement1 += String.fromCharCode(iKeyCode);
// Append the text from after the cursor
sElement1 += sElement2;
objTextBox.value = 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.value.substring(0, iCaretPosition-1);
// We need to keep "/" characters
if (sFirstElement == DATE_DIVIDER) {
sElement1 += DATE_DIVIDER;
}
// Append the new character
sElement1 += String.fromCharCode(iKeyCode);
// Replace the remaining selected text with blank spaces
for (var i=1; i<objSelectedText.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.value.substring(iCaretPosition +
objSelectedText.text.length-1, objTextBox.value.length);
sElement1 += sElement2;
objTextBox.value = sElement1;
}
// Put the cursor in the correct position
objSelectedRange = objTextBox.createTextRange();
// Move cursor on 1 if the first selected character is a "/"
if (bSelectedText && sFirstElement == DATE_DIVIDER) iCaretPosition
= iCaretPosition+1;
objSelectedRange.move("character", iCaretPosition)
objSelectedRange.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.value.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<objSelectedText.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.value.substring(iCaretPosition +
objSelectedText.text.length-1, objTextBox.value.length);
sElement1 += sElement2;
objTextBox.value = 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.value.substring(0, iCaretPosition-2);
var sElement2 = objTextBox.value.substring(iCaretPosition-1,
objTextBox.value.length);
sElement1 += SPACE_CHARACTER;
sElement1 += sElement2;
objTextBox.value = sElement1;
}
}
}
// Put the cursor in the correct position
objRange = objTextBox.createTextRange();
// 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.returnValue = false;
}
}
function getCaretPosition(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.value.length+1;
if (objTextBox.createTextRange){
objCaret = document.selection.createRange().duplicate();
while (objCaret.parentElement()==objTextBox &&
objCaret.move("character",1)==1) --i;
}
return i;
}
function dateOnPaste(objTextBox) {
/* Purpose : Handles paste event
*
* Effects : Copies the clipboard value to the text field
*
* Inputs : None
*
* Returns : None
*/
var sClipboard = window.clipboardData.getData('Text');
// Validate that the pasted text is in nn/nn/nnnn format
if (sClipboard.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/)) {
objTextBox.value = sClipboard;
} else {
// Do not allow paste
window.event.returnValue = 0;
}
}