I'm trying to add validation to my edittext controls. I need to make sure they are always numeric values. I've seen a number of posts indicating various methods for accomplishing this, but my edittext control is always returning an 'undefined' value regardless of whether I add a number or a letter. I can see the correct value in the debugger's view of the control, but the code fails. Can anyone please tell me what I'm doing wrong here?
CreateDialog.prototype.run = function()
{
// declare a bunch of vars
// Create a window of type palette.
var win = new Window("dialog", "Element Spray Generator",[iTop,iLeft,iTop + iWidth,iLeft + iHeight] ); // bounds = [left, top, right, bottom]
this.windowRef = win;
// add a bunch of other stuff...
win.txtEditScaleJitter = win.btnPanel.add("edittext",[win.btnPanel.bounds.width/5*4-iPadding, win.txtScaleJitter.bounds.top, win.btnPanel.bounds.width-iPadding, win.txtScaleJitter.bounds.bottom], "100%")
//Textbox events
win.txtEditScaleJitter.onChanging = function() {
//**** here win.txtEditScaleJitter.text is always undefined ******
var testCharacter = win.txtEditScaleJitter.text.charAt(win.txtEditScaleJitter.text.length -1);
switch(testCharacter ){
case "0": case "1": case "2": case "3":case "4": case "5":case "6":case "7":case "8": case "9": break;
default: alert("You entered a character that is not a number --> " + testCharacter + " <--"); break;
}
};
// Display the window
win.show();
return true;
}
Here is one example of checking for numeric entry.
var dlg=
"dialog{text:'Script Interface',bounds:[100,100,470,170],"+
"test:EditText{bounds:[10,10,360,30] , text:'' ,properties:{multiline:false,noecho:false,readonly:false}},"+
"button1:Button{bounds:[10,40,350,60] , text:'Cancel' }};"
var win = new Window(dlg,'test');
win.center();
win.test.onChanging = function() {
if (this.text.match(/[^\d]/)) {
this.text = this.text.replace(/[^\d]/g, '');
}
}
win.show();
You can also set up an event handler to check as the user enters test into the control. Below is an example that uses a keyboard event handler to allow only integers and an onChanging to check the integer's range is between 0 and 100.
////////////////////////////////////////////////////////////////////// /////////
// Function: NumericEditKeyboardHandler
// Usage: Do not allow anything except for numbers 0-9
// Input: ScriptUI keydown event
// Return: <nothing> key is rejected and beep is sounded if invalid
// From the script 'Fit Image.jsx' by Adobe
////////////////////////////////////////////////////////////////////// /////////
function NumericEditKeyboardHandler (event) {
try {
var keyIsOK = KeyIsNumeric (event) ||
KeyIsDelete (event) ||
KeyIsLRArrow (event) ||
KeyIsTabEnterEscape (event);
if (! keyIsOK) {
// Bad input: tell ScriptUI not to accept the keydown event
event.preventDefault();
/* Notify user of invalid input: make sure NOT
to put up an alert dialog or do anything which
requires user interaction, because that
interferes with preventing the 'default'
action for the keydown event */
app.beep();
}
}
catch (e) {
; // alert ("Ack! bug in NumericEditKeyboardHandler: " + e);
}
}
// key identifier functions
function KeyIsNumeric ( event ) {
return ( event.keyName >= '0' ) && ( event.keyName <= '9' ) && ! KeyHasModifier ( event );
}
function KeyIsFloat ( event ) {
return ( event.keyName.match( /[0-9.]/i ) != null ) && ! KeyHasModifier ( event );
}
function KeyHasModifier ( event ) {
return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;
}
function KeyIsDelete (event) {
// Shift-delete is ok
return (event.keyName == 'Backspace') && ! (event.ctrlKey);
}
function KeyIsLRArrow (event) {
return ((event.keyName == 'Left') || (event.keyName == 'Right')) && ! (event.altKey || event.metaKey);
}
function KeyIsTabEnterEscape (event) {
return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';
}
createDialog = function ( ) {
var dlg = new Window( 'dialog', 'Example Dialog' );
dlg.maskSt = dlg.add( 'edittext', undefined, '' );
dlg.maskSt.preferredSize = [40,20];
// Add a panel for main dialog buttons
dlg.btnPnl = dlg.add( 'panel', undefined, 'Process' );
dlg.btnPnl.orientation = "row";
dlg.btnPnl.alignment = "right";
dlg.btnPnl.okBtn = dlg.btnPnl.add( 'button', undefined, 'Ok', { name:'ok' });
dlg.btnPnl.cancelBtn = dlg.btnPnl.add( 'button', undefined, 'Cancel', { name:'cancel' });
return dlg;
};
initializeDialog = function( w ) {
with ( w ) {
maskSt.addEventListener ('keydown', NumericEditKeyboardHandler );
maskSt.onChange = function() {
// range check if needed
if( Number(this.text) < 0 || Number(this.text) > 100 ){
alert('Out of range');
this.text = '';
}
}
with ( btnPnl ) {
// The Ok and Cancel buttons close this dialog
okBtn.onClick = function ( ) { this.parent.parent.close( 1 ); };
cancelBtn.onClick = function ( ) { this.parent.parent.close( 2 ); };
}
}
};
runDialog = function( w ) {
return w.show( );
};
var win = createDialog();
initializeDialog( win );
runDialog( win );
You must have had a BIG cup of coffee. I just tried and no mater how fast I typed I could only enter numbers.
It might be better to change onChange to onChanging either way as that would test the range while the control has focus and handle any alpha chars the keyboard hander may have missed.
And sorry, I should have pointed out that mouse and keyboard events only work in CS4.
By the way. it really only has one more event handler ( NumericEditKeyboardHandler ) than your example. And in my posted example the onChage event doesn't occur until the control loses focus, so there are only two active event handlers while the user types with either exampe.
All the extra helper functions do is eval expressions. I would think those run very much faster than one could type.
Sorry Paul,
It's not that I did not believe you. I just don't understand how it can happen. But it's good to know.
Would you mind testing to see if you can enter alpha chars into the Fit Image dialog in CS4? That is where I got the code from, maybe I missed something when I extracted this function that I didn't catch.
That's good to know. I was starting to think that I would have to ask you if I could come visit for coffee and typing lessons.
Did you have ESTK as the target or Photoshop when you did your testing?
I had looking at Fit Image in CS4 to try to learn how to use javascriptresource to write a plugin script. I saw those functions and thougth they would be useful in other scripts so I extraced and extended to handle integer, floats, alphas, and hex.
I came across this thread looking to set up an editField to only allow numbers. Using the code posted by Michael in post#9 works, except for decimals when I use the 'KeyIsFloat' function. If I use the following:
var keyIsOK = KeyIsFloat (event);
I get the numbers only; it won't allow me to enter a decimal value at all. I have tried both the period key on the keyboard, as well as the numeric keypad, but no luck with either. I'm on a Mac, and tried the same code with both CS4 & CS5. I even tried changing the regEx to only allow the decimal (/\./) and that didn't work either.
Can anyone suggest why this won't allow me to enter a decimal?
You can't enter decimals because I didn't have the function coded correctly. Here is the version I am using now.
function KeyIsFloat ( event ) {
return ((( event.keyName >= '0' ) && ( event.keyName <= '9' )) || event.keyName == 'Decimal' ||
event.keyName == 'Period' || event.keyName == 'Minus') && ! KeyHasModifier ( event );
};
Thank you both. Yes, Paul, i had added a call to the KeyIsFloat function, and when that didn't work, I stripped out all of the calls except for that one to isolate the issue.
Thanks for the update, Michael. I'll apply that in the morning. I was assuming that the value might be something other than '.', but I wasn't able to diagnose by adding a breakpoint. Is there a limit to using event listeners that prevents using breakpoints in the debugger?
I find that setting breakpoints( red dots on the left side of the window ) doesn't work with event or dialog control callbacks. For those I force the stop using
$.level = 1;
debugger;
It takes a little more effort but it always breaks. For me at least, ESTK will sometimes ignore breakpoints no matter where they are.
Some new informaiton on this subject has come to light during our localization testing.
On certain keyboards and languages the Shift/Alt/Ctrl key must be pressed TO GET A NUMBER!
We had to remove our onChange handlers and go to verefying inputs during the "OK" button click.
What we need is a "what is the character that this keyboard combination is about to produce" vs what we have today with looking at modifiers. That call does not exist today.
Wanting to accept numbers can mean a lot of different things. Handling digits is relatively easy. When you have to deal with
floating point numbers, things get a bit gnarly because of localization issues. A decimal mark can be any of ".,-/" and mixing
in digit grouping separators just makes matters worse.
For what it's worth, I'm using this sort of code for keystroke filtering:
function filterKey(event) {
var obj = event.currentTarget;
var filter = obj.keyFilter; // a RegExp
var c = Number("0x" + event.keyIdentifier.substring(2));
var key = String.fromCharCode(c);
if (filter && key.match(filter)) {
return;
} else if (event.keyName.length == 1) {
// bail if it was a simple character that we couldn't match
event.stopPropagation();
event.preventDefault();
}
};
function addNumericFilter(obj) {
obj.keyFilter = /\d/;
obj.addEventListener('keydown', filterKey);
};
//...
addNumericFilter(pnl.textField);
It has the (dis)advantage of using RegExp for filtering, but it makes it easy to add new keystroke filters and gets around some of the issues of using onChanging.
North America
Europe, Middle East and Africa
Asia Pacific