Skip navigation
Currently Being Moderated

Edittext onChange has undefined value?

Sep 11, 2009 5:44 AM

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

 
Replies
  • Currently Being Moderated
    Sep 11, 2009 6:15 AM   in reply to annaforrest

    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();

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 8:00 AM   in reply to annaforrest

    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 );

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 9:04 AM   in reply to Michael L Hale

    It doesn't work at all in CS3 and with CS4 if you type fast enough you can still enter non numeric characters that are not removed.

    I wonder if it can't cope with all those handlers?

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 9:33 AM   in reply to Paul Riggott

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 9:49 AM   in reply to Michael L Hale

    Even with onChanging I can still enter letters...

    UIexample.jpg

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 9:52 AM   in reply to Michael L Hale

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 9:58 AM   in reply to Michael L Hale

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 10:04 AM   in reply to Michael L Hale

    Very true, in this case it might be because there were extra characters in the keyboard buffer? Anyway I'm going for another large coffee Mike.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 10:20 AM   in reply to Michael L Hale

    Just tried Fit Image and there is no way I can enter a non numeric character. I like the way it dosen't return the cursor to the begining of the field.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 1:17 PM   in reply to annaforrest

    Mike,

     

    This function is not in the 'FitImage.jsx' that comes with Photoshop CS3.  I can type in letters when I run it in CS3.  It must only run in CS4.  It probably has some 'event' not in CS3!

     

    Larry

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 1:28 PM   in reply to Larry Ligon

    Yes it is a CS4 function, and the code does work correctly, BUT not in ESTK (That's where I was testing) works fine in Photoshop so good find Mike.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 1:49 PM   in reply to Paul Riggott

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 2:00 PM   in reply to Michael L Hale

    I did all my testing in ESTK except for testing fit image and used that directly in Photoshop.

    My typing is extreamley slow, if you try it in ESTK it seems to buffer the errors, I tried writing to the console and that only worked on approx. every 10th keypress or so.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 2:16 PM   in reply to Paul Riggott

    The reason I asked is that in ESTK if I target Photoshop is works for me like it does in Photoshop - no alphas.

     

    But if I have ESTK as the traget, I do get alphas as you describe.

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 2:33 PM   in reply to Michael L Hale

    Sorry, yes the target was ESTK.

    It was odd that I didn't get an error for app.bleep(); but wasn't sure if it was reaching that line?

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 2:43 PM   in reply to Paul Riggott

    I tried both CS3 and ExtendScript Toolkit 2.02.77

     

    I could type in letters on both.

     

    Larry

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 11, 2009 2:54 PM   in reply to Larry Ligon

    This is the new CS4 Fit Image that has keyboard events, they didn't exist in CS3.

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 13, 2012 1:58 PM   in reply to Michael L Hale

    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?

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 13, 2012 2:17 PM   in reply to MarkWalsh

    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 );
    };
    
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 13, 2012 2:22 PM   in reply to MarkWalsh

    Also make sure you add KeyIsFloat(event)  as the original does not call this function.

     

     

    function NumericEditKeyboardHandler (event) {
    try {
    var keyIsOK = KeyIsNumeric (event) || 
    KeyIsDelete (event) || 
    KeyIsLRArrow (event) ||
    KeyIsTabEnterEscape (event);
    
    ..........
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 13, 2012 4:32 PM   in reply to Michael L Hale

    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?

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 13, 2012 6:44 PM   in reply to MarkWalsh

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 14, 2012 1:10 PM   in reply to annaforrest

    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.

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 14, 2012 3:08 PM   in reply to Tom Ruark

    Tom,

     

    What I think we really need is a numeric input control or at least a creation property for edittext so it will only accept numbers. That way we wouldn't need keyboard handlers for this kind of thing.

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 15, 2012 6:31 AM   in reply to Michael L Hale

    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.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points