You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by William Hoover <wh...@nemours.org> on 2007/10/18 18:06:20 UTC
Input Text Mask?
Is anyone interested in using the mask script (below) to a component in a Wicket extension? The script prevents invalid input in a text field as the user types (similar to the Atlas version: http://www.fci.com.br/maskedit/MaskEdit/MaskEdit.aspx). I didn't see a component in Wicket that would accomplish this out-of-the-box and thought it would be a cool addition to Wicket.
For example to force the input to mask a phone number:
<input type="text" onfocus="InputTextMask.processMaskFocus(this, "(999)999-9999", true);" />
/**
* InputTextMask script used for mask/regexp operations.
* Mask Individual Character Usage:
* 9 - designates only numeric values
* L - designates only uppercase letter values
* l - designates only lowercase letter values
* A - designates only alphanumeric values
* X - denotes that a custom client script regular expression is specified</li>
* All other characters are assumed to be "special" characters used to mask
* the input component
* Example 1:
* (999)999-9999 only numeric values can be entered where the the character
* position value is 9. Parenthesis and dash are non-editable/mask characters.
* Example 2:
* 99L-ll-X[^A-C]X only numeric values for the first two characters,
* uppercase values for the third character, lowercase letters for the
* fifth/sixth characters, and the last character X[^A-C]X together counts
* as the eighth character regular expression that would allow all characters
* but "A", "B", and "C". Dashes outside the regular expression are
* non-editable/mask characters.
*/
var InputTextMask = {
processMaskFocus: function(input, mask, clearWhenInvalid){
// create an input mask and register it on the specified input (if it hasnt already been added by a previous call
InputTextMask.createInputMask(input, mask, clearWhenInvalid);
if(input.value.length == 0){
// when the input value is empty populate it with the viewing mask and move the cursor to the
// beginning of the input field
var cursorPos = InputTextMask.getCursorPosition(input, input.value);
input.value = input.mask.viewMask;
InputTextMask.moveCursorToPosition(input, null, cursorPos);
}
},
getEvent: function(e) {
// get the event either from the window or from the passed event
return (typeof event != 'undefined')? event: e;
},
handleEventBubble: function(keyEvent, keyCode){
// this method ensures that the key enterned by the user is not propagated unless it is a tab or arrow key
try {
if(keyCode && (keyCode.isTab || keyCode.isLeftOrRightArrow)){
// allow all tab/arrow keys by returning true- no further action required
return true;
}
keyEvent.cancelBubble = true;
if(keyEvent.stopPropagation){
// prevent other event triggers
keyEvent.stopPropagation();
}
if(keyEvent.preventDefault){
// prevent the default event from firing. in this case it is propagation of the keyed input
keyEvent.preventDefault();
}
return false;
} catch(e) {
alert(e.message);
}
},
createInputMask: function(input, mask, clearWhenInvalid) {
// if this input hasnt already registered its mask go ahead and do so now. This only needs to be performed the
// first time the input is encountered when it gains focus. It will attach the MaskType object to the input object
// add add all of the appropriate event listeners to ensure that the mask is applied
if(!input.mask || input.mask.rawMask != mask){
input.mask = new InputTextMask.MaskType(input, mask, clearWhenInvalid);
// add the event listeners that will ensure that when the input contains an incomplete mask it will be remove.
// Also, make sure that the keydown event is fired from this point forward thus invoking the mask format.
if(input.addEventListener){
// most doms
input.addEventListener('blur', function(){input.mask.removeValueWhenInvalid();}, false);
input.addEventListener('keydown', function(e){return input.mask.processMaskFormatting(e);}, false);
if(window.opera){
// in opera- need to ensure that the keypress event isnt interfering with this input mask
input.addEventListener('keypress', function(e){return InputTextMask.handleEventBubble(InputTextMask.getEvent(e), null);}, false);
}
} else if(input.attachEvent) {
// ie
input.attachEvent('onblur', function(){input.mask.removeValueWhenInvalid();});
input.attachEvent('onkeydown', function(e){return input.mask.processMaskFormatting(e);});
} else {
// other browsers that do not support dynamic event propagations
input.onBlur = function(){input.mask.removeValueWhenInvalid();};
input.onKeyDown = function(e){input.mask.processMaskFormatting(e)};
}
}
},
getCursorPosition: function(input, previousValue) {
// gets the current cursor position (s=start, e=end) and creates/returns a new CursorPosition instance
var s, e, r;
if(input.createTextRange){
// ie- need to capture the start/end cursor positions
r = document.selection.createRange().duplicate();
r.moveEnd('character', previousValue.length);
if(r.text === ''){
s = previousValue.length;
} else {
s = previousValue.lastIndexOf(r.text);
}
r = document.selection.createRange().duplicate();
r.moveStart('character', -previousValue.length);
e = r.text.length;
} else {
// other browsers
s = input.selectionStart;
e = input.selectionEnd;
}
return new InputTextMask.CursorPosition(s, e, r, previousValue);
},
moveCursorToPosition: function(input, keyCode, cursorPosition) {
// moves a cursor position for the passed input element to the specified cursor position- because the
// range cursor position is 1 indexed we add an additional space (unless the pressed key is a backspace)
var p = (!keyCode || (keyCode && keyCode.isBackspace))? cursorPosition.start: cursorPosition.start + 1;
if(input.createTextRange){
// ie move- cursor to the index p
cursorPosition.range.move('character', p);
cursorPosition.range.select();
} else {
// other browser- move cursor to the index p
input.selectionStart = p;
input.selectionEnd = p;
}
},
injectValue: function(input, keyCode, cursorPosition) {
// inject the validated key into the input mask at the specified cursor position and return true on success
var key = (keyCode.isBackspace)? '_': input.mask.getValidatedKey(keyCode, cursorPosition);
if(key){
input.value = cursorPosition.previousValue.substring(0, cursorPosition.start) + key + cursorPosition.previousValue.substring(cursorPosition.start + 1, cursorPosition.previousValue.length);
return true;
}
// invalid key
return false;
},
MaskType: function(inputTextElement, mask, clearWhenInvalid) {
// this object instance is holds relative mask properties for a specified input element
this.inputTextElement = inputTextElement;
// designates whether or not the input value is cleared when its mask is incomplete and a blur event is triggered
this.clearWhenInvalid = clearWhenInvalid;
// holds the last validated key code
this.lastValidatedKeyCode = null;
// the mask value used to validate/mask valid input
this.rawMask = mask;
// the mask displayed in the input
this.viewMask = '';
// the string array of all the raw mask values (some indexes contain more than one char so we need to track this)
this.maskArray = new Array();
var mai = 0;
var regexp = '';
// cycle through the raw mask and perform view mask conversions
for(var i=0; i<mask.length; i++){
if(regexp){
if(regexp == 'X'){
// end of current regexp slot
regexp = '';
}
if(mask.charAt(i) == 'X'){
// current mask array index contains the complete regexp so we need to store it in the array
this.maskArray[mai] = regexp;
mai++;
regexp = null;
} else {
// still in the middle of the regexp keep adding the current character to the regexp
regexp += mask.charAt(i);
}
} else if(mask.charAt(i) == 'X'){
// current slot is a regexp
regexp += 'X';
this.viewMask += '_';
} else if(mask.charAt(i) == '9' || mask.charAt(i) == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
// the current mask character is one of the predefined/reserved characters
this.viewMask += '_';
this.maskArray[mai] = mask.charAt(i);
mai++;
} else {
// just a regular char
this.viewMask += mask.charAt(i);
this.maskArray[mai] = mask.charAt(i);
mai++;
}
}
// the predefined/reserved characters need to be replaced with the viewing mask char that desigantes an editable value (underscore)
this.specialChars = this.viewMask.replace(/(L|l|9|A|_|X)/g,'');
this.getValidatedKey = function(keyCode, cursorPosition) {
// validates if the passed key code is valid for the specified cursor position and returns the value if it is. otherwise, return false
var maskKey = this.maskArray[cursorPosition.start];
if(maskKey == '9'){
// only allow numbers at the specified slot
return keyCode.pressedKey.match(/[0-9]/);
} else if(maskKey == 'L'){
// only allow uppercase letters at specified slot (convert if necessary)
return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toUpperCase(): null;
} else if(maskKey == 'l'){
// only allow lowercase letters at specified slot (convert if necessary)
return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toLowerCase(): null;
} else {
if(maskKey == 'A'){
// only allow alpha-numeric values at the specified slot
return keyCode.pressedKey.match(/[A-Za-z0-9]/);
} else {
// only allow values that are verified by the specified regexp at the specified slot
return (this.maskArray[cursorPosition.start].length > 1)? keyCode.pressedKey.match(new RegExp(maskKey)): null;
}
}
};
this.removeValueWhenInvalid = function(){
// removes value from the input element when the mask is incomplete
if(this.inputTextElement.value.indexOf('_') > -1){
this.inputTextElement.value = '';
}
};
this.processMaskFormatting = function(e) {
// capture event (should be the keydown event)
var onKeyDownEvent = InputTextMask.getEvent(e);
// create the key code from the event.
var keyCode = new InputTextMask.KeyCode(onKeyDownEvent);
if(InputTextMask.handleEventBubble(onKeyDownEvent, keyCode)){
// the pressed key is allowed to propagate- no mask injection required
return true;
}
var v = this.inputTextElement.value;
if(v.length === 0){
// when the input value is empty populate it with the viewing mask
this.inputTextElement.value = this.viewMask;
}
var cursorPos = InputTextMask.getCursorPosition(this.inputTextElement, v);
if(cursorPos.end == cursorPos.previousValue.length && !keyCode.isBackspace){
// input cursor position is at the end of the mask- do not allow any more characters to be keyed
return false;
}
// move the cursor position to the next slot that does not contain a mask character
while(this.inputTextElement.mask.specialChars.match(RegExp.escape(cursorPos.previousValue.charAt(((keyCode.isBackspace)? cursorPos.start-1: cursorPos.start))))){
if(keyCode.isBackspace) {
// backspace needs to move the cursor backwards
cursorPos.decStart();
} else {
// still moving cursor one space to the right
cursorPos.incStart();
}
if(cursorPos.start >= cursorPos.previousValue.length || cursorPos.start < 0){
// end of the mask- no more keys should be keyed
return false;
}
}
if(keyCode.isBackspace){
// need to go back one space to the left
cursorPos.decStart();
}
// inject the key that was pressed into the input value mask
if(InputTextMask.injectValue(this.inputTextElement, keyCode, cursorPos)){
// when the injection is sucessful move the cursor to the next slot to the right of the injected key
InputTextMask.moveCursorToPosition(this.inputTextElement, keyCode, cursorPos);
}
// because the pressed key is being injected we always need to return false to prevent duplicate
// key injection
return false;
};
},
KeyCode: function(onKeyDownEvent) {
this.onKeyDownEvent = onKeyDownEvent;
// get the unicode value from the key event
this.unicode = onKeyDownEvent.which? onKeyDownEvent.which: (onKeyDownEvent.keyCode? onKeyDownEvent.keyCode: (onKeyDownEvent.charCode? onKeyDownEvent.charCode: 0));
this.isShiftPressed = onKeyDownEvent.shiftKey == false || onKeyDownEvent.shiftKey == true? onKeyDownEvent.shiftKey: (onKeyDownEvent.modifiers && (onKeyDownEvent.modifiers & 4)); //bitWise AND
// TODO : need to get cap lock capture for onkeydown event
//this.isCapLock = ((!this.isShiftPressed && this.unicode >= 65 && this.unicode <= 90) || (this.unicode >= 97 && this.unicode <= 122 && this.isShiftPressed));
if(this.unicode >= 96 && this.unicode <= 105) {
this.unicode -= 48; // handle number keypad
}
if(this.unicode >= 65 && this.unicode <= 90 && !this.isShiftPressed){
this.unicode += 32; // handle uppercase
}
this.isTab = (this.unicode == 9)? true: false;
this.isBackspace = (this.unicode == 8)? true: false;
this.isLeftOrRightArrow = (this.unicode == 37 || this.unicode == 39)? true: false;
// capture the actual key for the passed key code
this.pressedKey = String.fromCharCode(this.unicode);
},
CursorPosition: function(start, end, range, previousValue) {
// holds the cursor position values
this.start = isNaN(start)? 0: start;
this.end = isNaN(end)? 0: end;
this.range = range;
this.previousValue = previousValue;
this.incStart = function(){
this.start++;
};
this.decStart = function(){
this.start--;
};
}
};
// Add escape prototype feature to RegExp object
// text.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0');
// text.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
if(!RegExp.escape) {
RegExp.escape = function(text){
var sp;
if(!arguments.callee.sRE){
sp=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
arguments.callee.sRE = new RegExp('(\\' + sp.join('|\\') + ')','g');
}
return text.replace(arguments.callee.sRE, '\\$1');
};
}
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Input Text Mask?
Posted by Eelco Hillenius <ee...@gmail.com>.
On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> Okay, sounds good... I assume I will be notified on which approach that will be decided by the committers at some point in the process?
Of course. We'll discuss in public anyway.
Eelco
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
RE: Input Text Mask?
Posted by William Hoover <wh...@nemours.org>.
Okay, sounds good... I assume I will be notified on which approach that will be decided by the committers at some point in the process?
-----Original Message-----
From: Eelco Hillenius [mailto:eelco.hillenius@gmail.com]
Sent: Thursday, October 18, 2007 5:08 PM
To: users@wicket.apache.org
Subject: Re: Input Text Mask?
On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> I created a Jira Issue (https://issues.apache.org/jira/browse/WICKET-1085) with attached source. I placed the issue under extensions as others suggested.
Thanks.
> Would I still have to go through sf.net?
It would either be put in wicket-stuff minis - in which case you can
maintain it directly yourself after you get access to the wicket-stuff
project - or if we want to use it for the date field components, and
all comitters agree, we can put it in extensions.
Eelco
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Input Text Mask?
Posted by Eelco Hillenius <ee...@gmail.com>.
On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> I created a Jira Issue (https://issues.apache.org/jira/browse/WICKET-1085) with attached source. I placed the issue under extensions as others suggested.
Thanks.
> Would I still have to go through sf.net?
It would either be put in wicket-stuff minis - in which case you can
maintain it directly yourself after you get access to the wicket-stuff
project - or if we want to use it for the date field components, and
all comitters agree, we can put it in extensions.
Eelco
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
RE: Input Text Mask?
Posted by William Hoover <wh...@nemours.org>.
I created a Jira Issue (https://issues.apache.org/jira/browse/WICKET-1085) with attached source. I placed the issue under extensions as others suggested. Would I still have to go through sf.net?
-----Original Message-----
From: Igor Vaynberg [mailto:igor.vaynberg@gmail.com]
Sent: Thursday, October 18, 2007 3:57 PM
To: users@wicket.apache.org
Subject: Re: Input Text Mask?
create a sf.net account and i will give you commit access to wicketstuff repo.
-igor
On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> Sure. How would I go about doing so?
>
> -----Original Message-----
> From: Igor Vaynberg [mailto:igor.vaynberg@gmail.com]
> Sent: Thursday, October 18, 2007 1:11 PM
> To: users@wicket.apache.org
> Subject: Re: Input Text Mask?
>
>
> would you be interested in making this a subclass of textfield and
> throwing it into wicketstuff-minis project which is in wicket-stuff?
>
> -igor
>
>
> On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> > Is anyone interested in using the mask script (below) to a component in a Wicket extension? The script prevents invalid input in a text field as the user types (similar to the Atlas version: http://www.fci.com.br/maskedit/MaskEdit/MaskEdit.aspx). I didn't see a component in Wicket that would accomplish this out-of-the-box and thought it would be a cool addition to Wicket.
> >
> > For example to force the input to mask a phone number:
> > <input type="text" onfocus="InputTextMask.processMaskFocus(this, "(999)999-9999", true);" />
> >
> > /**
> > * InputTextMask script used for mask/regexp operations.
> > * Mask Individual Character Usage:
> > * 9 - designates only numeric values
> > * L - designates only uppercase letter values
> > * l - designates only lowercase letter values
> > * A - designates only alphanumeric values
> > * X - denotes that a custom client script regular expression is specified</li>
> > * All other characters are assumed to be "special" characters used to mask
> > * the input component
> > * Example 1:
> > * (999)999-9999 only numeric values can be entered where the the character
> > * position value is 9. Parenthesis and dash are non-editable/mask characters.
> > * Example 2:
> > * 99L-ll-X[^A-C]X only numeric values for the first two characters,
> > * uppercase values for the third character, lowercase letters for the
> > * fifth/sixth characters, and the last character X[^A-C]X together counts
> > * as the eighth character regular expression that would allow all characters
> > * but "A", "B", and "C". Dashes outside the regular expression are
> > * non-editable/mask characters.
> > */
> > var InputTextMask = {
> > processMaskFocus: function(input, mask, clearWhenInvalid){
> > // create an input mask and register it on the specified input (if it hasnt already been added by a previous call
> > InputTextMask.createInputMask(input, mask, clearWhenInvalid);
> > if(input.value.length == 0){
> > // when the input value is empty populate it with the viewing mask and move the cursor to the
> > // beginning of the input field
> > var cursorPos = InputTextMask.getCursorPosition(input, input.value);
> > input.value = input.mask.viewMask;
> > InputTextMask.moveCursorToPosition(input, null, cursorPos);
> > }
> > },
> > getEvent: function(e) {
> > // get the event either from the window or from the passed event
> > return (typeof event != 'undefined')? event: e;
> > },
> > handleEventBubble: function(keyEvent, keyCode){
> > // this method ensures that the key enterned by the user is not propagated unless it is a tab or arrow key
> > try {
> > if(keyCode && (keyCode.isTab || keyCode.isLeftOrRightArrow)){
> > // allow all tab/arrow keys by returning true- no further action required
> > return true;
> > }
> > keyEvent.cancelBubble = true;
> > if(keyEvent.stopPropagation){
> > // prevent other event triggers
> > keyEvent.stopPropagation();
> > }
> > if(keyEvent.preventDefault){
> > // prevent the default event from firing. in this case it is propagation of the keyed input
> > keyEvent.preventDefault();
> > }
> > return false;
> > } catch(e) {
> > alert(e.message);
> > }
> > },
> > createInputMask: function(input, mask, clearWhenInvalid) {
> > // if this input hasnt already registered its mask go ahead and do so now. This only needs to be performed the
> > // first time the input is encountered when it gains focus. It will attach the MaskType object to the input object
> > // add add all of the appropriate event listeners to ensure that the mask is applied
> > if(!input.mask || input.mask.rawMask != mask){
> > input.mask = new InputTextMask.MaskType(input, mask, clearWhenInvalid);
> > // add the event listeners that will ensure that when the input contains an incomplete mask it will be remove.
> > // Also, make sure that the keydown event is fired from this point forward thus invoking the mask format.
> > if(input.addEventListener){
> > // most doms
> > input.addEventListener('blur', function(){input.mask.removeValueWhenInvalid();}, false);
> > input.addEventListener('keydown', function(e){return input.mask.processMaskFormatting(e);}, false);
> > if(window.opera){
> > // in opera- need to ensure that the keypress event isnt interfering with this input mask
> > input.addEventListener('keypress', function(e){return InputTextMask.handleEventBubble(InputTextMask.getEvent(e), null);}, false);
> > }
> > } else if(input.attachEvent) {
> > // ie
> > input.attachEvent('onblur', function(){input.mask.removeValueWhenInvalid();});
> > input.attachEvent('onkeydown', function(e){return input.mask.processMaskFormatting(e);});
> > } else {
> > // other browsers that do not support dynamic event propagations
> > input.onBlur = function(){input.mask.removeValueWhenInvalid();};
> > input.onKeyDown = function(e){input.mask.processMaskFormatting(e)};
> > }
> > }
> > },
> > getCursorPosition: function(input, previousValue) {
> > // gets the current cursor position (s=start, e=end) and creates/returns a new CursorPosition instance
> > var s, e, r;
> > if(input.createTextRange){
> > // ie- need to capture the start/end cursor positions
> > r = document.selection.createRange().duplicate();
> > r.moveEnd('character', previousValue.length);
> > if(r.text === ''){
> > s = previousValue.length;
> > } else {
> > s = previousValue.lastIndexOf(r.text);
> > }
> > r = document.selection.createRange().duplicate();
> > r.moveStart('character', -previousValue.length);
> > e = r.text.length;
> > } else {
> > // other browsers
> > s = input.selectionStart;
> > e = input.selectionEnd;
> > }
> > return new InputTextMask.CursorPosition(s, e, r, previousValue);
> > },
> > moveCursorToPosition: function(input, keyCode, cursorPosition) {
> > // moves a cursor position for the passed input element to the specified cursor position- because the
> > // range cursor position is 1 indexed we add an additional space (unless the pressed key is a backspace)
> > var p = (!keyCode || (keyCode && keyCode.isBackspace))? cursorPosition.start: cursorPosition.start + 1;
> > if(input.createTextRange){
> > // ie move- cursor to the index p
> > cursorPosition.range.move('character', p);
> > cursorPosition.range.select();
> > } else {
> > // other browser- move cursor to the index p
> > input.selectionStart = p;
> > input.selectionEnd = p;
> > }
> > },
> > injectValue: function(input, keyCode, cursorPosition) {
> > // inject the validated key into the input mask at the specified cursor position and return true on success
> > var key = (keyCode.isBackspace)? '_': input.mask.getValidatedKey(keyCode, cursorPosition);
> > if(key){
> > input.value = cursorPosition.previousValue.substring(0, cursorPosition.start) + key + cursorPosition.previousValue.substring(cursorPosition.start + 1, cursorPosition.previousValue.length);
> > return true;
> > }
> > // invalid key
> > return false;
> > },
> > MaskType: function(inputTextElement, mask, clearWhenInvalid) {
> > // this object instance is holds relative mask properties for a specified input element
> > this.inputTextElement = inputTextElement;
> > // designates whether or not the input value is cleared when its mask is incomplete and a blur event is triggered
> > this.clearWhenInvalid = clearWhenInvalid;
> > // holds the last validated key code
> > this.lastValidatedKeyCode = null;
> > // the mask value used to validate/mask valid input
> > this.rawMask = mask;
> > // the mask displayed in the input
> > this.viewMask = '';
> > // the string array of all the raw mask values (some indexes contain more than one char so we need to track this)
> > this.maskArray = new Array();
> > var mai = 0;
> > var regexp = '';
> > // cycle through the raw mask and perform view mask conversions
> > for(var i=0; i<mask.length; i++){
> > if(regexp){
> > if(regexp == 'X'){
> > // end of current regexp slot
> > regexp = '';
> > }
> > if(mask.charAt(i) == 'X'){
> > // current mask array index contains the complete regexp so we need to store it in the array
> > this.maskArray[mai] = regexp;
> > mai++;
> > regexp = null;
> > } else {
> > // still in the middle of the regexp keep adding the current character to the regexp
> > regexp += mask.charAt(i);
> > }
> > } else if(mask.charAt(i) == 'X'){
> > // current slot is a regexp
> > regexp += 'X';
> > this.viewMask += '_';
> > } else if(mask.charAt(i) == '9' || mask.charAt(i) == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
> > // the current mask character is one of the predefined/reserved characters
> > this.viewMask += '_';
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > } else {
> > // just a regular char
> > this.viewMask += mask.charAt(i);
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > }
> > }
> > // the predefined/reserved characters need to be replaced with the viewing mask char that desigantes an editable value (underscore)
> > this.specialChars = this.viewMask.replace(/(L|l|9|A|_|X)/g,'');
> > this.getValidatedKey = function(keyCode, cursorPosition) {
> > // validates if the passed key code is valid for the specified cursor position and returns the value if it is. otherwise, return false
> > var maskKey = this.maskArray[cursorPosition.start];
> > if(maskKey == '9'){
> > // only allow numbers at the specified slot
> > return keyCode.pressedKey.match(/[0-9]/);
> > } else if(maskKey == 'L'){
> > // only allow uppercase letters at specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toUpperCase(): null;
> > } else if(maskKey == 'l'){
> > // only allow lowercase letters at specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toLowerCase(): null;
> > } else {
> > if(maskKey == 'A'){
> > // only allow alpha-numeric values at the specified slot
> > return keyCode.pressedKey.match(/[A-Za-z0-9]/);
> > } else {
> > // only allow values that are verified by the specified regexp at the specified slot
> > return (this.maskArray[cursorPosition.start].length > 1)? keyCode.pressedKey.match(new RegExp(maskKey)): null;
> > }
> > }
> > };
> > this.removeValueWhenInvalid = function(){
> > // removes value from the input element when the mask is incomplete
> > if(this.inputTextElement.value.indexOf('_') > -1){
> > this.inputTextElement.value = '';
> > }
> > };
> > this.processMaskFormatting = function(e) {
> > // capture event (should be the keydown event)
> > var onKeyDownEvent = InputTextMask.getEvent(e);
> > // create the key code from the event.
> > var keyCode = new InputTextMask.KeyCode(onKeyDownEvent);
> > if(InputTextMask.handleEventBubble(onKeyDownEvent, keyCode)){
> > // the pressed key is allowed to propagate- no mask injection required
> > return true;
> > }
> > var v = this.inputTextElement.value;
> > if(v.length === 0){
> > // when the input value is empty populate it with the viewing mask
> > this.inputTextElement.value = this.viewMask;
> > }
> > var cursorPos = InputTextMask.getCursorPosition(this.inputTextElement, v);
> > if(cursorPos.end == cursorPos.previousValue.length && !keyCode.isBackspace){
> > // input cursor position is at the end of the mask- do not allow any more characters to be keyed
> > return false;
> > }
> > // move the cursor position to the next slot that does not contain a mask character
> > while(this.inputTextElement.mask.specialChars.match(RegExp.escape(cursorPos.previousValue.charAt(((keyCode.isBackspace)? cursorPos.start-1: cursorPos.start))))){
> > if(keyCode.isBackspace) {
> > // backspace needs to move the cursor backwards
> > cursorPos.decStart();
> > } else {
> > // still moving cursor one space to the right
> > cursorPos.incStart();
> > }
> > if(cursorPos.start >= cursorPos.previousValue.length || cursorPos.start < 0){
> > // end of the mask- no more keys should be keyed
> > return false;
> > }
> > }
> > if(keyCode.isBackspace){
> > // need to go back one space to the left
> > cursorPos.decStart();
> > }
> > // inject the key that was pressed into the input value mask
> > if(InputTextMask.injectValue(this.inputTextElement, keyCode, cursorPos)){
> > // when the injection is sucessful move the cursor to the next slot to the right of the injected key
> > InputTextMask.moveCursorToPosition(this.inputTextElement, keyCode, cursorPos);
> > }
> > // because the pressed key is being injected we always need to return false to prevent duplicate
> > // key injection
> > return false;
> > };
> > },
> > KeyCode: function(onKeyDownEvent) {
> > this.onKeyDownEvent = onKeyDownEvent;
> > // get the unicode value from the key event
> > this.unicode = onKeyDownEvent.which? onKeyDownEvent.which: (onKeyDownEvent.keyCode? onKeyDownEvent.keyCode: (onKeyDownEvent.charCode? onKeyDownEvent.charCode: 0));
> > this.isShiftPressed = onKeyDownEvent.shiftKey == false || onKeyDownEvent.shiftKey == true? onKeyDownEvent.shiftKey: (onKeyDownEvent.modifiers && (onKeyDownEvent.modifiers & 4)); //bitWise AND
> > // TODO : need to get cap lock capture for onkeydown event
> > //this.isCapLock = ((!this.isShiftPressed && this.unicode >= 65 && this.unicode <= 90) || (this.unicode >= 97 && this.unicode <= 122 && this.isShiftPressed));
> > if(this.unicode >= 96 && this.unicode <= 105) {
> > this.unicode -= 48; // handle number keypad
> > }
> > if(this.unicode >= 65 && this.unicode <= 90 && !this.isShiftPressed){
> > this.unicode += 32; // handle uppercase
> > }
> > this.isTab = (this.unicode == 9)? true: false;
> > this.isBackspace = (this.unicode == 8)? true: false;
> > this.isLeftOrRightArrow = (this.unicode == 37 || this.unicode == 39)? true: false;
> > // capture the actual key for the passed key code
> > this.pressedKey = String.fromCharCode(this.unicode);
> > },
> > CursorPosition: function(start, end, range, previousValue) {
> > // holds the cursor position values
> > this.start = isNaN(start)? 0: start;
> > this.end = isNaN(end)? 0: end;
> > this.range = range;
> > this.previousValue = previousValue;
> > this.incStart = function(){
> > this.start++;
> > };
> > this.decStart = function(){
> > this.start--;
> > };
> > }
> > };
> > // Add escape prototype feature to RegExp object
> > // text.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0');
> > // text.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
> > if(!RegExp.escape) {
> > RegExp.escape = function(text){
> > var sp;
> > if(!arguments.callee.sRE){
> > sp=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
> > arguments.callee.sRE = new RegExp('(\\' + sp.join('|\\') + ')','g');
> > }
> > return text.replace(arguments.callee.sRE, '\\$1');
> > };
> > }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Input Text Mask?
Posted by Igor Vaynberg <ig...@gmail.com>.
create a sf.net account and i will give you commit access to wicketstuff repo.
-igor
On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> Sure. How would I go about doing so?
>
> -----Original Message-----
> From: Igor Vaynberg [mailto:igor.vaynberg@gmail.com]
> Sent: Thursday, October 18, 2007 1:11 PM
> To: users@wicket.apache.org
> Subject: Re: Input Text Mask?
>
>
> would you be interested in making this a subclass of textfield and
> throwing it into wicketstuff-minis project which is in wicket-stuff?
>
> -igor
>
>
> On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> > Is anyone interested in using the mask script (below) to a component in a Wicket extension? The script prevents invalid input in a text field as the user types (similar to the Atlas version: http://www.fci.com.br/maskedit/MaskEdit/MaskEdit.aspx). I didn't see a component in Wicket that would accomplish this out-of-the-box and thought it would be a cool addition to Wicket.
> >
> > For example to force the input to mask a phone number:
> > <input type="text" onfocus="InputTextMask.processMaskFocus(this, "(999)999-9999", true);" />
> >
> > /**
> > * InputTextMask script used for mask/regexp operations.
> > * Mask Individual Character Usage:
> > * 9 - designates only numeric values
> > * L - designates only uppercase letter values
> > * l - designates only lowercase letter values
> > * A - designates only alphanumeric values
> > * X - denotes that a custom client script regular expression is specified</li>
> > * All other characters are assumed to be "special" characters used to mask
> > * the input component
> > * Example 1:
> > * (999)999-9999 only numeric values can be entered where the the character
> > * position value is 9. Parenthesis and dash are non-editable/mask characters.
> > * Example 2:
> > * 99L-ll-X[^A-C]X only numeric values for the first two characters,
> > * uppercase values for the third character, lowercase letters for the
> > * fifth/sixth characters, and the last character X[^A-C]X together counts
> > * as the eighth character regular expression that would allow all characters
> > * but "A", "B", and "C". Dashes outside the regular expression are
> > * non-editable/mask characters.
> > */
> > var InputTextMask = {
> > processMaskFocus: function(input, mask, clearWhenInvalid){
> > // create an input mask and register it on the specified input (if it hasnt already been added by a previous call
> > InputTextMask.createInputMask(input, mask, clearWhenInvalid);
> > if(input.value.length == 0){
> > // when the input value is empty populate it with the viewing mask and move the cursor to the
> > // beginning of the input field
> > var cursorPos = InputTextMask.getCursorPosition(input, input.value);
> > input.value = input.mask.viewMask;
> > InputTextMask.moveCursorToPosition(input, null, cursorPos);
> > }
> > },
> > getEvent: function(e) {
> > // get the event either from the window or from the passed event
> > return (typeof event != 'undefined')? event: e;
> > },
> > handleEventBubble: function(keyEvent, keyCode){
> > // this method ensures that the key enterned by the user is not propagated unless it is a tab or arrow key
> > try {
> > if(keyCode && (keyCode.isTab || keyCode.isLeftOrRightArrow)){
> > // allow all tab/arrow keys by returning true- no further action required
> > return true;
> > }
> > keyEvent.cancelBubble = true;
> > if(keyEvent.stopPropagation){
> > // prevent other event triggers
> > keyEvent.stopPropagation();
> > }
> > if(keyEvent.preventDefault){
> > // prevent the default event from firing. in this case it is propagation of the keyed input
> > keyEvent.preventDefault();
> > }
> > return false;
> > } catch(e) {
> > alert(e.message);
> > }
> > },
> > createInputMask: function(input, mask, clearWhenInvalid) {
> > // if this input hasnt already registered its mask go ahead and do so now. This only needs to be performed the
> > // first time the input is encountered when it gains focus. It will attach the MaskType object to the input object
> > // add add all of the appropriate event listeners to ensure that the mask is applied
> > if(!input.mask || input.mask.rawMask != mask){
> > input.mask = new InputTextMask.MaskType(input, mask, clearWhenInvalid);
> > // add the event listeners that will ensure that when the input contains an incomplete mask it will be remove.
> > // Also, make sure that the keydown event is fired from this point forward thus invoking the mask format.
> > if(input.addEventListener){
> > // most doms
> > input.addEventListener('blur', function(){input.mask.removeValueWhenInvalid();}, false);
> > input.addEventListener('keydown', function(e){return input.mask.processMaskFormatting(e);}, false);
> > if(window.opera){
> > // in opera- need to ensure that the keypress event isnt interfering with this input mask
> > input.addEventListener('keypress', function(e){return InputTextMask.handleEventBubble(InputTextMask.getEvent(e), null);}, false);
> > }
> > } else if(input.attachEvent) {
> > // ie
> > input.attachEvent('onblur', function(){input.mask.removeValueWhenInvalid();});
> > input.attachEvent('onkeydown', function(e){return input.mask.processMaskFormatting(e);});
> > } else {
> > // other browsers that do not support dynamic event propagations
> > input.onBlur = function(){input.mask.removeValueWhenInvalid();};
> > input.onKeyDown = function(e){input.mask.processMaskFormatting(e)};
> > }
> > }
> > },
> > getCursorPosition: function(input, previousValue) {
> > // gets the current cursor position (s=start, e=end) and creates/returns a new CursorPosition instance
> > var s, e, r;
> > if(input.createTextRange){
> > // ie- need to capture the start/end cursor positions
> > r = document.selection.createRange().duplicate();
> > r.moveEnd('character', previousValue.length);
> > if(r.text === ''){
> > s = previousValue.length;
> > } else {
> > s = previousValue.lastIndexOf(r.text);
> > }
> > r = document.selection.createRange().duplicate();
> > r.moveStart('character', -previousValue.length);
> > e = r.text.length;
> > } else {
> > // other browsers
> > s = input.selectionStart;
> > e = input.selectionEnd;
> > }
> > return new InputTextMask.CursorPosition(s, e, r, previousValue);
> > },
> > moveCursorToPosition: function(input, keyCode, cursorPosition) {
> > // moves a cursor position for the passed input element to the specified cursor position- because the
> > // range cursor position is 1 indexed we add an additional space (unless the pressed key is a backspace)
> > var p = (!keyCode || (keyCode && keyCode.isBackspace))? cursorPosition.start: cursorPosition.start + 1;
> > if(input.createTextRange){
> > // ie move- cursor to the index p
> > cursorPosition.range.move('character', p);
> > cursorPosition.range.select();
> > } else {
> > // other browser- move cursor to the index p
> > input.selectionStart = p;
> > input.selectionEnd = p;
> > }
> > },
> > injectValue: function(input, keyCode, cursorPosition) {
> > // inject the validated key into the input mask at the specified cursor position and return true on success
> > var key = (keyCode.isBackspace)? '_': input.mask.getValidatedKey(keyCode, cursorPosition);
> > if(key){
> > input.value = cursorPosition.previousValue.substring(0, cursorPosition.start) + key + cursorPosition.previousValue.substring(cursorPosition.start + 1, cursorPosition.previousValue.length);
> > return true;
> > }
> > // invalid key
> > return false;
> > },
> > MaskType: function(inputTextElement, mask, clearWhenInvalid) {
> > // this object instance is holds relative mask properties for a specified input element
> > this.inputTextElement = inputTextElement;
> > // designates whether or not the input value is cleared when its mask is incomplete and a blur event is triggered
> > this.clearWhenInvalid = clearWhenInvalid;
> > // holds the last validated key code
> > this.lastValidatedKeyCode = null;
> > // the mask value used to validate/mask valid input
> > this.rawMask = mask;
> > // the mask displayed in the input
> > this.viewMask = '';
> > // the string array of all the raw mask values (some indexes contain more than one char so we need to track this)
> > this.maskArray = new Array();
> > var mai = 0;
> > var regexp = '';
> > // cycle through the raw mask and perform view mask conversions
> > for(var i=0; i<mask.length; i++){
> > if(regexp){
> > if(regexp == 'X'){
> > // end of current regexp slot
> > regexp = '';
> > }
> > if(mask.charAt(i) == 'X'){
> > // current mask array index contains the complete regexp so we need to store it in the array
> > this.maskArray[mai] = regexp;
> > mai++;
> > regexp = null;
> > } else {
> > // still in the middle of the regexp keep adding the current character to the regexp
> > regexp += mask.charAt(i);
> > }
> > } else if(mask.charAt(i) == 'X'){
> > // current slot is a regexp
> > regexp += 'X';
> > this.viewMask += '_';
> > } else if(mask.charAt(i) == '9' || mask.charAt(i) == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
> > // the current mask character is one of the predefined/reserved characters
> > this.viewMask += '_';
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > } else {
> > // just a regular char
> > this.viewMask += mask.charAt(i);
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > }
> > }
> > // the predefined/reserved characters need to be replaced with the viewing mask char that desigantes an editable value (underscore)
> > this.specialChars = this.viewMask.replace(/(L|l|9|A|_|X)/g,'');
> > this.getValidatedKey = function(keyCode, cursorPosition) {
> > // validates if the passed key code is valid for the specified cursor position and returns the value if it is. otherwise, return false
> > var maskKey = this.maskArray[cursorPosition.start];
> > if(maskKey == '9'){
> > // only allow numbers at the specified slot
> > return keyCode.pressedKey.match(/[0-9]/);
> > } else if(maskKey == 'L'){
> > // only allow uppercase letters at specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toUpperCase(): null;
> > } else if(maskKey == 'l'){
> > // only allow lowercase letters at specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toLowerCase(): null;
> > } else {
> > if(maskKey == 'A'){
> > // only allow alpha-numeric values at the specified slot
> > return keyCode.pressedKey.match(/[A-Za-z0-9]/);
> > } else {
> > // only allow values that are verified by the specified regexp at the specified slot
> > return (this.maskArray[cursorPosition.start].length > 1)? keyCode.pressedKey.match(new RegExp(maskKey)): null;
> > }
> > }
> > };
> > this.removeValueWhenInvalid = function(){
> > // removes value from the input element when the mask is incomplete
> > if(this.inputTextElement.value.indexOf('_') > -1){
> > this.inputTextElement.value = '';
> > }
> > };
> > this.processMaskFormatting = function(e) {
> > // capture event (should be the keydown event)
> > var onKeyDownEvent = InputTextMask.getEvent(e);
> > // create the key code from the event.
> > var keyCode = new InputTextMask.KeyCode(onKeyDownEvent);
> > if(InputTextMask.handleEventBubble(onKeyDownEvent, keyCode)){
> > // the pressed key is allowed to propagate- no mask injection required
> > return true;
> > }
> > var v = this.inputTextElement.value;
> > if(v.length === 0){
> > // when the input value is empty populate it with the viewing mask
> > this.inputTextElement.value = this.viewMask;
> > }
> > var cursorPos = InputTextMask.getCursorPosition(this.inputTextElement, v);
> > if(cursorPos.end == cursorPos.previousValue.length && !keyCode.isBackspace){
> > // input cursor position is at the end of the mask- do not allow any more characters to be keyed
> > return false;
> > }
> > // move the cursor position to the next slot that does not contain a mask character
> > while(this.inputTextElement.mask.specialChars.match(RegExp.escape(cursorPos.previousValue.charAt(((keyCode.isBackspace)? cursorPos.start-1: cursorPos.start))))){
> > if(keyCode.isBackspace) {
> > // backspace needs to move the cursor backwards
> > cursorPos.decStart();
> > } else {
> > // still moving cursor one space to the right
> > cursorPos.incStart();
> > }
> > if(cursorPos.start >= cursorPos.previousValue.length || cursorPos.start < 0){
> > // end of the mask- no more keys should be keyed
> > return false;
> > }
> > }
> > if(keyCode.isBackspace){
> > // need to go back one space to the left
> > cursorPos.decStart();
> > }
> > // inject the key that was pressed into the input value mask
> > if(InputTextMask.injectValue(this.inputTextElement, keyCode, cursorPos)){
> > // when the injection is sucessful move the cursor to the next slot to the right of the injected key
> > InputTextMask.moveCursorToPosition(this.inputTextElement, keyCode, cursorPos);
> > }
> > // because the pressed key is being injected we always need to return false to prevent duplicate
> > // key injection
> > return false;
> > };
> > },
> > KeyCode: function(onKeyDownEvent) {
> > this.onKeyDownEvent = onKeyDownEvent;
> > // get the unicode value from the key event
> > this.unicode = onKeyDownEvent.which? onKeyDownEvent.which: (onKeyDownEvent.keyCode? onKeyDownEvent.keyCode: (onKeyDownEvent.charCode? onKeyDownEvent.charCode: 0));
> > this.isShiftPressed = onKeyDownEvent.shiftKey == false || onKeyDownEvent.shiftKey == true? onKeyDownEvent.shiftKey: (onKeyDownEvent.modifiers && (onKeyDownEvent.modifiers & 4)); //bitWise AND
> > // TODO : need to get cap lock capture for onkeydown event
> > //this.isCapLock = ((!this.isShiftPressed && this.unicode >= 65 && this.unicode <= 90) || (this.unicode >= 97 && this.unicode <= 122 && this.isShiftPressed));
> > if(this.unicode >= 96 && this.unicode <= 105) {
> > this.unicode -= 48; // handle number keypad
> > }
> > if(this.unicode >= 65 && this.unicode <= 90 && !this.isShiftPressed){
> > this.unicode += 32; // handle uppercase
> > }
> > this.isTab = (this.unicode == 9)? true: false;
> > this.isBackspace = (this.unicode == 8)? true: false;
> > this.isLeftOrRightArrow = (this.unicode == 37 || this.unicode == 39)? true: false;
> > // capture the actual key for the passed key code
> > this.pressedKey = String.fromCharCode(this.unicode);
> > },
> > CursorPosition: function(start, end, range, previousValue) {
> > // holds the cursor position values
> > this.start = isNaN(start)? 0: start;
> > this.end = isNaN(end)? 0: end;
> > this.range = range;
> > this.previousValue = previousValue;
> > this.incStart = function(){
> > this.start++;
> > };
> > this.decStart = function(){
> > this.start--;
> > };
> > }
> > };
> > // Add escape prototype feature to RegExp object
> > // text.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0');
> > // text.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
> > if(!RegExp.escape) {
> > RegExp.escape = function(text){
> > var sp;
> > if(!arguments.callee.sRE){
> > sp=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
> > arguments.callee.sRE = new RegExp('(\\' + sp.join('|\\') + ')','g');
> > }
> > return text.replace(arguments.callee.sRE, '\\$1');
> > };
> > }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
RE: Input Text Mask?
Posted by William Hoover <wh...@nemours.org>.
johan, see https://issues.apache.org/jira/browse/WICKET-1085
-----Original Message-----
From: Johan Compagner [mailto:jcompagner@gmail.com]
Sent: Saturday, October 20, 2007 12:55 PM
To: users@wicket.apache.org
Subject: Re: Input Text Mask?
I think such a thing in extentions would also be nice.
johan
On 10/18/07, Igor Vaynberg <ig...@gmail.com> wrote:
>
> would you be interested in making this a subclass of textfield and
> throwing it into wicketstuff-minis project which is in wicket-stuff?
>
> -igor
>
>
> On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> > Is anyone interested in using the mask script (below) to a component in
> a Wicket extension? The script prevents invalid input in a text field as the
> user types (similar to the Atlas version:
> http://www.fci.com.br/maskedit/MaskEdit/MaskEdit.aspx). I didn't see a
> component in Wicket that would accomplish this out-of-the-box and thought it
> would be a cool addition to Wicket.
> >
> > For example to force the input to mask a phone number:
> > <input type="text" onfocus="InputTextMask.processMaskFocus(this,
> "(999)999-9999", true);" />
> >
> > /**
> > * InputTextMask script used for mask/regexp operations.
> > * Mask Individual Character Usage:
> > * 9 - designates only numeric values
> > * L - designates only uppercase letter values
> > * l - designates only lowercase letter values
> > * A - designates only alphanumeric values
> > * X - denotes that a custom client script regular expression is
> specified</li>
> > * All other characters are assumed to be "special" characters used to
> mask
> > * the input component
> > * Example 1:
> > * (999)999-9999 <LiveCall:(999)999-9999> only numeric values can be
> entered where the the character
> > * position value is 9. Parenthesis and dash are non-editable/mask
> characters.
> > * Example 2:
> > * 99L-ll-X[^A-C]X only numeric values for the first two characters,
> > * uppercase values for the third character, lowercase letters for the
> > * fifth/sixth characters, and the last character X[^A-C]X together
> counts
> > * as the eighth character regular expression that would allow all
> characters
> > * but "A", "B", and "C". Dashes outside the regular expression are
> > * non-editable/mask characters.
> > */
> > var InputTextMask = {
> > processMaskFocus: function(input, mask, clearWhenInvalid){
> > // create an input mask and register it on the specified
> input (if it hasnt already been added by a previous call
> > InputTextMask.createInputMask(input, mask,
> clearWhenInvalid);
> > if(input.value.length == 0){
> > // when the input value is empty populate it
> with the viewing mask and move the cursor to the
> > // beginning of the input field
> > var cursorPos = InputTextMask.getCursorPosition(input,
> input.value);
> > input.value = input.mask.viewMask;
> > InputTextMask.moveCursorToPosition(input, null,
> cursorPos);
> > }
> > },
> > getEvent: function(e) {
> > // get the event either from the window or from the
> passed event
> > return (typeof event != 'undefined')? event: e;
> > },
> > handleEventBubble: function(keyEvent, keyCode){
> > // this method ensures that the key enterned by the user
> is not propagated unless it is a tab or arrow key
> > try {
> > if(keyCode && (keyCode.isTab ||
> keyCode.isLeftOrRightArrow)){
> > // allow all tab/arrow keys by returning
> true- no further action required
> > return true;
> > }
> > keyEvent.cancelBubble = true;
> > if(keyEvent.stopPropagation){
> > // prevent other event triggers
> > keyEvent.stopPropagation();
> > }
> > if(keyEvent.preventDefault){
> > // prevent the default event from
> firing. in this case it is propagation of the keyed input
> > keyEvent.preventDefault();
> > }
> > return false;
> > } catch(e) {
> > alert(e.message);
> > }
> > },
> > createInputMask: function(input, mask, clearWhenInvalid) {
> > // if this input hasnt already registered its mask go
> ahead and do so now. This only needs to be performed the
> > // first time the input is encountered when it gains
> focus. It will attach the MaskType object to the input object
> > // add add all of the appropriate event listeners to
> ensure that the mask is applied
> > if(!input.mask || input.mask.rawMask != mask){
> > input.mask = new InputTextMask.MaskType(input,
> mask, clearWhenInvalid);
> > // add the event listeners that will ensure that
> when the input contains an incomplete mask it will be remove.
> > // Also, make sure that the keydown event is
> fired from this point forward thus invoking the mask format.
> > if(input.addEventListener){
> > // most doms
> > input.addEventListener('blur',
> function(){input.mask.removeValueWhenInvalid();}, false);
> > input.addEventListener('keydown',
> function(e){return input.mask.processMaskFormatting(e);}, false);
> > if(window.opera){
> > // in opera- need to ensure that
> the keypress event isnt interfering with this input mask
> > input.addEventListener('keypress',
> function(e){return InputTextMask.handleEventBubble(InputTextMask.getEvent(e),
> null);}, false);
> > }
> > } else if(input.attachEvent) {
> > // ie
> > input.attachEvent('onblur', function(){
> input.mask.removeValueWhenInvalid();});
> > input.attachEvent('onkeydown',
> function(e){return input.mask.processMaskFormatting(e);});
> > } else {
> > // other browsers that do not support
> dynamic event propagations
> > input.onBlur = function(){
> input.mask.removeValueWhenInvalid();};
> > input.onKeyDown = function(e){
> input.mask.processMaskFormatting(e)};
> > }
> > }
> > },
> > getCursorPosition: function(input, previousValue) {
> > // gets the current cursor position (s=start, e=end) and
> creates/returns a new CursorPosition instance
> > var s, e, r;
> > if(input.createTextRange){
> > // ie- need to capture the start/end cursor
> positions
> > r = document.selection.createRange
> ().duplicate();
> > r.moveEnd('character', previousValue.length);
> > if(r.text === ''){
> > s = previousValue.length;
> > } else {
> > s = previousValue.lastIndexOf(r.text);
> > }
> > r = document.selection.createRange
> ().duplicate();
> > r.moveStart('character', -previousValue.length);
> > e = r.text.length;
> > } else {
> > // other browsers
> > s = input.selectionStart;
> > e = input.selectionEnd;
> > }
> > return new InputTextMask.CursorPosition(s, e, r,
> previousValue);
> > },
> > moveCursorToPosition: function(input, keyCode, cursorPosition) {
> > // moves a cursor position for the passed input element
> to the specified cursor position- because the
> > // range cursor position is 1 indexed we add an
> additional space (unless the pressed key is a backspace)
> > var p = (!keyCode || (keyCode && keyCode.isBackspace))?
> cursorPosition.start: cursorPosition.start + 1;
> > if(input.createTextRange){
> > // ie move- cursor to the index p
> > cursorPosition.range.move('character', p);
> > cursorPosition.range.select();
> > } else {
> > // other browser- move cursor to the index p
> > input.selectionStart = p;
> > input.selectionEnd = p;
> > }
> > },
> > injectValue: function(input, keyCode, cursorPosition) {
> > // inject the validated key into the input mask at the
> specified cursor position and return true on success
> > var key = (keyCode.isBackspace)? '_':
> input.mask.getValidatedKey(keyCode, cursorPosition);
> > if(key){
> > input.value =
> cursorPosition.previousValue.substring(0, cursorPosition.start) + key +
> cursorPosition.previousValue.substring(cursorPosition.start + 1,
> cursorPosition.previousValue.length);
> > return true;
> > }
> > // invalid key
> > return false;
> > },
> > MaskType: function(inputTextElement, mask, clearWhenInvalid) {
> > // this object instance is holds relative mask
> properties for a specified input element
> > this.inputTextElement = inputTextElement;
> > // designates whether or not the input value is cleared
> when its mask is incomplete and a blur event is triggered
> > this.clearWhenInvalid = clearWhenInvalid;
> > // holds the last validated key code
> > this.lastValidatedKeyCode = null;
> > // the mask value used to validate/mask valid input
> > this.rawMask = mask;
> > // the mask displayed in the input
> > this.viewMask = '';
> > // the string array of all the raw mask values (some
> indexes contain more than one char so we need to track this)
> > this.maskArray = new Array();
> > var mai = 0;
> > var regexp = '';
> > // cycle through the raw mask and perform view mask
> conversions
> > for(var i=0; i<mask.length; i++){
> > if(regexp){
> > if(regexp == 'X'){
> > // end of current regexp slot
> > regexp = '';
> > }
> > if(mask.charAt(i) == 'X'){
> > // current mask array index
> contains the complete regexp so we need to store it in the array
> > this.maskArray[mai] = regexp;
> > mai++;
> > regexp = null;
> > } else {
> > // still in the middle of the
> regexp keep adding the current character to the regexp
> > regexp += mask.charAt(i);
> > }
> > } else if(mask.charAt(i) == 'X'){
> > // current slot is a regexp
> > regexp += 'X';
> > this.viewMask += '_';
> > } else if(mask.charAt(i) == '9' || mask.charAt(i)
> == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
> > // the current mask character is one of
> the predefined/reserved characters
> > this.viewMask += '_';
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > } else {
> > // just a regular char
> > this.viewMask += mask.charAt(i);
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > }
> > }
> > // the predefined/reserved characters need to be
> replaced with the viewing mask char that desigantes an editable value
> (underscore)
> > this.specialChars = this.viewMask.replace
> (/(L|l|9|A|_|X)/g,'');
> > this.getValidatedKey = function(keyCode, cursorPosition)
> {
> > // validates if the passed key code is valid for
> the specified cursor position and returns the value if it is. otherwise,
> return false
> > var maskKey = this.maskArray[
> cursorPosition.start];
> > if(maskKey == '9'){
> > // only allow numbers at the specified
> slot
> > return keyCode.pressedKey.match
> (/[0-9]/);
> > } else if(maskKey == 'L'){
> > // only allow uppercase letters at
> specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))?
> keyCode.pressedKey.toUpperCase(): null;
> > } else if(maskKey == 'l'){
> > // only allow lowercase letters at
> specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))?
> keyCode.pressedKey.toLowerCase(): null;
> > } else {
> > if(maskKey == 'A'){
> > // only allow alpha-numeric
> values at the specified slot
> > return keyCode.pressedKey.match
> (/[A-Za-z0-9]/);
> > } else {
> > // only allow values that are
> verified by the specified regexp at the specified slot
> > return (this.maskArray[
> cursorPosition.start].length > 1)? keyCode.pressedKey.match(new
> RegExp(maskKey)): null;
> > }
> > }
> > };
> > this.removeValueWhenInvalid = function(){
> > // removes value from the input element when the
> mask is incomplete
> > if(this.inputTextElement.value.indexOf('_') >
> -1){
> > this.inputTextElement.value = '';
> > }
> > };
> > this.processMaskFormatting = function(e) {
> > // capture event (should be the keydown event)
> > var onKeyDownEvent = InputTextMask.getEvent(e);
> > // create the key code from the event.
> > var keyCode = new InputTextMask.KeyCode
> (onKeyDownEvent);
> > if(InputTextMask.handleEventBubble(onKeyDownEvent,
> keyCode)){
> > // the pressed key is allowed to
> propagate- no mask injection required
> > return true;
> > }
> > var v = this.inputTextElement.value;
> > if(v.length === 0){
> > // when the input value is empty
> populate it with the viewing mask
> > this.inputTextElement.value =
> this.viewMask;
> > }
> > var cursorPos = InputTextMask.getCursorPosition(
> this.inputTextElement, v);
> > if(cursorPos.end ==
> cursorPos.previousValue.length && !keyCode.isBackspace){
> > // input cursor position is at the end
> of the mask- do not allow any more characters to be keyed
> > return false;
> > }
> > // move the cursor position to the next slot
> that does not contain a mask character
> > while(
> this.inputTextElement.mask.specialChars.match(RegExp.escape(
> cursorPos.previousValue.charAt(((keyCode.isBackspace)? cursorPos.start-1:
> cursorPos.start))))){
> > if(keyCode.isBackspace) {
> > // backspace needs to move the
> cursor backwards
> > cursorPos.decStart();
> > } else {
> > // still moving cursor one space
> to the right
> > cursorPos.incStart();
> > }
> > if(cursorPos.start >=
> cursorPos.previousValue.length || cursorPos.start < 0){
> > // end of the mask- no more keys
> should be keyed
> > return false;
> > }
> > }
> > if(keyCode.isBackspace){
> > // need to go back one space to the left
> > cursorPos.decStart();
> > }
> > // inject the key that was pressed into the
> input value mask
> > if(InputTextMask.injectValue(
> this.inputTextElement, keyCode, cursorPos)){
> > // when the injection is sucessful move
> the cursor to the next slot to the right of the injected key
> > InputTextMask.moveCursorToPosition(
> this.inputTextElement, keyCode, cursorPos);
> > }
> > // because the pressed key is being injected we
> always need to return false to prevent duplicate
> > // key injection
> > return false;
> > };
> > },
> > KeyCode: function(onKeyDownEvent) {
> > this.onKeyDownEvent = onKeyDownEvent;
> > // get the unicode value from the key event
> > this.unicode = onKeyDownEvent.which?
> onKeyDownEvent.which: (onKeyDownEvent.keyCode? onKeyDownEvent.keyCode: (
> onKeyDownEvent.charCode? onKeyDownEvent.charCode: 0));
> > this.isShiftPressed = onKeyDownEvent.shiftKey == false
> || onKeyDownEvent.shiftKey == true? onKeyDownEvent.shiftKey: (
> onKeyDownEvent.modifiers && (onKeyDownEvent.modifiers & 4)); //bitWise AND
> > // TODO : need to get cap lock capture for onkeydown
> event
> > //this.isCapLock = ((!this.isShiftPressed &&
> this.unicode >= 65 && this.unicode <= 90) || (this.unicode >= 97 &&
> this.unicode <= 122 && this.isShiftPressed));
> > if(this.unicode >= 96 && this.unicode <= 105) {
> > this.unicode -= 48; // handle number keypad
> > }
> > if(this.unicode >= 65 && this.unicode <= 90 &&
> !this.isShiftPressed){
> > this.unicode += 32; // handle uppercase
> > }
> > this.isTab = (this.unicode == 9)? true: false;
> > this.isBackspace = (this.unicode == 8)? true: false;
> > this.isLeftOrRightArrow = (this.unicode == 37 ||
> this.unicode == 39)? true: false;
> > // capture the actual key for the passed key code
> > this.pressedKey = String.fromCharCode(this.unicode);
> > },
> > CursorPosition: function(start, end, range, previousValue) {
> > // holds the cursor position values
> > this.start = isNaN(start)? 0: start;
> > this.end = isNaN(end)? 0: end;
> > this.range = range;
> > this.previousValue = previousValue;
> > this.incStart = function(){
> > this.start++;
> > };
> > this.decStart = function(){
> > this.start--;
> > };
> > }
> > };
> > // Add escape prototype feature to RegExp object
> > // text.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0');
> > // text.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
> > if(!RegExp.escape) {
> > RegExp.escape = function(text){
> > var sp;
> > if(!arguments.callee.sRE){
> >
> sp=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
> > arguments.callee.sRE = new RegExp('(\\' +
> sp.join('|\\') + ')','g');
> > }
> > return text.replace(arguments.callee.sRE, '\\$1');
> > };
> > }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Input Text Mask?
Posted by Johan Compagner <jc...@gmail.com>.
I think such a thing in extentions would also be nice.
johan
On 10/18/07, Igor Vaynberg <ig...@gmail.com> wrote:
>
> would you be interested in making this a subclass of textfield and
> throwing it into wicketstuff-minis project which is in wicket-stuff?
>
> -igor
>
>
> On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> > Is anyone interested in using the mask script (below) to a component in
> a Wicket extension? The script prevents invalid input in a text field as the
> user types (similar to the Atlas version:
> http://www.fci.com.br/maskedit/MaskEdit/MaskEdit.aspx). I didn't see a
> component in Wicket that would accomplish this out-of-the-box and thought it
> would be a cool addition to Wicket.
> >
> > For example to force the input to mask a phone number:
> > <input type="text" onfocus="InputTextMask.processMaskFocus(this,
> "(999)999-9999", true);" />
> >
> > /**
> > * InputTextMask script used for mask/regexp operations.
> > * Mask Individual Character Usage:
> > * 9 - designates only numeric values
> > * L - designates only uppercase letter values
> > * l - designates only lowercase letter values
> > * A - designates only alphanumeric values
> > * X - denotes that a custom client script regular expression is
> specified</li>
> > * All other characters are assumed to be "special" characters used to
> mask
> > * the input component
> > * Example 1:
> > * (999)999-9999 <LiveCall:(999)999-9999> only numeric values can be
> entered where the the character
> > * position value is 9. Parenthesis and dash are non-editable/mask
> characters.
> > * Example 2:
> > * 99L-ll-X[^A-C]X only numeric values for the first two characters,
> > * uppercase values for the third character, lowercase letters for the
> > * fifth/sixth characters, and the last character X[^A-C]X together
> counts
> > * as the eighth character regular expression that would allow all
> characters
> > * but "A", "B", and "C". Dashes outside the regular expression are
> > * non-editable/mask characters.
> > */
> > var InputTextMask = {
> > processMaskFocus: function(input, mask, clearWhenInvalid){
> > // create an input mask and register it on the specified
> input (if it hasnt already been added by a previous call
> > InputTextMask.createInputMask(input, mask,
> clearWhenInvalid);
> > if(input.value.length == 0){
> > // when the input value is empty populate it
> with the viewing mask and move the cursor to the
> > // beginning of the input field
> > var cursorPos = InputTextMask.getCursorPosition(input,
> input.value);
> > input.value = input.mask.viewMask;
> > InputTextMask.moveCursorToPosition(input, null,
> cursorPos);
> > }
> > },
> > getEvent: function(e) {
> > // get the event either from the window or from the
> passed event
> > return (typeof event != 'undefined')? event: e;
> > },
> > handleEventBubble: function(keyEvent, keyCode){
> > // this method ensures that the key enterned by the user
> is not propagated unless it is a tab or arrow key
> > try {
> > if(keyCode && (keyCode.isTab ||
> keyCode.isLeftOrRightArrow)){
> > // allow all tab/arrow keys by returning
> true- no further action required
> > return true;
> > }
> > keyEvent.cancelBubble = true;
> > if(keyEvent.stopPropagation){
> > // prevent other event triggers
> > keyEvent.stopPropagation();
> > }
> > if(keyEvent.preventDefault){
> > // prevent the default event from
> firing. in this case it is propagation of the keyed input
> > keyEvent.preventDefault();
> > }
> > return false;
> > } catch(e) {
> > alert(e.message);
> > }
> > },
> > createInputMask: function(input, mask, clearWhenInvalid) {
> > // if this input hasnt already registered its mask go
> ahead and do so now. This only needs to be performed the
> > // first time the input is encountered when it gains
> focus. It will attach the MaskType object to the input object
> > // add add all of the appropriate event listeners to
> ensure that the mask is applied
> > if(!input.mask || input.mask.rawMask != mask){
> > input.mask = new InputTextMask.MaskType(input,
> mask, clearWhenInvalid);
> > // add the event listeners that will ensure that
> when the input contains an incomplete mask it will be remove.
> > // Also, make sure that the keydown event is
> fired from this point forward thus invoking the mask format.
> > if(input.addEventListener){
> > // most doms
> > input.addEventListener('blur',
> function(){input.mask.removeValueWhenInvalid();}, false);
> > input.addEventListener('keydown',
> function(e){return input.mask.processMaskFormatting(e);}, false);
> > if(window.opera){
> > // in opera- need to ensure that
> the keypress event isnt interfering with this input mask
> > input.addEventListener('keypress',
> function(e){return InputTextMask.handleEventBubble(InputTextMask.getEvent(e),
> null);}, false);
> > }
> > } else if(input.attachEvent) {
> > // ie
> > input.attachEvent('onblur', function(){
> input.mask.removeValueWhenInvalid();});
> > input.attachEvent('onkeydown',
> function(e){return input.mask.processMaskFormatting(e);});
> > } else {
> > // other browsers that do not support
> dynamic event propagations
> > input.onBlur = function(){
> input.mask.removeValueWhenInvalid();};
> > input.onKeyDown = function(e){
> input.mask.processMaskFormatting(e)};
> > }
> > }
> > },
> > getCursorPosition: function(input, previousValue) {
> > // gets the current cursor position (s=start, e=end) and
> creates/returns a new CursorPosition instance
> > var s, e, r;
> > if(input.createTextRange){
> > // ie- need to capture the start/end cursor
> positions
> > r = document.selection.createRange
> ().duplicate();
> > r.moveEnd('character', previousValue.length);
> > if(r.text === ''){
> > s = previousValue.length;
> > } else {
> > s = previousValue.lastIndexOf(r.text);
> > }
> > r = document.selection.createRange
> ().duplicate();
> > r.moveStart('character', -previousValue.length);
> > e = r.text.length;
> > } else {
> > // other browsers
> > s = input.selectionStart;
> > e = input.selectionEnd;
> > }
> > return new InputTextMask.CursorPosition(s, e, r,
> previousValue);
> > },
> > moveCursorToPosition: function(input, keyCode, cursorPosition) {
> > // moves a cursor position for the passed input element
> to the specified cursor position- because the
> > // range cursor position is 1 indexed we add an
> additional space (unless the pressed key is a backspace)
> > var p = (!keyCode || (keyCode && keyCode.isBackspace))?
> cursorPosition.start: cursorPosition.start + 1;
> > if(input.createTextRange){
> > // ie move- cursor to the index p
> > cursorPosition.range.move('character', p);
> > cursorPosition.range.select();
> > } else {
> > // other browser- move cursor to the index p
> > input.selectionStart = p;
> > input.selectionEnd = p;
> > }
> > },
> > injectValue: function(input, keyCode, cursorPosition) {
> > // inject the validated key into the input mask at the
> specified cursor position and return true on success
> > var key = (keyCode.isBackspace)? '_':
> input.mask.getValidatedKey(keyCode, cursorPosition);
> > if(key){
> > input.value =
> cursorPosition.previousValue.substring(0, cursorPosition.start) + key +
> cursorPosition.previousValue.substring(cursorPosition.start + 1,
> cursorPosition.previousValue.length);
> > return true;
> > }
> > // invalid key
> > return false;
> > },
> > MaskType: function(inputTextElement, mask, clearWhenInvalid) {
> > // this object instance is holds relative mask
> properties for a specified input element
> > this.inputTextElement = inputTextElement;
> > // designates whether or not the input value is cleared
> when its mask is incomplete and a blur event is triggered
> > this.clearWhenInvalid = clearWhenInvalid;
> > // holds the last validated key code
> > this.lastValidatedKeyCode = null;
> > // the mask value used to validate/mask valid input
> > this.rawMask = mask;
> > // the mask displayed in the input
> > this.viewMask = '';
> > // the string array of all the raw mask values (some
> indexes contain more than one char so we need to track this)
> > this.maskArray = new Array();
> > var mai = 0;
> > var regexp = '';
> > // cycle through the raw mask and perform view mask
> conversions
> > for(var i=0; i<mask.length; i++){
> > if(regexp){
> > if(regexp == 'X'){
> > // end of current regexp slot
> > regexp = '';
> > }
> > if(mask.charAt(i) == 'X'){
> > // current mask array index
> contains the complete regexp so we need to store it in the array
> > this.maskArray[mai] = regexp;
> > mai++;
> > regexp = null;
> > } else {
> > // still in the middle of the
> regexp keep adding the current character to the regexp
> > regexp += mask.charAt(i);
> > }
> > } else if(mask.charAt(i) == 'X'){
> > // current slot is a regexp
> > regexp += 'X';
> > this.viewMask += '_';
> > } else if(mask.charAt(i) == '9' || mask.charAt(i)
> == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
> > // the current mask character is one of
> the predefined/reserved characters
> > this.viewMask += '_';
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > } else {
> > // just a regular char
> > this.viewMask += mask.charAt(i);
> > this.maskArray[mai] = mask.charAt(i);
> > mai++;
> > }
> > }
> > // the predefined/reserved characters need to be
> replaced with the viewing mask char that desigantes an editable value
> (underscore)
> > this.specialChars = this.viewMask.replace
> (/(L|l|9|A|_|X)/g,'');
> > this.getValidatedKey = function(keyCode, cursorPosition)
> {
> > // validates if the passed key code is valid for
> the specified cursor position and returns the value if it is. otherwise,
> return false
> > var maskKey = this.maskArray[
> cursorPosition.start];
> > if(maskKey == '9'){
> > // only allow numbers at the specified
> slot
> > return keyCode.pressedKey.match
> (/[0-9]/);
> > } else if(maskKey == 'L'){
> > // only allow uppercase letters at
> specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))?
> keyCode.pressedKey.toUpperCase(): null;
> > } else if(maskKey == 'l'){
> > // only allow lowercase letters at
> specified slot (convert if necessary)
> > return (keyCode.pressedKey.match(/[A-Za-z]/))?
> keyCode.pressedKey.toLowerCase(): null;
> > } else {
> > if(maskKey == 'A'){
> > // only allow alpha-numeric
> values at the specified slot
> > return keyCode.pressedKey.match
> (/[A-Za-z0-9]/);
> > } else {
> > // only allow values that are
> verified by the specified regexp at the specified slot
> > return (this.maskArray[
> cursorPosition.start].length > 1)? keyCode.pressedKey.match(new
> RegExp(maskKey)): null;
> > }
> > }
> > };
> > this.removeValueWhenInvalid = function(){
> > // removes value from the input element when the
> mask is incomplete
> > if(this.inputTextElement.value.indexOf('_') >
> -1){
> > this.inputTextElement.value = '';
> > }
> > };
> > this.processMaskFormatting = function(e) {
> > // capture event (should be the keydown event)
> > var onKeyDownEvent = InputTextMask.getEvent(e);
> > // create the key code from the event.
> > var keyCode = new InputTextMask.KeyCode
> (onKeyDownEvent);
> > if(InputTextMask.handleEventBubble(onKeyDownEvent,
> keyCode)){
> > // the pressed key is allowed to
> propagate- no mask injection required
> > return true;
> > }
> > var v = this.inputTextElement.value;
> > if(v.length === 0){
> > // when the input value is empty
> populate it with the viewing mask
> > this.inputTextElement.value =
> this.viewMask;
> > }
> > var cursorPos = InputTextMask.getCursorPosition(
> this.inputTextElement, v);
> > if(cursorPos.end ==
> cursorPos.previousValue.length && !keyCode.isBackspace){
> > // input cursor position is at the end
> of the mask- do not allow any more characters to be keyed
> > return false;
> > }
> > // move the cursor position to the next slot
> that does not contain a mask character
> > while(
> this.inputTextElement.mask.specialChars.match(RegExp.escape(
> cursorPos.previousValue.charAt(((keyCode.isBackspace)? cursorPos.start-1:
> cursorPos.start))))){
> > if(keyCode.isBackspace) {
> > // backspace needs to move the
> cursor backwards
> > cursorPos.decStart();
> > } else {
> > // still moving cursor one space
> to the right
> > cursorPos.incStart();
> > }
> > if(cursorPos.start >=
> cursorPos.previousValue.length || cursorPos.start < 0){
> > // end of the mask- no more keys
> should be keyed
> > return false;
> > }
> > }
> > if(keyCode.isBackspace){
> > // need to go back one space to the left
> > cursorPos.decStart();
> > }
> > // inject the key that was pressed into the
> input value mask
> > if(InputTextMask.injectValue(
> this.inputTextElement, keyCode, cursorPos)){
> > // when the injection is sucessful move
> the cursor to the next slot to the right of the injected key
> > InputTextMask.moveCursorToPosition(
> this.inputTextElement, keyCode, cursorPos);
> > }
> > // because the pressed key is being injected we
> always need to return false to prevent duplicate
> > // key injection
> > return false;
> > };
> > },
> > KeyCode: function(onKeyDownEvent) {
> > this.onKeyDownEvent = onKeyDownEvent;
> > // get the unicode value from the key event
> > this.unicode = onKeyDownEvent.which?
> onKeyDownEvent.which: (onKeyDownEvent.keyCode? onKeyDownEvent.keyCode: (
> onKeyDownEvent.charCode? onKeyDownEvent.charCode: 0));
> > this.isShiftPressed = onKeyDownEvent.shiftKey == false
> || onKeyDownEvent.shiftKey == true? onKeyDownEvent.shiftKey: (
> onKeyDownEvent.modifiers && (onKeyDownEvent.modifiers & 4)); //bitWise AND
> > // TODO : need to get cap lock capture for onkeydown
> event
> > //this.isCapLock = ((!this.isShiftPressed &&
> this.unicode >= 65 && this.unicode <= 90) || (this.unicode >= 97 &&
> this.unicode <= 122 && this.isShiftPressed));
> > if(this.unicode >= 96 && this.unicode <= 105) {
> > this.unicode -= 48; // handle number keypad
> > }
> > if(this.unicode >= 65 && this.unicode <= 90 &&
> !this.isShiftPressed){
> > this.unicode += 32; // handle uppercase
> > }
> > this.isTab = (this.unicode == 9)? true: false;
> > this.isBackspace = (this.unicode == 8)? true: false;
> > this.isLeftOrRightArrow = (this.unicode == 37 ||
> this.unicode == 39)? true: false;
> > // capture the actual key for the passed key code
> > this.pressedKey = String.fromCharCode(this.unicode);
> > },
> > CursorPosition: function(start, end, range, previousValue) {
> > // holds the cursor position values
> > this.start = isNaN(start)? 0: start;
> > this.end = isNaN(end)? 0: end;
> > this.range = range;
> > this.previousValue = previousValue;
> > this.incStart = function(){
> > this.start++;
> > };
> > this.decStart = function(){
> > this.start--;
> > };
> > }
> > };
> > // Add escape prototype feature to RegExp object
> > // text.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0');
> > // text.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
> > if(!RegExp.escape) {
> > RegExp.escape = function(text){
> > var sp;
> > if(!arguments.callee.sRE){
> >
> sp=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
> > arguments.callee.sRE = new RegExp('(\\' +
> sp.join('|\\') + ')','g');
> > }
> > return text.replace(arguments.callee.sRE, '\\$1');
> > };
> > }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> > For additional commands, e-mail: users-help@wicket.apache.org
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
RE: Input Text Mask?
Posted by William Hoover <wh...@nemours.org>.
Sure. How would I go about doing so?
-----Original Message-----
From: Igor Vaynberg [mailto:igor.vaynberg@gmail.com]
Sent: Thursday, October 18, 2007 1:11 PM
To: users@wicket.apache.org
Subject: Re: Input Text Mask?
would you be interested in making this a subclass of textfield and
throwing it into wicketstuff-minis project which is in wicket-stuff?
-igor
On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> Is anyone interested in using the mask script (below) to a component in a Wicket extension? The script prevents invalid input in a text field as the user types (similar to the Atlas version: http://www.fci.com.br/maskedit/MaskEdit/MaskEdit.aspx). I didn't see a component in Wicket that would accomplish this out-of-the-box and thought it would be a cool addition to Wicket.
>
> For example to force the input to mask a phone number:
> <input type="text" onfocus="InputTextMask.processMaskFocus(this, "(999)999-9999", true);" />
>
> /**
> * InputTextMask script used for mask/regexp operations.
> * Mask Individual Character Usage:
> * 9 - designates only numeric values
> * L - designates only uppercase letter values
> * l - designates only lowercase letter values
> * A - designates only alphanumeric values
> * X - denotes that a custom client script regular expression is specified</li>
> * All other characters are assumed to be "special" characters used to mask
> * the input component
> * Example 1:
> * (999)999-9999 only numeric values can be entered where the the character
> * position value is 9. Parenthesis and dash are non-editable/mask characters.
> * Example 2:
> * 99L-ll-X[^A-C]X only numeric values for the first two characters,
> * uppercase values for the third character, lowercase letters for the
> * fifth/sixth characters, and the last character X[^A-C]X together counts
> * as the eighth character regular expression that would allow all characters
> * but "A", "B", and "C". Dashes outside the regular expression are
> * non-editable/mask characters.
> */
> var InputTextMask = {
> processMaskFocus: function(input, mask, clearWhenInvalid){
> // create an input mask and register it on the specified input (if it hasnt already been added by a previous call
> InputTextMask.createInputMask(input, mask, clearWhenInvalid);
> if(input.value.length == 0){
> // when the input value is empty populate it with the viewing mask and move the cursor to the
> // beginning of the input field
> var cursorPos = InputTextMask.getCursorPosition(input, input.value);
> input.value = input.mask.viewMask;
> InputTextMask.moveCursorToPosition(input, null, cursorPos);
> }
> },
> getEvent: function(e) {
> // get the event either from the window or from the passed event
> return (typeof event != 'undefined')? event: e;
> },
> handleEventBubble: function(keyEvent, keyCode){
> // this method ensures that the key enterned by the user is not propagated unless it is a tab or arrow key
> try {
> if(keyCode && (keyCode.isTab || keyCode.isLeftOrRightArrow)){
> // allow all tab/arrow keys by returning true- no further action required
> return true;
> }
> keyEvent.cancelBubble = true;
> if(keyEvent.stopPropagation){
> // prevent other event triggers
> keyEvent.stopPropagation();
> }
> if(keyEvent.preventDefault){
> // prevent the default event from firing. in this case it is propagation of the keyed input
> keyEvent.preventDefault();
> }
> return false;
> } catch(e) {
> alert(e.message);
> }
> },
> createInputMask: function(input, mask, clearWhenInvalid) {
> // if this input hasnt already registered its mask go ahead and do so now. This only needs to be performed the
> // first time the input is encountered when it gains focus. It will attach the MaskType object to the input object
> // add add all of the appropriate event listeners to ensure that the mask is applied
> if(!input.mask || input.mask.rawMask != mask){
> input.mask = new InputTextMask.MaskType(input, mask, clearWhenInvalid);
> // add the event listeners that will ensure that when the input contains an incomplete mask it will be remove.
> // Also, make sure that the keydown event is fired from this point forward thus invoking the mask format.
> if(input.addEventListener){
> // most doms
> input.addEventListener('blur', function(){input.mask.removeValueWhenInvalid();}, false);
> input.addEventListener('keydown', function(e){return input.mask.processMaskFormatting(e);}, false);
> if(window.opera){
> // in opera- need to ensure that the keypress event isnt interfering with this input mask
> input.addEventListener('keypress', function(e){return InputTextMask.handleEventBubble(InputTextMask.getEvent(e), null);}, false);
> }
> } else if(input.attachEvent) {
> // ie
> input.attachEvent('onblur', function(){input.mask.removeValueWhenInvalid();});
> input.attachEvent('onkeydown', function(e){return input.mask.processMaskFormatting(e);});
> } else {
> // other browsers that do not support dynamic event propagations
> input.onBlur = function(){input.mask.removeValueWhenInvalid();};
> input.onKeyDown = function(e){input.mask.processMaskFormatting(e)};
> }
> }
> },
> getCursorPosition: function(input, previousValue) {
> // gets the current cursor position (s=start, e=end) and creates/returns a new CursorPosition instance
> var s, e, r;
> if(input.createTextRange){
> // ie- need to capture the start/end cursor positions
> r = document.selection.createRange().duplicate();
> r.moveEnd('character', previousValue.length);
> if(r.text === ''){
> s = previousValue.length;
> } else {
> s = previousValue.lastIndexOf(r.text);
> }
> r = document.selection.createRange().duplicate();
> r.moveStart('character', -previousValue.length);
> e = r.text.length;
> } else {
> // other browsers
> s = input.selectionStart;
> e = input.selectionEnd;
> }
> return new InputTextMask.CursorPosition(s, e, r, previousValue);
> },
> moveCursorToPosition: function(input, keyCode, cursorPosition) {
> // moves a cursor position for the passed input element to the specified cursor position- because the
> // range cursor position is 1 indexed we add an additional space (unless the pressed key is a backspace)
> var p = (!keyCode || (keyCode && keyCode.isBackspace))? cursorPosition.start: cursorPosition.start + 1;
> if(input.createTextRange){
> // ie move- cursor to the index p
> cursorPosition.range.move('character', p);
> cursorPosition.range.select();
> } else {
> // other browser- move cursor to the index p
> input.selectionStart = p;
> input.selectionEnd = p;
> }
> },
> injectValue: function(input, keyCode, cursorPosition) {
> // inject the validated key into the input mask at the specified cursor position and return true on success
> var key = (keyCode.isBackspace)? '_': input.mask.getValidatedKey(keyCode, cursorPosition);
> if(key){
> input.value = cursorPosition.previousValue.substring(0, cursorPosition.start) + key + cursorPosition.previousValue.substring(cursorPosition.start + 1, cursorPosition.previousValue.length);
> return true;
> }
> // invalid key
> return false;
> },
> MaskType: function(inputTextElement, mask, clearWhenInvalid) {
> // this object instance is holds relative mask properties for a specified input element
> this.inputTextElement = inputTextElement;
> // designates whether or not the input value is cleared when its mask is incomplete and a blur event is triggered
> this.clearWhenInvalid = clearWhenInvalid;
> // holds the last validated key code
> this.lastValidatedKeyCode = null;
> // the mask value used to validate/mask valid input
> this.rawMask = mask;
> // the mask displayed in the input
> this.viewMask = '';
> // the string array of all the raw mask values (some indexes contain more than one char so we need to track this)
> this.maskArray = new Array();
> var mai = 0;
> var regexp = '';
> // cycle through the raw mask and perform view mask conversions
> for(var i=0; i<mask.length; i++){
> if(regexp){
> if(regexp == 'X'){
> // end of current regexp slot
> regexp = '';
> }
> if(mask.charAt(i) == 'X'){
> // current mask array index contains the complete regexp so we need to store it in the array
> this.maskArray[mai] = regexp;
> mai++;
> regexp = null;
> } else {
> // still in the middle of the regexp keep adding the current character to the regexp
> regexp += mask.charAt(i);
> }
> } else if(mask.charAt(i) == 'X'){
> // current slot is a regexp
> regexp += 'X';
> this.viewMask += '_';
> } else if(mask.charAt(i) == '9' || mask.charAt(i) == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
> // the current mask character is one of the predefined/reserved characters
> this.viewMask += '_';
> this.maskArray[mai] = mask.charAt(i);
> mai++;
> } else {
> // just a regular char
> this.viewMask += mask.charAt(i);
> this.maskArray[mai] = mask.charAt(i);
> mai++;
> }
> }
> // the predefined/reserved characters need to be replaced with the viewing mask char that desigantes an editable value (underscore)
> this.specialChars = this.viewMask.replace(/(L|l|9|A|_|X)/g,'');
> this.getValidatedKey = function(keyCode, cursorPosition) {
> // validates if the passed key code is valid for the specified cursor position and returns the value if it is. otherwise, return false
> var maskKey = this.maskArray[cursorPosition.start];
> if(maskKey == '9'){
> // only allow numbers at the specified slot
> return keyCode.pressedKey.match(/[0-9]/);
> } else if(maskKey == 'L'){
> // only allow uppercase letters at specified slot (convert if necessary)
> return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toUpperCase(): null;
> } else if(maskKey == 'l'){
> // only allow lowercase letters at specified slot (convert if necessary)
> return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toLowerCase(): null;
> } else {
> if(maskKey == 'A'){
> // only allow alpha-numeric values at the specified slot
> return keyCode.pressedKey.match(/[A-Za-z0-9]/);
> } else {
> // only allow values that are verified by the specified regexp at the specified slot
> return (this.maskArray[cursorPosition.start].length > 1)? keyCode.pressedKey.match(new RegExp(maskKey)): null;
> }
> }
> };
> this.removeValueWhenInvalid = function(){
> // removes value from the input element when the mask is incomplete
> if(this.inputTextElement.value.indexOf('_') > -1){
> this.inputTextElement.value = '';
> }
> };
> this.processMaskFormatting = function(e) {
> // capture event (should be the keydown event)
> var onKeyDownEvent = InputTextMask.getEvent(e);
> // create the key code from the event.
> var keyCode = new InputTextMask.KeyCode(onKeyDownEvent);
> if(InputTextMask.handleEventBubble(onKeyDownEvent, keyCode)){
> // the pressed key is allowed to propagate- no mask injection required
> return true;
> }
> var v = this.inputTextElement.value;
> if(v.length === 0){
> // when the input value is empty populate it with the viewing mask
> this.inputTextElement.value = this.viewMask;
> }
> var cursorPos = InputTextMask.getCursorPosition(this.inputTextElement, v);
> if(cursorPos.end == cursorPos.previousValue.length && !keyCode.isBackspace){
> // input cursor position is at the end of the mask- do not allow any more characters to be keyed
> return false;
> }
> // move the cursor position to the next slot that does not contain a mask character
> while(this.inputTextElement.mask.specialChars.match(RegExp.escape(cursorPos.previousValue.charAt(((keyCode.isBackspace)? cursorPos.start-1: cursorPos.start))))){
> if(keyCode.isBackspace) {
> // backspace needs to move the cursor backwards
> cursorPos.decStart();
> } else {
> // still moving cursor one space to the right
> cursorPos.incStart();
> }
> if(cursorPos.start >= cursorPos.previousValue.length || cursorPos.start < 0){
> // end of the mask- no more keys should be keyed
> return false;
> }
> }
> if(keyCode.isBackspace){
> // need to go back one space to the left
> cursorPos.decStart();
> }
> // inject the key that was pressed into the input value mask
> if(InputTextMask.injectValue(this.inputTextElement, keyCode, cursorPos)){
> // when the injection is sucessful move the cursor to the next slot to the right of the injected key
> InputTextMask.moveCursorToPosition(this.inputTextElement, keyCode, cursorPos);
> }
> // because the pressed key is being injected we always need to return false to prevent duplicate
> // key injection
> return false;
> };
> },
> KeyCode: function(onKeyDownEvent) {
> this.onKeyDownEvent = onKeyDownEvent;
> // get the unicode value from the key event
> this.unicode = onKeyDownEvent.which? onKeyDownEvent.which: (onKeyDownEvent.keyCode? onKeyDownEvent.keyCode: (onKeyDownEvent.charCode? onKeyDownEvent.charCode: 0));
> this.isShiftPressed = onKeyDownEvent.shiftKey == false || onKeyDownEvent.shiftKey == true? onKeyDownEvent.shiftKey: (onKeyDownEvent.modifiers && (onKeyDownEvent.modifiers & 4)); //bitWise AND
> // TODO : need to get cap lock capture for onkeydown event
> //this.isCapLock = ((!this.isShiftPressed && this.unicode >= 65 && this.unicode <= 90) || (this.unicode >= 97 && this.unicode <= 122 && this.isShiftPressed));
> if(this.unicode >= 96 && this.unicode <= 105) {
> this.unicode -= 48; // handle number keypad
> }
> if(this.unicode >= 65 && this.unicode <= 90 && !this.isShiftPressed){
> this.unicode += 32; // handle uppercase
> }
> this.isTab = (this.unicode == 9)? true: false;
> this.isBackspace = (this.unicode == 8)? true: false;
> this.isLeftOrRightArrow = (this.unicode == 37 || this.unicode == 39)? true: false;
> // capture the actual key for the passed key code
> this.pressedKey = String.fromCharCode(this.unicode);
> },
> CursorPosition: function(start, end, range, previousValue) {
> // holds the cursor position values
> this.start = isNaN(start)? 0: start;
> this.end = isNaN(end)? 0: end;
> this.range = range;
> this.previousValue = previousValue;
> this.incStart = function(){
> this.start++;
> };
> this.decStart = function(){
> this.start--;
> };
> }
> };
> // Add escape prototype feature to RegExp object
> // text.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0');
> // text.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
> if(!RegExp.escape) {
> RegExp.escape = function(text){
> var sp;
> if(!arguments.callee.sRE){
> sp=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
> arguments.callee.sRE = new RegExp('(\\' + sp.join('|\\') + ')','g');
> }
> return text.replace(arguments.callee.sRE, '\\$1');
> };
> }
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Input Text Mask?
Posted by Igor Vaynberg <ig...@gmail.com>.
would you be interested in making this a subclass of textfield and
throwing it into wicketstuff-minis project which is in wicket-stuff?
-igor
On 10/18/07, William Hoover <wh...@nemours.org> wrote:
> Is anyone interested in using the mask script (below) to a component in a Wicket extension? The script prevents invalid input in a text field as the user types (similar to the Atlas version: http://www.fci.com.br/maskedit/MaskEdit/MaskEdit.aspx). I didn't see a component in Wicket that would accomplish this out-of-the-box and thought it would be a cool addition to Wicket.
>
> For example to force the input to mask a phone number:
> <input type="text" onfocus="InputTextMask.processMaskFocus(this, "(999)999-9999", true);" />
>
> /**
> * InputTextMask script used for mask/regexp operations.
> * Mask Individual Character Usage:
> * 9 - designates only numeric values
> * L - designates only uppercase letter values
> * l - designates only lowercase letter values
> * A - designates only alphanumeric values
> * X - denotes that a custom client script regular expression is specified</li>
> * All other characters are assumed to be "special" characters used to mask
> * the input component
> * Example 1:
> * (999)999-9999 only numeric values can be entered where the the character
> * position value is 9. Parenthesis and dash are non-editable/mask characters.
> * Example 2:
> * 99L-ll-X[^A-C]X only numeric values for the first two characters,
> * uppercase values for the third character, lowercase letters for the
> * fifth/sixth characters, and the last character X[^A-C]X together counts
> * as the eighth character regular expression that would allow all characters
> * but "A", "B", and "C". Dashes outside the regular expression are
> * non-editable/mask characters.
> */
> var InputTextMask = {
> processMaskFocus: function(input, mask, clearWhenInvalid){
> // create an input mask and register it on the specified input (if it hasnt already been added by a previous call
> InputTextMask.createInputMask(input, mask, clearWhenInvalid);
> if(input.value.length == 0){
> // when the input value is empty populate it with the viewing mask and move the cursor to the
> // beginning of the input field
> var cursorPos = InputTextMask.getCursorPosition(input, input.value);
> input.value = input.mask.viewMask;
> InputTextMask.moveCursorToPosition(input, null, cursorPos);
> }
> },
> getEvent: function(e) {
> // get the event either from the window or from the passed event
> return (typeof event != 'undefined')? event: e;
> },
> handleEventBubble: function(keyEvent, keyCode){
> // this method ensures that the key enterned by the user is not propagated unless it is a tab or arrow key
> try {
> if(keyCode && (keyCode.isTab || keyCode.isLeftOrRightArrow)){
> // allow all tab/arrow keys by returning true- no further action required
> return true;
> }
> keyEvent.cancelBubble = true;
> if(keyEvent.stopPropagation){
> // prevent other event triggers
> keyEvent.stopPropagation();
> }
> if(keyEvent.preventDefault){
> // prevent the default event from firing. in this case it is propagation of the keyed input
> keyEvent.preventDefault();
> }
> return false;
> } catch(e) {
> alert(e.message);
> }
> },
> createInputMask: function(input, mask, clearWhenInvalid) {
> // if this input hasnt already registered its mask go ahead and do so now. This only needs to be performed the
> // first time the input is encountered when it gains focus. It will attach the MaskType object to the input object
> // add add all of the appropriate event listeners to ensure that the mask is applied
> if(!input.mask || input.mask.rawMask != mask){
> input.mask = new InputTextMask.MaskType(input, mask, clearWhenInvalid);
> // add the event listeners that will ensure that when the input contains an incomplete mask it will be remove.
> // Also, make sure that the keydown event is fired from this point forward thus invoking the mask format.
> if(input.addEventListener){
> // most doms
> input.addEventListener('blur', function(){input.mask.removeValueWhenInvalid();}, false);
> input.addEventListener('keydown', function(e){return input.mask.processMaskFormatting(e);}, false);
> if(window.opera){
> // in opera- need to ensure that the keypress event isnt interfering with this input mask
> input.addEventListener('keypress', function(e){return InputTextMask.handleEventBubble(InputTextMask.getEvent(e), null);}, false);
> }
> } else if(input.attachEvent) {
> // ie
> input.attachEvent('onblur', function(){input.mask.removeValueWhenInvalid();});
> input.attachEvent('onkeydown', function(e){return input.mask.processMaskFormatting(e);});
> } else {
> // other browsers that do not support dynamic event propagations
> input.onBlur = function(){input.mask.removeValueWhenInvalid();};
> input.onKeyDown = function(e){input.mask.processMaskFormatting(e)};
> }
> }
> },
> getCursorPosition: function(input, previousValue) {
> // gets the current cursor position (s=start, e=end) and creates/returns a new CursorPosition instance
> var s, e, r;
> if(input.createTextRange){
> // ie- need to capture the start/end cursor positions
> r = document.selection.createRange().duplicate();
> r.moveEnd('character', previousValue.length);
> if(r.text === ''){
> s = previousValue.length;
> } else {
> s = previousValue.lastIndexOf(r.text);
> }
> r = document.selection.createRange().duplicate();
> r.moveStart('character', -previousValue.length);
> e = r.text.length;
> } else {
> // other browsers
> s = input.selectionStart;
> e = input.selectionEnd;
> }
> return new InputTextMask.CursorPosition(s, e, r, previousValue);
> },
> moveCursorToPosition: function(input, keyCode, cursorPosition) {
> // moves a cursor position for the passed input element to the specified cursor position- because the
> // range cursor position is 1 indexed we add an additional space (unless the pressed key is a backspace)
> var p = (!keyCode || (keyCode && keyCode.isBackspace))? cursorPosition.start: cursorPosition.start + 1;
> if(input.createTextRange){
> // ie move- cursor to the index p
> cursorPosition.range.move('character', p);
> cursorPosition.range.select();
> } else {
> // other browser- move cursor to the index p
> input.selectionStart = p;
> input.selectionEnd = p;
> }
> },
> injectValue: function(input, keyCode, cursorPosition) {
> // inject the validated key into the input mask at the specified cursor position and return true on success
> var key = (keyCode.isBackspace)? '_': input.mask.getValidatedKey(keyCode, cursorPosition);
> if(key){
> input.value = cursorPosition.previousValue.substring(0, cursorPosition.start) + key + cursorPosition.previousValue.substring(cursorPosition.start + 1, cursorPosition.previousValue.length);
> return true;
> }
> // invalid key
> return false;
> },
> MaskType: function(inputTextElement, mask, clearWhenInvalid) {
> // this object instance is holds relative mask properties for a specified input element
> this.inputTextElement = inputTextElement;
> // designates whether or not the input value is cleared when its mask is incomplete and a blur event is triggered
> this.clearWhenInvalid = clearWhenInvalid;
> // holds the last validated key code
> this.lastValidatedKeyCode = null;
> // the mask value used to validate/mask valid input
> this.rawMask = mask;
> // the mask displayed in the input
> this.viewMask = '';
> // the string array of all the raw mask values (some indexes contain more than one char so we need to track this)
> this.maskArray = new Array();
> var mai = 0;
> var regexp = '';
> // cycle through the raw mask and perform view mask conversions
> for(var i=0; i<mask.length; i++){
> if(regexp){
> if(regexp == 'X'){
> // end of current regexp slot
> regexp = '';
> }
> if(mask.charAt(i) == 'X'){
> // current mask array index contains the complete regexp so we need to store it in the array
> this.maskArray[mai] = regexp;
> mai++;
> regexp = null;
> } else {
> // still in the middle of the regexp keep adding the current character to the regexp
> regexp += mask.charAt(i);
> }
> } else if(mask.charAt(i) == 'X'){
> // current slot is a regexp
> regexp += 'X';
> this.viewMask += '_';
> } else if(mask.charAt(i) == '9' || mask.charAt(i) == 'L' || mask.charAt(i) == 'l' || mask.charAt(i) == 'A') {
> // the current mask character is one of the predefined/reserved characters
> this.viewMask += '_';
> this.maskArray[mai] = mask.charAt(i);
> mai++;
> } else {
> // just a regular char
> this.viewMask += mask.charAt(i);
> this.maskArray[mai] = mask.charAt(i);
> mai++;
> }
> }
> // the predefined/reserved characters need to be replaced with the viewing mask char that desigantes an editable value (underscore)
> this.specialChars = this.viewMask.replace(/(L|l|9|A|_|X)/g,'');
> this.getValidatedKey = function(keyCode, cursorPosition) {
> // validates if the passed key code is valid for the specified cursor position and returns the value if it is. otherwise, return false
> var maskKey = this.maskArray[cursorPosition.start];
> if(maskKey == '9'){
> // only allow numbers at the specified slot
> return keyCode.pressedKey.match(/[0-9]/);
> } else if(maskKey == 'L'){
> // only allow uppercase letters at specified slot (convert if necessary)
> return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toUpperCase(): null;
> } else if(maskKey == 'l'){
> // only allow lowercase letters at specified slot (convert if necessary)
> return (keyCode.pressedKey.match(/[A-Za-z]/))? keyCode.pressedKey.toLowerCase(): null;
> } else {
> if(maskKey == 'A'){
> // only allow alpha-numeric values at the specified slot
> return keyCode.pressedKey.match(/[A-Za-z0-9]/);
> } else {
> // only allow values that are verified by the specified regexp at the specified slot
> return (this.maskArray[cursorPosition.start].length > 1)? keyCode.pressedKey.match(new RegExp(maskKey)): null;
> }
> }
> };
> this.removeValueWhenInvalid = function(){
> // removes value from the input element when the mask is incomplete
> if(this.inputTextElement.value.indexOf('_') > -1){
> this.inputTextElement.value = '';
> }
> };
> this.processMaskFormatting = function(e) {
> // capture event (should be the keydown event)
> var onKeyDownEvent = InputTextMask.getEvent(e);
> // create the key code from the event.
> var keyCode = new InputTextMask.KeyCode(onKeyDownEvent);
> if(InputTextMask.handleEventBubble(onKeyDownEvent, keyCode)){
> // the pressed key is allowed to propagate- no mask injection required
> return true;
> }
> var v = this.inputTextElement.value;
> if(v.length === 0){
> // when the input value is empty populate it with the viewing mask
> this.inputTextElement.value = this.viewMask;
> }
> var cursorPos = InputTextMask.getCursorPosition(this.inputTextElement, v);
> if(cursorPos.end == cursorPos.previousValue.length && !keyCode.isBackspace){
> // input cursor position is at the end of the mask- do not allow any more characters to be keyed
> return false;
> }
> // move the cursor position to the next slot that does not contain a mask character
> while(this.inputTextElement.mask.specialChars.match(RegExp.escape(cursorPos.previousValue.charAt(((keyCode.isBackspace)? cursorPos.start-1: cursorPos.start))))){
> if(keyCode.isBackspace) {
> // backspace needs to move the cursor backwards
> cursorPos.decStart();
> } else {
> // still moving cursor one space to the right
> cursorPos.incStart();
> }
> if(cursorPos.start >= cursorPos.previousValue.length || cursorPos.start < 0){
> // end of the mask- no more keys should be keyed
> return false;
> }
> }
> if(keyCode.isBackspace){
> // need to go back one space to the left
> cursorPos.decStart();
> }
> // inject the key that was pressed into the input value mask
> if(InputTextMask.injectValue(this.inputTextElement, keyCode, cursorPos)){
> // when the injection is sucessful move the cursor to the next slot to the right of the injected key
> InputTextMask.moveCursorToPosition(this.inputTextElement, keyCode, cursorPos);
> }
> // because the pressed key is being injected we always need to return false to prevent duplicate
> // key injection
> return false;
> };
> },
> KeyCode: function(onKeyDownEvent) {
> this.onKeyDownEvent = onKeyDownEvent;
> // get the unicode value from the key event
> this.unicode = onKeyDownEvent.which? onKeyDownEvent.which: (onKeyDownEvent.keyCode? onKeyDownEvent.keyCode: (onKeyDownEvent.charCode? onKeyDownEvent.charCode: 0));
> this.isShiftPressed = onKeyDownEvent.shiftKey == false || onKeyDownEvent.shiftKey == true? onKeyDownEvent.shiftKey: (onKeyDownEvent.modifiers && (onKeyDownEvent.modifiers & 4)); //bitWise AND
> // TODO : need to get cap lock capture for onkeydown event
> //this.isCapLock = ((!this.isShiftPressed && this.unicode >= 65 && this.unicode <= 90) || (this.unicode >= 97 && this.unicode <= 122 && this.isShiftPressed));
> if(this.unicode >= 96 && this.unicode <= 105) {
> this.unicode -= 48; // handle number keypad
> }
> if(this.unicode >= 65 && this.unicode <= 90 && !this.isShiftPressed){
> this.unicode += 32; // handle uppercase
> }
> this.isTab = (this.unicode == 9)? true: false;
> this.isBackspace = (this.unicode == 8)? true: false;
> this.isLeftOrRightArrow = (this.unicode == 37 || this.unicode == 39)? true: false;
> // capture the actual key for the passed key code
> this.pressedKey = String.fromCharCode(this.unicode);
> },
> CursorPosition: function(start, end, range, previousValue) {
> // holds the cursor position values
> this.start = isNaN(start)? 0: start;
> this.end = isNaN(end)? 0: end;
> this.range = range;
> this.previousValue = previousValue;
> this.incStart = function(){
> this.start++;
> };
> this.decStart = function(){
> this.start--;
> };
> }
> };
> // Add escape prototype feature to RegExp object
> // text.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$0');
> // text.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, '\\$1');
> if(!RegExp.escape) {
> RegExp.escape = function(text){
> var sp;
> if(!arguments.callee.sRE){
> sp=['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
> arguments.callee.sRE = new RegExp('(\\' + sp.join('|\\') + ')','g');
> }
> return text.replace(arguments.callee.sRE, '\\$1');
> };
> }
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org