var CTRL_PASTE = 22; 
var CTRL_COPY = 3; 
var CTRL_CUT = 24; 
var TAB_KEY = 9; 
var DELETE_KEY = 46; 
var BACKSPACE_KEY = 8; 
var ENTER_KEY = 13; 
var RIGHT_ARROW_KEY = 39; 
var DOWN_ARROW_KEY = 40; 
var UP_ARROW_KEY = 38; 
var LEFT_ARROW_KEY = 37; 
var HOME_KEY = 36; 
var END_KEY = 35; 
var PAGEUP_KEY = 33; 
var PAGEDOWN_KEY = 34; 
var CAPS_LOCK_KEY = 20; 
var ESCAPE_KEY = 27; 

// -------------------------------------------------------------------- 
// Main function 
// Gets the current keystroke and deals with it....lol 
// -------------------------------------------------------------------- 

function tbMask(textBox) { 
var keyCode = event.keyCode; 
// get character from keyCode....dealing with the "Numeric KeyPad" 
// keyCodes so that it can be used 
var keyCharacter = cleanKeyCode(keyCode); 
var retVal = false; 
// grab the mask 
var mask = textBox.mask; 


switch(keyCode) 
{ 
case BACKSPACE_KEY: 
var c = getCursorPos(textBox); 
if(c > 0) { 
var currentMaskChar; 
// get next available char to delete except mask chars 
while(c > 0) { 

c--; 

currentMaskChar = mask.charAt(c); 

if(currentMaskChar == '9' || currentMaskChar == 'X' || currentMaskChar == 'A') { 

// found a spot.....replace that char with '_' 

var x = textBox.value.substring(0,c); 

var y = textBox.value.substring(c+1,textBox.value.length); 

textBox.value = x + '_' + y; 

setCursorPos(textBox,c); 

textBox.curPos = c; 

break; 

} 

} 

} 

break; 

case TAB_KEY: // keep track of cursor b4 tabbing out of field 

var c = getCursorPos(textBox); 

textBox.curPos = c; 

retVal = true; 

break; 

case HOME_KEY: // just move/keep track of cursor 

setCursorPos(textBox,0); 

textBox.curPos = c; 

break; 

case END_KEY: // just move/keep track of cursor 

setCursorPos(textBox,textBox.value.length); 

textBox.curPos = textBox.value.length; 

break; 

case ENTER_KEY: 

retVal = true; 

break; 

case DELETE_KEY: 

var c = getCursorPos(textBox); 

if(c > -1) { 

var currentMaskChar = mask.charAt(c); 

// only allow delete if it's a valid char 

if(currentMaskChar == '9' || currentMaskChar == 'X' || currentMaskChar == 'A') { 

var x = textBox.value.substring(0,c); 

var y = textBox.value.substring(c+1,textBox.value.length); 

textBox.value = x + '_' + y; 

setCursorPos(textBox,c); 

textBox.curPos = c; 

} 

} 

break; 

case LEFT_ARROW_KEY: // just move/keep track of cursor 

var c = getCursorPos(textBox); 

if(c > 0) { 

setCursorPos(textBox,c-1); 

textBox.curPos = c-1; 

} 

break; 

case RIGHT_ARROW_KEY: // just move/keep track of cursor 

var c = getCursorPos(textBox); 

if(c < textBox.value.length) { 

setCursorPos(textBox,c+1); 

textBox.curPos = c+1; 

} 

break; 

default: // adding a new char somewhere in the field 

var c = getCursorPos(textBox); 

var currentMaskChar; 

// get next available to change.....except masking chars 

while(c < textBox.value.length) { 

currentMaskChar = mask.charAt(c); 

if(currentMaskChar == '9' || currentMaskChar == 'X' || currentMaskChar == 'A') break; 

c++; 

} 

switch(currentMaskChar) 

{ 

case '9': // numeric only 

if('0123456789'.indexOf(keyCharacter) != -1) 

addNewKey(textBox,keyCharacter,c); 

break; 

case 'A': // alpha only 

if('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(keyCharacter) != -1) 

addNewKey(textBox,keyCharacter,c); 

break; 

case 'X': // alphanumeric 

if('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.indexOf(keyCharacter) != -1) 

addNewKey(textBox,keyCharacter,c); 

break; 

default: 

break; 

} 

} 



return retVal; 

} 

// -------------------------------------------------------------------- 

// Accept a TextBox, a keycharacter and an integer position 

// adds the key to the position and then sets cursor to next availble spot 

// -------------------------------------------------------------------- 

function addNewKey(tb,key,pos) { 

// add the new key to the textbox at pos 

var startSel = tb.value.substring(0,pos); 

var endSel = tb.value.substring(pos+1,tb.value.length); 

tb.value = startSel + key + endSel; 



// advance cursor to next '_' 

while(pos < tb.value.length) { 

curChar = tb.value.charAt(pos); 

if(curChar == '_') break; 

pos++; 

} 

setCursorPos(tb,pos); 

tb.curPos = pos; 

} 

// -------------------------------------------------------------------- 

// Loops thru pasted value and checks each char against the mask 

// 

// Leaves old value and return false if *any* char is off 

// Creates new masked value if all pasted data is ok 

// -------------------------------------------------------------------- 

function tbPaste(textBox) { 



// grab the textBox value and the mask 

var pastedVal = window.clipboardData.getData("Text"); 

var mask = textBox.mask; 

var newVal = ''; 

var curPastedVal = 0; 



for(var i=0;i<mask.length;i++) 

{ 

var currentMaskChar = mask.charAt(i); 

// if current mask pos allows entry 

if(currentMaskChar == '9' || currentMaskChar == 'X' || currentMaskChar == 'A') 

{ 

var currentPastedChar = pastedVal.charAt(curPastedVal); 

// check each current mask char against new keystroke 

// return false if any are out of sync 

if(currentMaskChar == '9') { 

if('0123456789'.indexOf(currentPastedChar) == -1) 

return false; 

} else if(currentMaskChar == 'A') { 

if('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(currentPastedChar) == -1) 

return false; 

} else if(currentMaskChar == 'X') { 

if('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.indexOf(currentPastedChar) == -1) 

return false; 

} else { 

return false; 

} 



// add new key 

newVal += currentPastedChar; 

curPastedVal++; 

} 

else { 

// add mask literal 

newVal += currentMaskChar; 

} 

} 

textBox.value = newVal; 

return false; 

} 

// -------------------------------------------------------------------- 

// puts masked thingie in tb ie: '(___) ___-____' 

// -------------------------------------------------------------------- 

function tbFocus(textBox) { 

var val = textBox.value; 

var mask = textBox.mask; 

var startVal = ''; 



// give the tb a property set to current cursor pos...sorta used at this point 

// to set cursor pos when re-entering a tb. 

// eventually want to use it to get rid of get/setCursorPos functions...if possible 

if(textBox.curPos == 'undefined' || textBox.curPos == null) 

textBox.curPos = -1; 



// if value null....set the starting format ie: '(___) ___-____' 

if(val.length == 0 || val == null) { 

for(var i = 0; i < mask.length; i++) { 

var c = mask.charAt(i); 

if(c == '9' || c == 'X' || c == 'A') { 

startVal += '_'; 

if(textBox.curPos == -1) textBox.curPos = i; 

} 

else { 

startVal += c; 

} 

} 

textBox.value = startVal; 

} 



// otherwise just set proper cursor pos 

if(textBox.curPos == -1) { 

textBox.curPos = textBox.value.length; 

} 



setCursorPos(textBox,textBox.curPos); 



// set just in case. 

textBox.maxlength = mask.length; 



return true; 

} 

// -------------------------------------------------------------------- 

// The Numeric KeyPad returns keyCodes that ain't all that workable. 

// 

// ie: KeyPad '1' returns keyCode 97 which String.fromCharCode converts to an 'a'. 

// 

// This way allows the Numeric KeyPad to be used 

// -------------------------------------------------------------------- 

function cleanKeyCode(key) 

{ 

switch(key) 

{ 

case 96: return "0"; break; 

case 97: return "1"; break; 

case 98: return "2"; break; 

case 99: return "3"; break; 

case 100: return "4"; break; 

case 101: return "5"; break; 

case 102: return "6"; break; 

case 103: return "7"; break; 

case 104: return "8"; break; 

case 105: return "9"; break; 

default: return String.fromCharCode(key); break; 

} 

} 

// -------------------------------------------------------------------- 

// Google gems 

// -------------------------------------------------------------------- 

function getCursorPos(el){ 

var sel, rng, r2, i=-1; 



if(document.selection && el.createTextRange) { 

sel=document.selection; 

if(sel){ 

r2=sel.createRange(); 

rng=el.createTextRange(); 

rng.setEndPoint("EndToStart", r2); 

i=rng.text.length; 

} 

} 

return i; 

} 

function setCursorPos(field,pos) { 

if (field.createTextRange) { 

var r = field.createTextRange(); 

r.moveStart('character', pos); 

r.collapse(); 

r.select(); 

} 

} 



