Edit

Specific UI Element Handler Names

Since common UI handlers tend to need to be implemented for specific window classes or fields, there is an easy way to implement these handlers for their specific target.

For the following handlers, you can write a handler that specifies its windowID class and optional additional scope in the handler name:

  • Before:windowID:transtype
  • ItemHit:windowID:transtype
  • Validate:windowID:transtype
  • After:windowID:transtype
  • Cancel:windowID:transtype
  • Close:windowID:transtype
  • ValidateField:windowID:fieldindent:transtype
  • EnterField:_windowID:fieldindent:transtype
  • ExitedField:windowID:fieldindent:transtype
  • EnterCell:windowID:listname:columnname:transtype
  • ValidateCell:windowID:listname:columnname:transtype
  • ExitedCell:windowID:listname:columnname:transtype

The transtype specifier only applies to the Transaction entry window and will not be present for any other kind of window. Your handler will only be called if all of the specifiers match. To have your handler called more generally, simply use fewer specifiers (note that the specifiers are necessarily positional, so you can only reduce specificity by dropping specifiers from the end). If there are multiple handlers for the same message in your script that match, they will all be called, beginning with the most specific. E.g. if you have ValidateField:f_trans:e_user1:DI and also ValidateField:f_trans, they will both be called, in that order (assuming the first one does not return false, in which case the call sequence would stop at that point).

Example:

    // will be called for all transaction entry window fields
    on ValidateField:f_trans
        say("validate trans field")
    return 1
    end
    
    // will only be called for transaction user1 field for a sales invoice
    on ValidateField:f_trans:e_user1:DI
    say("validate sales invoice user1")
    return 1
    end

Note: You SHOULD always return a value (0 or 1) for these validation handlers, however, if you fail to do so, 1 is the default return value.

Important: You should generally never implement a non-specific handler (such as Before or Validate, with no window id) unless you take great care to limit your functionality appropriately. Remember that even the script editor receives these messages.

Other ways of invoking handlers

You can install a handler in the Command menu using the InstallMenuCommand function. You would normally do this from your script's Load handler. The command will be uninstalled automatically when the script is unloaded (or you can do so explicitly by calling the InstallMenuCommand function again with an empty handler name).

You can install a handler in the Transaction Entry and list windows using the InstallToolbarIcon function. Do this from the Before handler for the window. The icon will be automatically uninstalled prior to another Before (so you should reinstall it for every Before message). This is so that you can easily install a transaction-type-specific toolbar icon. Lists will get a Before every time the toolbar changes (such as for a change of selected view).

To make a handler accessible to reports, forms, the evaluate external command, different scripts, or the entry field expression parser, use the public attribute in the handler declaration.

    on MyHandlerName(myParam) public
        say("This is the public handler " + myParam)
    end

External invocations of the message will need to use its public name, consisting of the script name, a colon, and the handler name (e.g. My_Script:MyHandlerName(x)). If the script is not currently loaded, you won't be able to compile a script that calls it. Inter-script calling is not recommended.

Scripts normally run with the privileges of the logged-in user. You can have a handler run with admin privileges by adding the elevated attribute to the handler declaration. Note that the extra privilege is dropped when the handler exits, so the operation requiring the privilege will have to be completed in its entirety.

    on MyHandlerName(myParam) elevated
        say("I'm running with admin privileges")
        // hmm what would be useful to do here?
        //   • post without elective posting privilege?
        //   • override the extension field with a discounted value ✓
        //   • replace a value in a selection?
        //   • Clear the hold checkbox with SetFieldValue()?
    end