Infor M3 H5 Development Guide
Version 10.3.1.0
Published May 2017
Copyright © 2017 Infor
Important Notices
The material contained in this publication (including any supplementary information) constitutes and
contains confidential and proprietary information of Infor.
By gaining access to the attached, you acknowledge and agree that the material (including any
modification, translation or adaptation of the material) and all copyright, trade secrets and all other
right, title and interest therein, are the sole property of Infor and that you shall not gain right, title or
interest in the material (including any modification, translation or adaptation of the material) by virtue
of your review thereof other than the non-exclusive right to use the material solely in connection with
and the furtherance of your license and use of software made available to your company from Infor
pursuant to a separate agreement, the terms of which separate agreement shall govern your use of
this material and all supplemental related materials ("Purpose").
In addition, by accessing the enclosed material, you acknowledge and agree that you are required to
maintain such material in strict confidence and that your use of such material is limited to the
Purpose described above. Although Infor has taken due care to ensure that the material included in
this publication is accurate and complete, Infor cannot warrant that the information contained in this
publication is complete, does not contain typographical or other errors, or will meet your specific
requirements. As such, Infor does not assume and hereby disclaims all liability, consequential or
otherwise, for any loss or damage to any person or entity which is caused by or relates to errors or
omissions in this publication (including any supplementary information), whether such errors or
omissions result from negligence, accident or any other cause.
Without limitation, U.S. export control laws and other applicable export and import laws govern your
use of this material and you will neither export or re-export, directly or indirectly, this material nor any
related materials or supplemental information in violation of such laws, or use such materials for any
purpose prohibited by such laws.
Trademark Acknowledgements
The word and design marks set forth herein are trademarks and/or registered trademarks of Infor
and/or related affiliates and subsidiaries. All rights reserved. All other company, product, trade or
service names referenced may be registered trademarks or trademarks of their respective owners.
Publication Information
Release: Infor M3 H5 10.3.1.0
Publication date: < May 10, 2017 >
Infor M3 H5 Development Guide | 3
Contents
About this guide ................................................................................................................................... 9
Related documents .......................................................................................................................... 9
Contacting Infor................................................................................................................................ 9
The H5 Scripting Blog .................................................................................................................... 10
Chapter 1 Introduction .................................................................................................................. 11
Scripting overview .......................................................................................................................... 11
Resources ...................................................................................................................................... 11
Creating a script in M3 H5 ............................................................................................................. 12
Contents of a script file .................................................................................................................. 12
Example Script......................................................................................................................... 12
Init method ............................................................................................................................... 12
Element parameter .................................................................................................................. 13
Args parameter ........................................................................................................................ 13
Controller parameter ................................................................................................................ 13
Log parameter ......................................................................................................................... 13
Debug parameter (deprecated) ............................................................................................... 13
M3 H5 limitations ........................................................................................................................... 14
M3 H5 script minification ................................................................................................................ 14
Chapter 2 Developing scripts ....................................................................................................... 15
Development environment ............................................................................................................. 15
Prerequisites ............................................................................................................................ 15
Using Visual Studio ................................................................................................................. 15
Configuring the project ...................................................................................................... 15
Running Samples .............................................................................................................. 16
Debugging ......................................................................................................................... 16
Adding a new script to the solution ................................................................................... 17
Using VS Code and Node.js .................................................................................................... 17
Contents
4 | Infor M3 H5 Development Guide
Opening project in VS Code .............................................................................................. 17
Running Samples on a Node.js server ............................................................................. 17
Adding a new script to the project ..................................................................................... 18
Debugging in browsers ............................................................................................................ 18
MForms Panel Layout .................................................................................................................... 18
Adding Content to a Form ....................................................................................................... 19
Element layout ......................................................................................................................... 19
Events ...................................................................................................................................... 19
Example ................................................................................................................................... 19
Chapter 3 Deploying scripts ......................................................................................................... 21
Deploying a customized script in M3 H5 ....................................................................................... 21
Chapter 4 Adding scripts to a form ............................................................................................. 23
Adding a personalized script to a form .......................................................................................... 23
Adding a script shortcut ................................................................................................................. 23
Chapter 5 Public APIs.................................................................................................................... 25
API Overview ................................................................................................................................. 25
InstanceController .......................................................................................................................... 25
Properties ................................................................................................................................ 25
RenderEngine: RenderEngine .................................................................................. 25
Requesting: InstanceEvent .................................................................................... 26
Requested: InstanceEvent ...................................................................................... 26
RequestCompleted: InstanceEvent ....................................................................... 26
Functions ................................................................................................................................. 26
GetContent() ...................................................................................................................... 26
GetContentElement() ........................................................................................................ 26
GetElement() ..................................................................................................................... 26
GetGrid() ............................................................................................................................ 27
GetInstanceId() .................................................................................................................. 27
GetMode() ......................................................................................................................... 27
GetPanelName() ............................................................................................................... 27
GetProgramName() ........................................................................................................... 28
GetSortingOrder() .............................................................................................................. 28
GetValue() ......................................................................................................................... 28
GetView() ........................................................................................................................... 28
ListOption() ........................................................................................................................ 29
Contents
Infor M3 H5 Development Guide | 5
PageDown()....................................................................................................................... 29
PressKey() ......................................................................................................................... 29
SetValue().......................................................................................................................... 29
ShowMessage() ................................................................................................................ 30
ShowMessageInStatusBar() ............................................................................................. 30
Request Event Arguments ............................................................................................................. 30
RequestEventArgs .............................................................................................................. 30
CancelRequestEventArgs ................................................................................................. 30
RenderEngine ................................................................................................................................ 31
Properties ................................................................................................................................ 31
Content: ContentElement ........................................................................................ 31
Functions ................................................................................................................................. 31
ShowMessage() ................................................................................................................ 31
ListControl ...................................................................................................................................... 31
Properties ................................................................................................................................ 32
ListView ......................................................................................................................... 32
Functions ................................................................................................................................. 32
Columns() .......................................................................................................................... 32
GetColumnIndexByName() ............................................................................................... 32
Headers() ........................................................................................................................... 32
ListView .......................................................................................................................................... 33
Functions ................................................................................................................................. 33
GetValueByColumnIndex() ............................................................................................... 33
GetValueByColumnName() ............................................................................................... 33
SelectedItem() ................................................................................................................... 33
SetValueByColumnIndex() ................................................................................................ 34
SetValueByColumnName() ............................................................................................... 34
ScriptDebugConsole (deprecated) ................................................................................................ 34
Functions ................................................................................................................................. 35
WriteLine() ......................................................................................................................... 35
Clear() ................................................................................................................................ 35
ScriptLog ........................................................................................................................................ 35
Functions ................................................................................................................................. 35
Error() ................................................................................................................................ 35
Warning() ........................................................................................................................... 36
Info() .................................................................................................................................. 36
Debug() .............................................................................................................................. 36
Contents
6 | Infor M3 H5 Development Guide
Trace() ............................................................................................................................... 36
SetDefault() ....................................................................................................................... 37
SetDebug() ........................................................................................................................ 37
SetTrace().......................................................................................................................... 37
ScriptUtil ......................................................................................................................................... 37
Functions ................................................................................................................................. 38
AddEventHandler() ............................................................................................................ 38
ApiRequest() (deprecated) ................................................................................................ 38
DoEnterpriseSearch()........................................................................................................ 39
FindChild() ......................................................................................................................... 39
GetFieldValue() ................................................................................................................. 39
GetUserContext() .............................................................................................................. 40
Launch() ............................................................................................................................ 40
LoadScript() ....................................................................................................................... 40
OpenMenu() ...................................................................................................................... 41
RemoveEventHandler() ..................................................................................................... 41
SetFieldValue() .................................................................................................................. 41
SessionCache ................................................................................................................................ 42
Functions ................................................................................................................................. 42
Add() .................................................................................................................................. 42
ContainsKey() .................................................................................................................... 42
Get() .................................................................................................................................. 43
Remove() ........................................................................................................................... 43
InstanceCache ............................................................................................................................... 43
Functions ................................................................................................................................. 44
Add() .................................................................................................................................. 44
ContainsKey() .................................................................................................................... 44
Get() .................................................................................................................................. 44
Remove() ........................................................................................................................... 45
ConfirmDialog ................................................................................................................................ 45
Functions ................................................................................................................................. 45
ShowMessageDialog() ...................................................................................................... 45
ContentElement ............................................................................................................................. 46
Functions ................................................................................................................................. 47
Add() .................................................................................................................................. 47
AddElement()..................................................................................................................... 47
CreateElement() ................................................................................................................ 47
Contents
Infor M3 H5 Development Guide | 7
GetContentBody() ............................................................................................................. 48
GetElement() ..................................................................................................................... 48
GetPrevContainer() ........................................................................................................... 48
OnUnload() ........................................................................................................................ 49
Unload() ............................................................................................................................. 49
MFormsAutomation ....................................................................................................................... 49
Functions ................................................................................................................................. 50
addStep() ........................................................................................................................... 50
addField() .......................................................................................................................... 50
setFocus().......................................................................................................................... 50
toEncodedURI() ................................................................................................................. 51
MIService ....................................................................................................................................... 51
Functions ................................................................................................................................. 51
executeRequest() .............................................................................................................. 51
execute() ............................................................................................................................ 52
Chapter 6 MForms Automation .................................................................................................... 53
What is MForms Automation? ....................................................................................................... 53
Automation Sequences .................................................................................................................. 53
Automation Steps .................................................................................................................... 54
Automation Fields .................................................................................................................... 54
Example ............................................................................................................................. 55
Automation XML ...................................................................................................................... 55
Examples ........................................................................................................................... 55
Starting Automations in M3 H5 ................................................................................................ 56
URI Format ........................................................................................................................ 56
Example ............................................................................................................................. 56
Helper Class ............................................................................................................................ 56
Chapter 7 MI Service ...................................................................................................................... 57
MIRequest ...................................................................................................................................... 57
Example ......................................................................................................................................... 58
Chapter 8 Drillback ........................................................................................................................ 59
Invoking a drillback ........................................................................................................................ 59
infor.companyon.client.sendPrepareDrillbackMessage()........................................................ 59
Drillback parameters ...................................................................................................................... 59
Examples ................................................................................................................................. 60
Contents
8 | Infor M3 H5 Development Guide
Chapter 9 Best practices ............................................................................................................... 63
Use H5 functions and properties that are documented ................................................................. 63
Use recommended API functions .................................................................................................. 63
Use proper logging utility ............................................................................................................... 64
Use TypeScript .............................................................................................................................. 64
Be wary of using ES6/ES2016 features ........................................................................................ 64
Minify scripts .................................................................................................................................. 64
Chapter 10 Script examples ............................................................................................................ 65
H5SampleHelloWorld.ts ................................................................................................................. 65
H5SampleUserDetails.ts ................................................................................................................ 66
H5SampleShowXml.ts ................................................................................................................... 67
H5SampleOptionButton.ts ............................................................................................................. 68
H5SamplePreviewListHeader.ts .................................................................................................... 70
H5SampleShowOnMap.ts ............................................................................................................. 72
H5SampleMFormsAutomation.ts ................................................................................................... 74
H5SampleRegexValidator.ts ......................................................................................................... 75
H5SampleRequestTracer.ts .......................................................................................................... 78
H5SampleCancelRequest.ts ......................................................................................................... 80
H5SampleOpenFieldHelp.ts .......................................................................................................... 81
H5SampleCustomColumns.ts ....................................................................................................... 82
H5SampleMIService.ts .................................................................................................................. 83
H5SampleImageFromList.ts .......................................................................................................... 87
H5SampleDrillback.ts .................................................................................................................... 89
Chapter 11 Appendix ....................................................................................................................... 91
Node.js ........................................................................................................................................... 91
Install Node.js .......................................................................................................................... 91
Verify the Node package manager .......................................................................................... 91
Verify the Node executable ..................................................................................................... 92
TypeScript ...................................................................................................................................... 92
Infor M3 H5 Development Guide | 9
About this guide
The M3 H5 Development Guide provides conceptual and how-to information for developing,
deploying and adding scripts to MForms. It also contains information about the public APIs and script
examples that the user can use as a guide in scripting.
This guide is for developers who want to create and deploy scripts for M3 H5.
Related documents
You can find the documents in the product documentation section of the Infor Xtreme Support portal,
as described in the following section.
M3 UI Adapter Installation Guide for LifeCycle Manager 9.x
M3 UI Adapter Installation Guide for LifeCycle Manager 10.x
M3 Core Administration Guide - Windows
Infor M3 H5 User and Administration Guide
Contacting Infor
If you have questions about Infor products, go to the Infor Xtreme Support portal at
www.infor.com/inforxtreme.
If we update this document after the product release, we will post the new version on this Web site.
We recommend that you check this Web site periodically for updated documentation.
If you have comments about Infor documentation, contact documentation@infor.com.
Introduction
10 | Infor M3 H5 Development Guide
The H5 Scripting Blog
We recommend visiting the H5 scripting blog for information, feedback, and questions.
https://smartofficeblog.com/h5-scripting/
Infor M3 H5 Development Guide | 11
Chapter 1 Introduction
1
Scripting overview
You can use one or more scripts that can be connected to a form to extend the functionality of M3
forms in H5. By adding a script to a form, the script has access to the form, and can add and modify
content.
These scripts are a type of personalization and are deployed to a server as JavaScript files using an
administration tool. It will have access to public classes exposed by the M3 H5 framework.
Scripts can be developed using JavaScript or TypeScript but the latter is preferred for it adds typing,
compilation and refactoring support. More information on developing with TypeScript is provided in
the next chapter.
Scripts can also use jQuery, a fast, small, and feature-rich JavaScript library that makes tasks, such
as HTML document traversal and manipulation, event handling, animation, and Ajax, much simpler
with an easy-to-use API that works across a multitude of browsers.
Resources
Following is a list of resources to develop scripts:
For information about
URL
jQuery API Documentation
http://api.jquery.com/
TypeScript
http://www.typescriptlang.org/docs/tutorial.html
Template and Samples (KB 1909067)
https://www.inforxtreme.com/espublic/EN/answerlinkdot
net/SoHo/Solutions/SoHoViewSolution.aspx?SolutionID
=1909067
Introduction
12 | Infor M3 H5 Development Guide
Creating a script in M3 H5
Scripts can be created using a Web development IDE or an external text editor as these are client-
side scripts only. The development setup and script debugging are detailed in the next chapter.
Contents of a script file
A script file must follow certain rules to be used by the H5 framework. If the script does not follow
these rules, it will not be executed.
The script class name must match the script file name (excluding the file extension).
The script must have a public function called Init with a specific signature.
Important: If there is a mismatch between the script class and the script file name, the script will not
work when it is deployed to the server.
Example Script
var test = new function{
this.Init = function(scriptArgs){
var controller = scriptArgs.controller;
var args = scriptsArgs.args;
var element = scriptArgs
var log = scriptArgs.log;
/* Write code here */
}
}
The following method and parameters describe the content of the script file.
Init method
The script must have a public function called Init with this signature:
this.Init = function(scriptArgs){
/* Write code here */
}
The scriptArgs parameter of the Init method contains JSON object that can be used to access
elements or objects from the framework. These parameters are detailed in the following sections.
Introduction
Infor M3 H5 Development Guide | 13
Element parameter
The element parameter is the control to which the script is connected. The argument is null if the
script is not connected to a specific element. The element parameter can be a TextBox, ComboBox,
CheckBox, and so on, depending on which element the script is attached to. To access the element:
this.Init = function(scriptArgs){
var element = scriptArgs.elem;
}
Args parameter
The args parameter contains the script arguments string. The value is null if no arguments were
specified. To access args:
this.Init = function(scriptArgs){
var args = scriptArgs.args;
}
Controller parameter
The controller is the InstanceController for the current program. This is used to access the
content of an M3 form. To access the controller:
this.Init = function(scriptArgs){
var controller = scriptArgs.controller;
}
Log parameter
The log parameter is an instance of ScriptLog and can be used for logging to the browser
console. To access log:
this.Init = function(scriptArgs){
var log = scriptArgs.log;
}
Debug parameter (deprecated)
The debug parameter is an instance of the class ScriptDebugConsole. This has been deprecated
in favor of the log propery. To access debug:
Introduction
14 | Infor M3 H5 Development Guide
this.Init = function(scriptArgs){
var debug = scriptArgs.debug;
}
M3 H5 limitations
The H5 scripts have more limitations compared to MForms JScript in SmartOffice, mostly due to the
web platform and not specific to H5. Some examples of the limitations are as follows:
No access to file system or applications
Cross domain calls are not allowed by default
Browser restrictions for window/iframe access
M3 H5 script minification
The H5 script files should be minified before they are deployed in a production environment. When
files are minified, there is less data to download, code comments are removed, and code is
obfuscated. There are also several open source script minifiers that are available and one of them
can be found at http://yui.github.io/yuicompressor/ .
Infor M3 H5 Development Guide | 15
Chapter 2 Developing scripts
2
This chapter describes how to set up the development environment, run the Samples project, and
add content to an H5 form via script written in TypeScript.
All the code examples from here on are written in TypeScript. The typing files are available for the
H5 APIs, jQuery and other frameworks.
Development environment
Prerequisites
To develop and test scripts, you will need an editor for the source files, and a web server for hosting
the files. Tools such as Visual Studio have a source code editor, debugger, and built-in web server,
while some only have a source code editor and a support for running command line tools.
The following is a selection of the tools that can be used for developing scripts:
Visual Studio Professional or Enterprise
o Requires a license
o Minimum version is Visual Studio 2013 with update 4
Visual Studio Community
o Free version of Visual Studio with limited functionality
Visual Studio Code + Node.js web server
o Visual Studio Code is free and runs on Windows, macOS and Linux
Using Visual Studio
Configuring the project
1 Open the H5 Script samples solution (Samples.sln).
2 Right click Samples tree item.
Developing scripts
16 | Infor M3 H5 Development Guide
3 Select Properties menu item.
4 Select Web tab.
5 Select Start URL radio button.
6 Set Start URL.
Here, the localScript parameter points to a single local script. The scriptCache parameter
disables script caching for development.
a URL templates
i) <H5 URL>?localScript=<IIS Express URL>/<Script name>
ii) <H5 URL>?scriptCache=false&localScript=<IIS Express URL>/<Script name>
b Example URLs:
i) https://server.infor.com:23008/mne/?localScript=http://localhost:49482/H5SampleHelloWorld.
js
ii) https://server.infor.com:23008/mne/?scriptCache=false&localScript=http://localhost:49482/H
5SampleHelloWorld.js
7 Save.
Running Samples
1 Open the H5 Script samples solution (Samples.sln).
2 Make sure that the project has been properly configured, as described in the previous section.
3 Modify the script name in the Start URL if needed.
4 Debug the project with F5 or run with Ctrl+F5. The M3 H5 application will be opened.
Debugging
Note: When running in Chrome, the same origin policy needs to be disabled.
1 Set a breakpoint in a script file.
2 To start debugging, press F5.
3 Log on to H5.
4 Start the M3 program where the script should be tested.
5 Select Tools menu item.
6 Select Scripts… menu item under Personalize.
7 Type in the edit box the script name and optional arguments.
8 Click Add.
Developing scripts
Infor M3 H5 Development Guide | 17
9 Click Save.
10 Refresh the panel with the Refresh button in the toolbar or press F5.
11 The breakpoint should be hit in Visual Studio.
Adding a new script to the solution
Alternatively, you can use the H5ScriptsProjectTemplate solution that is included in the SDK.
1 In the solution, right click on the project tree item.
2 Click Add > New Item.
3 Select Web > TypeScript File.
4 Enter Name.
5 Click Add.
Using VS Code and Node.js
Opening project in VS Code
1 Open Folder
2 Select H5ScriptSDK/Samples/Samples
This is the directory that contains the tsconfig.json file.
Running Samples on a Node.js server
1 To use a Node.js server, follow the instructions in the Appendix and make sure they are correctly
installed before trying to run the samples.
2 Double-click InstallWebServer.cmd and wait for the installation to complete.
3 Double-click StartWebServer.cmd after the web server installation. Open this file in a text editor
to modify the port number.
4 Open a browser and navigate to http://localhost:8080 to verify that the server is up.
If the default port (8080) is available, the web server will be started. If the server does not start,
check that the port is available. If the port is not available, try to start the server on another port
by editing StartWebServer.cmd in a text editor. If there are other issues with the installation,
check that NPM and Node.js is installed according to the information in the Appendix.
5 Navigate to the following URL:
<H5 URL>?scriptCache=false&localScript=<Node.js server URL>/<Script name>
Developing scripts
18 | Infor M3 H5 Development Guide
Example:
https://server.infor.com:23007/mne/?localScript=http://localhost:8080/H5SampleHelloWorld.js
To verify that the script is accessible, navigate to <Node.js server URL>/<Script name>.
Example:
http://localhost:8080/H5SampleHelloWorld.js
6 Log on to H5.
7 Start the M3 program where the script should be tested.
8 Select Tools menu item.
9 Select Scripts… menu item under Personalize.
10 Type in the edit box the script name and optional arguments.
11 Click Add.
12 Click Save.
13 Refresh the panel with the Refresh button in the toolbar or press F5.
Adding a new script to the project
1 File > New File
2 Enter file name with .ts extension, e.g., H5Test.ts.
3 Ctrl + S to save. This automatically transpiles the script to JavaScript, e.g., H5Test.js.
4 To manually compile files, Ctrl + Shift + B.
Debugging in browsers
Internet Explorer 11 and Chrome have good developer tools. To open the tools in both browsers,
press F12.
TypeScript can also be debugged in IE and Chrome using debugger map files.
MForms Panel Layout
The form that shows the content of an M3 program is located between the command bar and the
status bar. This is the form that can have its content modified by scripts. The layout of the contents
of a form is displayed based on the computed positioning of each element passed from an M3
program.
Developing scripts
Infor M3 H5 Development Guide | 19
Adding Content to a Form
The form elements can be accessed through the ContentElement, which can be retrieved from
the InstanceController. To add content to the panel, call the ContentElement.AddElement
function.
Element layout
The standard content is positioned on the form using the Top, Left, Width, and Height properties
of the PositionElement class. When you add custom elements to a form, the elements should
always be positioned using these properties.
Events
Because M3 H5 is a web-based application, script developers can utilize the default events of the
browser for the elements. For button elements, the commonly used event is the click event, which
can be used to perform additional validation and to properly handle the data to be submitted or
passed.
Events must also be properly handled. This means that some events may need to be unsubscribed
or turned off after usage to prevent memory leaks or multiple calls to the same script of different
instances. Data that is used inside the event must also be passed properly to avoid having
anonymous functions, which also causes memory leak.
Example
class H5Sample {
public static Init(args: IScriptArgs): void {
const buttonElement = new ButtonElement();
buttonElement.Name = "btnFoo";
buttonElement.Value = "Foo";
buttonElement.Position = new PositionElement();
buttonElement.Position.Top = 3;
buttonElement.Position.Left = 1;
buttonElement.Position.Width = 5;
const contentElement = args.controller.GetContentElement();
const button = contentElement.AddElement(buttonElement);
button.click({}, () => {
args.log.Info("Foo was clicked.");
});
Developing scripts
20 | Infor M3 H5 Development Guide
}
}
This TypeScript example transpiles to the following JavaScript code:
var H5Sample = (function () {
function H5Sample() {
}
H5Sample.Init = function (args) {
var buttonElement = new ButtonElement();
buttonElement.Name = "btnFoo";
buttonElement.Value = "Foo";
buttonElement.Position = new PositionElement();
buttonElement.Position.Top = 3;
buttonElement.Position.Left = 1;
buttonElement.Position.Width = 5;
var contentElement = args.controller.GetContentElement();
var button = contentElement.AddElement(buttonElement);
button.click({}, function () {
args.log.Info("Foo was clicked.");
});
};
return H5Sample;
}());
Infor M3 H5 Development Guide | 21
Chapter 3 Deploying scripts
3
Deploying a customized script in M3 H5
When a script has been developed and tested, it must be uploaded to M3 H5 in order to be available
to other users.
To upload an H5 script:
1 Go to Administration Tools.
2 Go to Data files tab.
3 Select H5 Script as file type in dropdown.
4 Click Import and locate script file.
Note: For scripts developed in TypeScript, make sure to upload the transpiled JavaScript (.js) file,
not the TypeScript (.ts) file.
Infor M3 H5 Development Guide | 23
Chapter 4 Adding scripts to a form
4
Adding a personalized script to a form
Scripts can be added to an M3 H5 form as a personalization. A script personalization can be created
by one user and then deployed to many users using global or role personalizations.
The Personalized Scripts dialog can be used to connect scripts to elements on a form.
In the form:
1 Select Tools > Personalization > Scripts
2 Select a Target element from the list. The selected element will be connected and passed as an
argument to the script. Select the blank option if there is no target element.
3 Input the name of the name of Script. This should match the name of the uploaded script.
4 Specify the script Arguments. This is optional.
5 Click Add.
6 Click Save.
7 Refresh the form for the script to take effect.
Note: If no other steps are taken, the script becomes active only for the user who created the
personalization. Scripts can be associated with roles or assigned to run globally.
Adding a script shortcut
Scripts can also be connected to shortcuts.
In the form:
1 Open the Shortcuts dialog.
a Expand Toolbox at the right side of the panel.
b Click the Shortcuts icon.
2 Expand the Advanced area.
Adding scripts to a form
24 | Infor M3 H5 Development Guide
3 Specify the Name and Value of the shortcut. These are the texts that will be displayed in the
toolbox.
4 Select the Script name from the list.
5 Specify the script Arguments. This is optional.
6 Click Add.
7 Click Save.
Infor M3 H5 Development Guide | 25
Chapter 5 Public APIs
5
API Overview
There are many public classes, methods, and properties in M3 H5 but only a number of these are
allowed for use by scripts. Many classes are public for technical reasons but should only be used
internally by the M3 H5 framework.
In scripts, use only public classes that are documented. This ensures that scripts will not break when
updated version of M3 H5 are installed.
This chapter provides the methods and properties of classes that are allowed to be used from
scripts. There are code examples on how to use them in the TypeScript syntax. The colon (:) is used
to denote variable type. Some code use arrow functions (=>), which capture the this where the
function is created rather than where it is invoked. For more information, please see the TypeScript
Handbook. The following examples are not complete and are mainly used to show the syntax.
InstanceController
Each running M3 program has one controller object. The controller provides access to the content of
a panel through the RenderEngine property and makes it possible to trigger the function keys and
list options from script code.
Properties
RenderEngine: RenderEngine
Holds controls in a panel. See RenderEngine.
Public APIs
26 | Infor M3 H5 Development Guide
Requesting: InstanceEvent
This is a cancelable event that is raised when H5 is about to make a server request. It can be used
to validate the panel before a request is started and cancel the event if the validation fails. See
Request Event Arguments.
Requested: InstanceEvent
This event is raised just before each call to the server and can be used to unsubscribe to events on
a panel and clean up other resources. See Request Event Arguments.
RequestCompleted: InstanceEvent
This event is raised when a server request is done. See Request Event Arguments.
Functions
GetContent()
Gets the content panel
Returns: JQuery A content panel
Example:
let myContent = this.controller.GetContent();
GetContentElement()
Gets the content element
Returns: ContentElement
Example:
let myContentElement = this.controller.GetContentElement();
GetElement()
Gets a named child element on the panel
Returns: JQuery The element
Example:
Public APIs
Infor M3 H5 Development Guide | 27
let myElement = this.controller.GetElement();
GetGrid()
Gets the current data grid
Returns: A data grid or null if there is no grid on the current panel
Example:
let myGrid = this.controller.GetGrid();
GetInstanceId()
Gets the ID for the current program instance
Returns: string - An instance id
Example:
let myIid = this.controller.GetInstanceId();
GetMode()
Gets the current panel mode
Returns: string
The panel mode on a detail panel will be one of:
“1” – Create
“2” – Change
“3” – Copy
“4” – Delete
“5” – Display
“” The panel mode will be blank on list panels and in other cases when the detail panel modes
do not apply
Example:
let myMode = this.controller.GetMode();
GetPanelName()
Gets the current panel name
Returns: string
Public APIs
28 | Infor M3 H5 Development Guide
Example:
let myPanelName = this.controller.GetPanelName();
GetProgramName()
Gets the current program name
Returns: string
Example:
let myProgramName = this.controller.GetProgramName();
GetSortingOrder()
Gets the current sorting order
Returns: string
Example:
let mySortingOrder = this.controller.GetSortingOrder();
GetValue()
Gets the value of a field on the current panel
Parameter:
name: string Name of the element
Returns: string A value or null
Example:
let myValue = this.controller.GetValue(“elemName”);
GetView()
Gets the current view
Returns: string A view or null if no view exists
Example:
let myView = this.controller.GetView();
Public APIs
Infor M3 H5 Development Guide | 29
ListOption()
Executes a list option request
Parameter:
option: string The option to execute, 1-99
Returns: void
Example:
this.controller.ListOption(“5”);
PageDown()
Executes a page down request
Returns: void
Example:
this.controller.PageDown();
PressKey()
Executes a key request
Parameter:
key: string The key to press, F1-F24 or ENTER
Returns: void
Example:
this.controller.PressKey(“F5”);
SetValue()
Sets the value of a field on the current panel
Parameters:
name: string The element name
val: any The element value to set
Returns: void
Example:
this.controller.SetValue(“elemName”, “elemValue”);
Public APIs
30 | Infor M3 H5 Development Guide
ShowMessage()
Shows a message in the status bar or in a message box depending on the settings for the current
user
Parameter:
message: string The message to show
Returns: void
Example:
this.controller.ShowMessage(“This is a validation message”);
ShowMessageInStatusBar()
Shows a message in the status bar
Parameter:
message: string The message to show
Returns: void
Example:
this.controller.ShowMessageInStatusBar(“This is a validation message”);
Request Event Arguments
These are the event arguments for the Requesting, Requested and RequestCompleted
events. For an example on how to cancel a request, see the Script examples chapter.
RequestEventArgs
Provides data for a request event.
CancelRequestEventArgs
Provides data for a cancelable request.
Public APIs
Infor M3 H5 Development Guide | 31
RenderEngine
The RenderEngine class generates the controls on a panel and can be used to update or add
content to a panel from scripts.
Properties
Content: ContentElement
Provides access to the content panel of an M3 panel. See ContentElement.
Functions
ShowMessage()
Shows a message in the status bar or in a dialog depending on the user settings.
This function is identical to InstanceController’s ShowMessage().
Parameter:
msg: string The message to be displayed
Returns: void
Example:
this.controller.ShowMessage(“The order number must be entered.”);
ListControl
ListControl is a wrapper object for the list that provides access to the actual ListView control and
other data related to the list
Public APIs
32 | Infor M3 H5 Development Guide
Properties
ListView
Sub-class for the actual control of the list. See ListView API.
Functions
Columns()
Provides the column name(s) of the current displayed list
Returns: string[] An array containing the four-character column name(s) of the list. This will
return an empty array if there is no column or if there is no list available.
GetColumnIndexByName()
Provides the zero-based index of a specified column name
Parameter:
colName: string The four-character name of the column
Returns: number
Example:
let myIndex = ListControl.GetColumnIndexByName(“ITNO”);
Headers()
Returns the original text for each column header(s)
Column headers can be modified using the Label personalization therefore the returned value(s)
using this method may be different from the actual displayed header text(s).
Returns: string[] An array containing the text for each column header(s). This will return an
empty array if there is no column or if there is no list available.
Example:
let myHeaders = ListControl.Headers();
Public APIs
Infor M3 H5 Development Guide | 33
ListView
Functions
GetValueByColumnIndex()
Collects all the selected item(s) then gets the values relative to the specified column index
Parameter:
colIdx: number - The column index from which the value will be retrieved
Returns: string[] An array of value(s) of the provided column index of the selected item(s).
This will return an empty array if there is no selected item or if there is no list available. null will be
returned if column index in not found.
Example:
//Get values of the first column for the selected list rows
let result = ListControl.ListView.GetValueByColumnIndex(0);
GetValueByColumnName()
Collects all the selected item(s) then gets the values relative to the specified column name
Parameter:
colName: string The column name from which the value will be retrieved
Returns: string[] An array of value(s) of the provided column name of the selected item(s).
This will return an empty array if there is no selected item or if there is no list available. null will be
returned if column index in not found
Example:
//Get values of the ITNO column for the selected list rows
let result = ListControl.ListView.GetValueByColumnName(“ITNO”);
SelectedItem()
Gets the selected rows in the list
Returns: number[] A sorted array of zero-based row number(s) of the selected item(s). This will
return an empty array if there is no selected item or if there is no list available.
Example:
Public APIs
34 | Infor M3 H5 Development Guide
let selected = ListControl.ListView.SelectedItem();
SetValueByColumnIndex()
Sets the value of a column of an editable list corresponding to the index
The value will be set to the first item of the list if there is no selected item. If there are selected items,
the value will be set to the first selected item.
Parameters:
colIdx: number The zero-based column index to which the value will be set
value: string The value to set
Returns: void
Example:
ListControl.ListView.SetValueByColumnIndex(0, “newValue”);
SetValueByColumnName()
Sets the value of a column of an editable list corresponding to the name
The value will be set to the first item of the list if there is no selected item. If there are selected items,
the value will be set to the first selected item.
Parameters:
colName: string The column name to which the value will be set
value: string The value to set
Returns: void
Example:
ListControl.ListView.SetValueByColumnIndex(0, “newValue”);
ScriptDebugConsole (deprecated)
The ScriptDebugConsole class can be used to write debug trace messages during the development
of a script. This class is now deprecated starting from version 10.3.0.0 of M3 H5. Consider using the
ScriptLog API instead.
Public APIs
Infor M3 H5 Development Guide | 35
Functions
WriteLine()
Writes a string and a new line character to the browser console.
Parameters:
text: string The string to display
Returns: void
Example:
ScriptDebugConsole.WriteLine(“testValue”);
Clear()
Clears all text written to the console.
Returns: void
Example:
ScriptDebugConsole.Clear();
ScriptLog
The ScriptLog is used in place of the ScriptDebugConsole starting from version 10.3.0 of M3 H5.
Functions
Error()
Logs an error.
Parameters:
message: string The message to be logged
Returns: void
Example:
let log = scriptArgs.log;
Public APIs
36 | Infor M3 H5 Development Guide
log.Error(“errorMessage”);
Warning()
Logs a warning message that might warn of potential problems.
Parameters:
message: string The message to be logged
Returns: void
Example:
let log = scriptArgs.log;
log.Warning(“warningMessage”);
Info()
Logs a message about an information at the log files.
Parameters:
message: string The message to be logged
Returns: void
Example:
let log = scriptArgs.log;
log.Info(“infoMessage”);
Debug()
Logs debug messages that is of main use for developers.
Parameters:
message: string The message to be logged
Returns: void
Example:
let log = scriptArgs.log;
log.Debug(“debugMessage”);
Trace()
Logs messages that are very detailed and are intended only for development.
Parameters:
Public APIs
Infor M3 H5 Development Guide | 37
message: string The message to be logged
Returns: void
Example:
let log = scriptArgs.log;
log.Trace(“traceMessage”);
SetDefault()
The SetDefault method makes the log level the same as Info().
Returns: void
Example:
let log = scriptArgs.log;
log.SetDefault();
SetDebug()
The SetDebug method makes the log level the same as Debug().
Returns: void
Example:
let log = scriptArgs.log;
log.SetDebug();
SetTrace()
The SetTrace method makes the log level the same as Trace().
Returns: void
Example:
let log = scriptArgs.log;
log.SetTrace();
ScriptUtil
The ScriptUtil class contains utility methods scripts can use.
Public APIs
38 | Infor M3 H5 Development Guide
Functions
AddEventHandler()
Attaches an event handler to an element
You can also include a namespace for the event handler that you want to attach by adding the (.)
character plus the namespace that you want to the eventType parameter. The namespace can be
used to remove just the event handler that you attached when you use the
ScriptUtil.RemoveEventHandler method.
Parameters:
element: jQuery The element to which the event handler will be attached
eventType: string The event type to which the handler will respond. Examples of event
type are “click”, “mousedown , “mousemove”, etc. The eventType parameter can also
include the namespace for the event handler. Examples are click.myClick” and
“mouseDown.myMousedown”.
callback: function(e: Event) The callback method to execute when the event occurs.
The callback method receives the Event object as a parameter.
paramData (optional): any Holds parameters to be passed the callback method. This will
become the paramData property of the Event object of the callback parameter.
Returns: void
Example:
let eventParam = { field1: “myField1”, field2: “myField2” };
ScriptUtil.AddEventHandler(button, "click", (event) => {
//Do something
});
ScriptUtil.AddEventHandler(myButton, " click.myClickEvent", function(event){
//Do something
}, eventParam);
ApiRequest() (deprecated)
Executes an M3 API call to the server. This function has been deprecated in favor of MIService.
Parameters:
URL: string The request URL to the M3 API
onSuccess (optional): function(result : Object) The function to execute if the
request is successful; accepts the result Object from the server response as parameter
onFail (optional): function(e : Object, msg : string) The method to execute if
there is an error in the request; accepts the error Object and the error message as parameters.
Use null as value for onSuccess to pass an onFail parameter only.
Public APIs
Infor M3 H5 Development Guide | 39
Returns: void
Example:
ScriptUtil.ApiRequest(url,
(result) => {
this.onSuccess(result)
}, (e, msg) => {
this.onError(e, msg)
});
DoEnterpriseSearch()
Sets value in the search input and execute the search functionality
This method can be used to execute a search query in the list of an M3 panel.
Parameter:
query: string The string to search for
controller (optional): InstanceController The instance controller; uses the active
controller by default
Returns: void
Example:
ScriptUtil.DoEnterpriseSearch(“myQuery”);
FindChild()
Finds an element in the panel
Parameters:
parent: jQuery The parent node of the element to find
elementName: string The name of the element to find
Returns: jQuery
Example:
ScriptUtil.FindChild(parent, “myChild”);
GetFieldValue()
Gets the value of a specified field
Parameter:
fieldName: string The name of the field whose value will be retrieved
Public APIs
40 | Infor M3 H5 Development Guide
controller (optional): InstanceController The instance controller; uses the active
controller by default
Returns: string The value of the field, or null if the field cannot be found.
Example:
ScriptUtil.GetFieldValue(myTextbox.attr("id"));
GetUserContext()
Gets user context data that contains login information of the user
Parameter:
contextProp (optional): string The name of the context property to get
Returns: string The value of the specified user context property. This will return null if the
property is not found. If no parameter is passed, the whole user context data object will be returned
Example:
let myCompany = ScriptUtil.GetUserContext("CurrentCompany"); //”136”
let myContext = ScriptUtil.GetUserContext();
this.log.Info(myCompany === myContext.CurrentCompany); //true
Launch()
Launches a program, file or a URL.
The default handler of the operation is used to find the program for the files or URLs.
Parameter:
task: string A program name, file name or URL to execute
Returns: void
Example:
let uri = 'https://www.google.com/maps/dir/' + encodeURI(address);
ScriptUtil.Launch(uri);
LoadScript()
Loads an external script file from the script repository
The script file must contain a class with the name similar to the name of the file.
Parameters:
URL: jQuery The location of the script file to be loaded
Public APIs
Infor M3 H5 Development Guide | 41
callback: function(data: string) A callback method to execute after the script has
been loaded. The callback method receives the string content of the loaded script file.
Returns: void
Example:
ScriptUtil.LoadScript("scripts/SampleExternalScript.js", function(data){ });
OpenMenu()
Displays a menu located in the menu bar
Parameter:
menuName: string The name of the menu to open
controller (optional): InstanceController The instance controller; uses the active
controller by default
Returns: void
Example:
ScriptUtil.OpenMenu(menuName);
RemoveEventHandler()
A utility method for removing event handlers that are attached to an element
If you attached the event handler using ScriptUtil.AddEventHandler method and included a
namespace for the event handler, you will be able to remove only that specific handler.
Parameters:
element: jQuery The element from which the event handler will be removed
eventType: string The event type for which the handler will be removed. Examples of
event type are click, mousedown, mousemove, etc. The eventType parameter can also use
a namespace associated to the event handler by adding a (.) character plus the namespace of
the handler. Examples are click.myClick and mouseDown.myMousedown. This will allow
you to remove only the event type under that namespace.
Returns: void
Example:
ScriptUtil.RemoveEventHandler(buttonElement, “click”);
ScriptUtil.RemoveEventHandler(buttonElement. “click.myClickEvent”);
SetFieldValue()
Sets the value of a specified field
Public APIs
42 | Infor M3 H5 Development Guide
Parameters:
fieldName: string The name of the field whose value will be set
value: string The value to set. This accepts true and false for a checkbox field
controller (optional): InstanceController The instance controller; uses the active
controller by default
Returns: void
Example:
let field = ScriptUtil.GetFieldValue(myTextbox.attr("id")).toUpperCase();
ScriptUtil.SetFieldValue(field, “myValue”);
SessionCache
The SessionCache is a helper class for scripts to cache items in the MForms session. Make sure to
use unique key names to avoid conflicts with other scripts when you add content to the cache.
Functions
Add()
Adds value to the cache.
If a value with the same key exists, it will be overwritten.
Parameters:
key: string The key of the value to add
value: any The value to add
Returns: void
Example:
SessionCache.Add(“progName”, “MMS001”);
ContainsKey()
Checks if a key exists in the session cache
Parameters:
key: string The key to check
Public APIs
Infor M3 H5 Development Guide | 43
Returns: boolean - true if the key exists, false otherwise.
Example:
if(SessionCache.ContainsKey(“myKey”)) {
//Do something
}
Get()
Gets a value from the session cache
Parameter:
key: string The key of the value to get
Returns: any The cached value. This will return null if key is not found.
Example:
let myCachedProgram = SessionCache.Get(“myProgram”);
Remove()
Removes a value from the session cache
Parameter:
key: string The key of the value to remove
Returns: boolean true if the key existed, false otherwise.
Example:
if(SessionCache.Remove(“myKey”) {
this.log.Info(“myKey was removed”);
}
InstanceCache
The InstanceCache is a helper class for scripts to cache items for a specific MForms instance. Make
sure to use unique key names to avoid conflicts with other scripts when adding content to the cache.
Public APIs
44 | Infor M3 H5 Development Guide
Functions
Add()
Adds a value to the instance cache
If a value with the same key exists, it will be overwritten.
Parameters:
controller: InstanceController The controller for the instance
key: string The key of the value to add
value: any The value to add
Returns: void
Example:
InstanceCache.Add(this.controller, “myKey”, true);
ContainsKey()
Checks if a key exists in the instance cache
Parameters:
controller: InstanceController The controller for the instance
key: string The key to check
Returns: boolean - true if the key exists, false otherwise.
Example:
const key = this.scriptName;
if (InstanceCache.ContainsKey(this.controller, key)) {
// The key exists in cache
}
Get()
Gets a value from the instance cache
Parameter:
controller: InstanceController The controller for the instance
key: string The key of the value to get
Returns: any The cached object. This will return null if key is not found.
Public APIs
Infor M3 H5 Development Guide | 45
Example:
let myCachedValue = InstanceCache.Get(this.controller, “myKey”);
Remove()
Removes a value from the instance cache
Parameter:
controller: InstanceController The controller for the instance
key: string The key of the value to remove
Returns: boolean true if the key existed, false otherwise.
Example:
if(InstanceCache.Remove(this.controller, “myKey”) {
this.log.Info(“myKey was removed”);
}
ConfirmDialog
The ConfirmDialog class contains a method for showing the kinds of dialogs that conform to the
design system of M3 H5.
Functions
ShowMessageDialog()
The ShowMessageDialog takes in an JSON object that can be used to define what type of Message
Dialog to be displayed.
Parameters:
options: Object A JSON object that contains the options that is available for configuring
the Message Dialog to be shown.
options.dialogType (optional): string Determines what type of dialog to be
displayed. It can be “Question”, “Information”, “Warning”, “Error” or “Success”. Default value
would be “Information”.
options.header: string The dialog header.
options.message: string More detailed message to be displayed in the dialog.
Public APIs
46 | Infor M3 H5 Development Guide
options.id: string Only required for Warning and Question dialogs.
options.withCancelButton (optional): boolean Optional property that flags if a
cancel button should be displayed or not.
options.isCancelDefault (optional): boolean Optional property that flags if the
cancel button is the default button or not.
Returns: void
Example 1:
let headerMsg = “Test Header”;
let msg = “This is a Sample Message Dialog”;
let options = {
dialogType: “Information”,
header: headerMsg,
message: msg,
id: “testScript”
};
ConfirmDialog.ShowMessageDialog(options);
Example 2:
//Retrieving the user response in a Question dialog
ConfirmDialog.ShowMessageDialog({
header: “My Question”,
message: “Are you?”,
dialogType: “Question”,
closed: (ret) => {
//If user selects Ok, ret.ok is True and ret.cancel is False
this.log.Info("Ok: " + ret.ok + " Cancel: " + ret.cancel);
}
});
ContentElement
The ContentElement object provides access to the content panel of an M3 panel.
Public APIs
Infor M3 H5 Development Guide | 47
Functions
Add()
Adds an element to the content panel
The exact width and position of the element in pixels must be specified to properly add an element
using this method.
Parameters:
element: any The HTML element to be added
Returns: void
Example:
let $list = $(“<div>”,{“class”:”inforDataGrid”});
let contentElement = this.controller.GetContentElement();
contentElement.Add($list);
AddElement()
Creates an HTML element based on the provided element data object and adds it to the content
panel
The element data can be an instance of the following: ButtonElement, CheckBoxElement,
ComboBoxElement, TextBoxElement, etc. This is an alternative to ContentElement.Add()
method.
Parameters:
elementData: any The data object regarding the element to be created
Returns: any An HTML element. The created and added element, null if no element is
created.
Example:
let buttonElement = new ButtonElement();
let contentElement = this.controller.GetContentElement();
contentElement.AddElement(buttonElement);
CreateElement()
Creates an element based on the provided data
The element data can be an instance of the following: ButtonElement, CheckBoxElement,
ComboBoxElement, TextBoxElement, etc.
Public APIs
48 | Infor M3 H5 Development Guide
Parameters:
elementData: any The data object regarding the element to be created
Returns: JQuery The element based on the provided Object data, null if no element is
created.
Example:
let buttonElement = new ButtonElement();
let contentElement = this.controller.GetContentElement();
contentElement.CreateElement(buttonElement);
GetContentBody()
Retrieves the contentBody element of the panel
Returns: JQuery An HTML element; null if not found.
Example:
let contentBody = this.controller.GetContentBody();
GetElement()
Gets an element in an M3 panel
Parameters:
elementName: string The name of the element to get
Returns: JQuery An HTML element. The element corresponding to the provided element name,
null if no element is found.
Example:
let contentElement = this.controller.GetContentElement();
let $field = contentElement.GetElement(“ITNO”);
GetPrevContainer()
Finds the immediate element container to the left of a given element container of a field
Element containers are those HTML elements with “elementContainer” class.
Parameters:
elementContainer: JQuery The element container of a field, the one with
“elementContainer” class.
Returns: JQuery An HTML element. The immediate element container to the left of the given
element container.
Public APIs
Infor M3 H5 Development Guide | 49
Example:
let $host = this.controller.ParentWindow;
let contentElement = this.controller.GetContentElement();
let $firstLabel = $host.find(“.someLabelClass”).eq(0);
let $elem =
contentElement.GetPrevContainer($firstLabel.closest(“.elementContainer”));
OnUnload()
Provides a way to add callback method to execute when the content panel unloads its content
Parameters:
callback: function() The function to execute when the content panel unloads.
Returns: void
Example:
let content = this.controller.GetContentElement();
content.OnUnload(function(){
//Code here
});
Unload()
Triggers the callback method(s) added using ContentElement.OnUnload()
This method does not remove the contents added to the content panel.
Returns: void
Example:
let content = this.controller.GetContentElement();
content.Unload();
MFormsAutomation
This is a helper class to create an automation XML and its equivalent URI, which can be used to
launch an M3 program in H5. The MForms Automation chapter discusses the feature in detail.
Public APIs
50 | Infor M3 H5 Development Guide
Functions
addStep()
Adds a step to the automation sequence.
Parameters:
action: string The command for the automation step. The available values are: Run, Key,
ListOption, Set. Use the ActionType enum to specify the value.
parameter: string The command value.
expected: string (optional) The expected value.
Returns: void
Example:
cont auto = new MFormsAutomation();
auto.addStep(ActionType.Run, “MNS150”);
auto.addStep(ActionType.Key, “ENTER”);
addField()
Adds a field to the current step.
Parameters:
name: string The name of the field.
value: string The value for the field.
Returns: void
Example:
auto.addField(“W1USID”, ScriptUtil.GetUserContext(“USID”));
setFocus()
Adds a field that sets focus.
Parameters:
name: string The name of the field.
Returns: void
Example:
auto.setFocus(“WWQTTP”);
Public APIs
Infor M3 H5 Development Guide | 51
toEncodedURI()
Converts the automation to a URI string.
Returns: string
Example:
auto.addStep(ActionType.Run, “MNS150”);
const uri = auto.toEncodedUri();
MIService
This is a helper class for calling M3 MI programs and reading the response. See the MIService
chapter for more information.
Functions
executeRequest()
Executes an MI transaction using the request object
Parameter:
request: MIRequest Contains input and information about the request. It contains the
parameters for program, transaction, record or output fields. This is detailed in the MIService
chapter.
Returns: Promise A promise that will resolve an MIResponse. If the promise is rejected, the
response will contain the error information.
Example:
const myRequest = new MIRequest();
MIService.Current.executeRequest(myRequest).then((response: IMIResponse)=>{
//Read results here
}).catch((response: IMIResponse)=>{
//Handle errors here
});
Public APIs
52 | Infor M3 H5 Development Guide
execute()
Executes an MI transaction
Parameter:
program: string The program involved in the request.
transaction: string The method to be used.
record: any (optional) An object that contains records of the data involved.
outputfields: string array (optional) Corresponding output fields.
timeout: number (optional) How long would it take for the timeout.
Returns: Promise A promise that will resolve an MIResponse. If the promise is rejected, the
response will contain the error information.
Example:
const program = “MNS150MI”;
const transaction = “GetUserData”;
const record = { USID: this.usid };
const outputFields = [“USID”, “CONO”, “DIVI”, “DTFM”];
MIService.Current.execute(program, transaction, record,
outputfields).then((response: IMIResponse)=>{
//Read results here
}).catch((response: IMIResponse)=>{
//Handle errors here
});
Infor M3 H5 Development Guide | 53
Chapter 6 MForms Automation
6
What is MForms Automation?
MForms automation makes it possible to start M3 programs and perform single automated steps on
M3 UI Adapter (MUA) server before returning the result and control to the user. The steps in the
automation sequence can set values, press keys, execute lists options and set focus, etc.
Automation data can be sent to the MNE server as a small XML document that contains the
definition of the automation Automations can be started from both Infor Smart Office and Workplace.
The automation functionality has some limitations and is not a complete replacement for LWS/BCI
scripts. It can however be a more lightweight solution for many scenarios.
One important limitation is that the automation will only work if the program starts on the panel it was
defined for (A/B etc). If the user has set a different start panel for a program the automation will not
work, it will simply stop at the start panel.
Automation Sequences
An automation sequence consists of the exact same actions that a user would do when running an
M3 BE program. The user can basically enter data on a panel and make requests to the server by
using enter, function keys and list options. The automation sequence will contain one step for each
request and each step can set values on the panel.
Note that in some cases it might be necessary to first set values for sorting order and panel version
and pressing enter before assuming that specific fields are available.
A typical automation could be to start a program, select an item and open an E-panel in change
mode. The user would do the following steps to achieve that:
Start the program (for example MMS001)
Select sorting order. Changing sorting order in the UI will automatically trigger the ENTER key.
Enter an item number in the first position field, change the panel sequence and press ENTER.
Select the first row in the list and choose the change list option.
The E-panel is displayed.
MForms Automation
54 | Infor M3 H5 Development Guide
These user actions must be mapped to steps in the automation sequence. An automation sequence
can contain 1-n steps.
Automation Steps
Each automation step must have a command, a value and 0-n fields. The available commands and
values are listed in the table below.
Command
Values
RUN
M3 BE program name
KEY
ENTER, F1-F24
LSTOPT
1-99, -1
AUTOSET
N/A
Automation Fields
Fields are used to enter data on a panel and for sending other special data such as focus. A field
has a name and a value.
You can locate the name of a field on an H5 panel in the field help window. To open the field help
window, set the focus on a control in the panel and press F1.
MForms Automation
Infor M3 H5 Development Guide | 55
Example
Field name = “WWITNO” Field value = “ITEM001”
Focus
o It can be set on a specific field by using the special field name FCS.
o Example
Field name = “FCS” Field value = “WWITNO”
Selected List Rows
o When using the list option command the default is to select the first row in the list. It
is possible to select other list rows using the special field name SELROWS. The
value is a comma-separated list of row names. The name for a row is on the format
R<1-based list index>.
o Example
Field name = “SELROWS” Field value = “R1,R2,R3”
Automation XML
An automation sequence is described in the form of a small XML document. The XML document can
be generated in runtime or created using XML templates.
Examples
Empty automation XML
<?xml version=”1.0” encoding=”utf-8”?>
<sequence>
<step command=”” value=”” />
<step command=”” value=””>
<field name=””></field>
</step>
<step command=”” value=””>
<field name=””></field>
<field name=””></field>
<field name=””></field>
</step>
</sequence>
Automation XML with values
<?xml version=”1.0” encoding=”utf-8”?>
<sequence>
<step command=”RUN” value=”MMS001” />
<step command=”KEY” value=”ENTER”>
MForms Automation
56 | Infor M3 H5 Development Guide
<field name=”WWQTTP”>1</field>
</step>
<step command=”KEY” value=”ENTER”>
<field name=”W1ITNO”>TESTITEM</field>
<field name=”WWPSEQ”>E</field>
</step>
<step command=”LSTOPT” value=”2” />
</sequence>
Starting Automations in M3 H5
Automations can be started in M3 H5 using a URI with the host _automation and the automation
XML in the data parameter. The automation XML value should be URL encoded.
URI Format
mforms://_automation/?data=<AUTOMATION XML>
Example
mforms://_automation?data=%3c%3fxml+version%3d%221.0%22+encoding%3d%22utf-
8%22%3f%3e%3csequence%3e%3cstep+command%3d%22RUN%22+value%3d%22MMS001%22+%2f%
3e%3c%2fsequence%3e
Helper Class
There is a helper class that can be used to generate automation XML from code. From the
generated automation XML, it creates a URI to launch an M3 program in H5. See the API chapter
and an example of it for reference.
Infor M3 H5 Development Guide | 57
Chapter 7 MI Service
7
The M3 framework has support for calling M3 MI programs using the REST endpoint on the BE
server. The MIService is a helper class that can be used to call transactions to M3 MI programs. It
builds the request URL from the set of request parameters, executes the request, and parses the MI
response values.
Use the MIService.Current instance to avoid creating objects every time. See the API chapter
for the available functions, and the Sample scripts chapter for an example.
MIRequest
The executeRequest() accepts an MIRequest object with the following properties:
Properties
Values
program
M3 BE program name
transaction
Transaction name
outputFields
String array
record
JSON
MI Service
58 | Infor M3 H5 Development Guide
Properties
Values
includeMetadata
true/false
typedOutput
true/false
maxReturnedRecords
number
timeout
number
Example
const myRequest = new MIRequest();
myRequest.program = "MNS150MI";
myRequest.transaction = "GetUserData";
myRequest.outputFields = ["CONO", "DIVI", "DTFM"];
myRequest.record = { USID: “USERFOO” };
myRequest.includeMetadata = true;
myRequest.typedOutput = true;
myRequest.maxReturnedRecords = 10;
myRequest.timeout = 60000;
MIService.Current.executeRequest(myRequest).then((response: IMIResponse) => {
//Success
}, (response: IMIResponse) => {
//Error
}
});
MIService builds this request into the following URL:
execute/MNS150MI/GetUserData;metadata=true;maxrecs=10;excludempty=false;cono=760;divi=AA
A;returncols=CONO,DIVI,DTFM?&USID=USERFOO?&_rid=YEBDH7IISB564BFJ
Infor M3 H5 Development Guide | 59
Chapter 8 Drillback
8
This chapter describes how to use standard Ming.le drillback links to launch M3 bookmarks in H5.
Invoking a drillback
Drill backs can be invoked by calling the Infor Ming.le JavaScript API to fire the drillback message. A
script is provided in the examples chapter.
infor.companyon.client.sendPrepareDrillbackMessage()
Returns: void
Example:
let myDrillback = “?LogicalId=lid://infor.m3.1&AccountingEntity=136_AAA…”;
infor.companyon.client.sendPrepareDrillbackMessage(myDrillback);
Drillback parameters
Name
Description
LogicalId
Used to determine which ERP to forward the drillback request to
Must start with lid://
AccountingEntity
If blank or missing, CONO and DIVI must be part of ID1-ID7
ID1-ID7
Used to provide bookmark key values
Drillback
60 | Infor M3 H5 Development Guide
Name
Description
ViewId
Used to provide metadata about an M3 bookmark
Key-value-pairs separated by semi colon (;) and the key and value
separated by equals (=)
Keys are case-insensitive
Key
Description
Program
TableName
Option
Panel
PanelSequence
Optional
KeyNames
The bookmark key names
Keys
Consists of bookmark key names and
value keys separated by comma (,)
Has priority over KeyNames
CombinedElementSeparator
Optional
The separator character for the
AccountingEntity parameter
The default value is underscore (_)
CombinedElementsAccountingEntity
Optional
A comma separated list of key names
for the AccountingEntity parameter
The default value is CONO,DIVI
Examples
Using KeyNames
o Company and division will be automatically retrieved from the AccountingEntity
parameter
o Additional bookmark keys are retrieved from ID1-ID7
?LogicalId=lid://infor.m3.1&AccountingEntity=136_AAA&ViewId=Program=CRS610
;TableName=OCUSMA;Option=5;Panel=E;KeyNames=OKCONO,OKCUNO&ID1=MANGO
Using Keys
o The value key can be CONO, DIVI or ID1-ID7
o CONO is retrieved from the AccountingEntity
Drillback
Infor M3 H5 Development Guide | 61
?LogicalId=lid://infor.m3.1&AccountingEntity=136_AAA&ViewId=Progr
am=CRS610;TableName=OCUSMA;Option=5;Panel=E;Keys=OKCONO,CONO,OKCU
NO,ID1&ID1=MANGO
o CONO is specified using the ID1-parameter
?LogicalId=lid://infor.m3.1&AccountingEntity=136_AAA&ViewId=Progr
am=CRS610;TableName=OCUSMA;Option=5;Panel=E;Keys=OKCONO,ID1,OKCUN
O,ID2&ID1=136&ID2=MANGO
Using CombinedElementsAccountingEntity
?LogicalId=lid://infor.m3.1&AccountingEntity=136_AAA&ViewId=CombinedElemen
tSeparator=_;CombinedElementsAccountingEntity=CONO,DIVI;Program=CRS610;Tab
leName=OCUSMA;Option=5;Panel=E;Keys=OKCONO,ID1,OKCUNO,ID2&ID1=136&ID2=MANG
O
Infor M3 H5 Development Guide | 63
Chapter 9 Best practices
9
This chapter provides suggestions to improve the quality and maintainability of your scripts.
Use H5 functions and properties that are
documented
Although there are many accessible functions, it is recommended to use those that are listed in the
public API. This ensures that the scripts will not break when H5 is updated.
Use recommended API functions
Here are some of the more commonly-used functionalities:
1 InstanceController.ParentWindow
Use this property to get the current panel, instead of using CSS class selectors, i.e.,
$(".lawsonHost:visible") and $(".visible-tab-host").
2 ContentElement.AddElement()
Consider using this function to add elements and easily align them in the panel row, as opposed
to ContentElement.Add() which requires the exact position in pixels and ControlFactory
which is not part of the public API.
3 MIService
Use this utility for M3 API requests, instead of the now deprecated
ScriptUtil.ApiRequest().
Best practices
64 | Infor M3 H5 Development Guide
Use proper logging utility
The problem with logging using console.log()is that you have no way to turn it off. Use the log
object from the script arguments and use the log levels provided.
Use TypeScript
TypeScript allows writing safer code. Although optional, it is best to include the data type,
avoiding any as much as possible, when declaring a variable to take advantage of its type-checking.
It also allows usage of some ES6 features by transpiling them to ES5-compliant code. It is
recommended to utilize these features such as:
1 const and let
These allow definition of block-scoped variables, as opposed to the function-scoped var
declarations. Use these instead of var whenever possible. Use const to make a variable
immutable.
2 for…of and for…in
These constructs eliminate potential index bugs in the for loop. Note that for…of iterates over
the elements of an array, while for…in iterates over the keys of an object.
3 Arrow functions (=>)
The fat arrow captures this from the surrounding context as opposed to an ordinary function
that tends to lose the meaning of this when it is passed around. It is recommended to use this
in callback functions.
Be wary of using ES6/ES2016 features
As of this writing, some browsers, like Internet Explorer, do not fully support ES6/ES2016 features.
Verify that the functions and properties you use are supported in the browsers that you target your
scripts to run in. Note that the TypeScript compiler can convert some, not all, code to be ES5-
compliant.
Minify scripts
Consider minifying large scripts to improve load time. More information on minification in the
Overview chapter.
Infor M3 H5 Development Guide | 65
Chapter 10 Script examples
10
This chapter contains examples of scripts written in TypeScript. The scripts are complete and can be
copied from this document to a new TypeScript file. The transpiled JavaScript file can then be
deployed to M3 H5.
H5SampleHelloWorld.ts
This script shows a message dialog information about the connected element and script arguments.
class H5SampleHelloWorld {
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
let message: string;
const element = args.elem;
if (element) {
message = "Connected element: " + element.Name;
} else {
message = "No element connected.";
}
const argumentString = args.args;
if (argumentString != null) {
message = message + " Arguments: " + argumentString;
} else {
message = message + " No arguments.";
}
// Show an information message dialog.
ConfirmDialog.Show({
header: "H5SampleHelloWorld",
message: message,
dialogType: "Information"
Script examples
66 | Infor M3 H5 Development Guide
});
}
}
H5SampleUserDetails.ts
This script adds a custom ButtonElement on the panel. When the button is clicked, a message
dialog shows M3-related data about the logged on user.
class H5SampleUserDetails {
private controller: IInstanceController;
private log: IScriptLog;
private args: string;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
this.args = scriptArgs.args;
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleUserDetails(args).run();
}
private run(): void {
this.addButton();
}
private addButton(): void {
const buttonElement = new ButtonElement();
buttonElement.Name = "showUserDetails";
buttonElement.Value = "Show User Details";
buttonElement.Position = new PositionElement();
buttonElement.Position.Top = 3;
buttonElement.Position.Left = 1;
buttonElement.Position.Width = 5;
const contentElement = this.controller.GetContentElement();
const button = contentElement.AddElement(buttonElement);
button.click(() => {
this.showDetails();
Script examples
Infor M3 H5 Development Guide | 67
});
}
private showDetails(): void {
const userContext = ScriptUtil.GetUserContext();
const header = "USER DETAILS";
const message = [];
for (let key in userContext) {
message.push(key + ": " + userContext[key]);
}
const opts = {
dialogType: "Information",
header: header,
message: message.join("<br/>"),
id: "msgDetails",
withCancelButton: true,
isCancelDefault: false
}
ConfirmDialog.ShowMessageDialog(opts);
}
}
H5SampleShowXml.ts
This example displays the raw XML content of an MForm from the View Definitions file. The script
retrieves the XML file, and converts text symbols to HTML codes to properly display the text symbols
in a Message Dialog.
class H5SampleShowXml{
private log: IScriptLog;
private args: string;
private static charMap = {
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;',
"'": '&#39;',
'!': '&#33;',
'[': '&#91;',
']': '&#93;'
};
Script examples
68 | Infor M3 H5 Development Guide
constructor(args: IScriptArgs) {
this.controller = args.controller;
this.log = args.log;
this.args = args.args;
}
public static Init(args: IScriptArgs): void {
new H5SampleShowXml(args).run();
}
private run(): void {
const xml = this.controller.Response.RawContent;
const strXml = (new XMLSerializer()).serializeToString(xml);
const finalStr = this.escapeChar(strXml);
ConfirmDialog.ShowMessageDialog({
dialogType: "Information",
header: "XML Response",
message: finalStr
});
}
private escapeChar(xml: string): string {
return xml.replace(/[<>&"'!]/g, (ch) => {
return H5SampleShowXml.charMap[ch];
});
}
}
H5SampleOptionButton.ts
Adds one or more option buttons that executes a list option when clicked.
class H5SampleOptionButton {
private controller: IInstanceController;
private log: IScriptLog;
private args: string;
private buttons: IButtonInfo[];
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
this.args = scriptArgs.args;
}
Script examples
Infor M3 H5 Development Guide | 69
private parseArgs(args: string): boolean {
try {
// The argument string should be either an array of IButtonInfo
or a single IButtonInfo object on JSON format.
const json: any = JSON.parse(args);
let buttons: IButtonInfo[];
if (json.length > 0) {
// Assume it's an array of buttons
buttons = json;
} else {
// Assume it's a single buttons object
buttons = [json];
}
// Validate that all mandatory properties are set.
for (let button of buttons) {
if (!button.text || !button.option) {
this.log.Error("Invalid argument string " + args);
return false;
}
}
this.buttons = buttons;
} catch (ex) {
this.log.Error("Failed to parse argument string " + args, ex);
return false;
}
return true;
}
private addButton(buttonInfo: IButtonInfo): void {
const buttonElement = new ButtonElement();
buttonElement.Value = buttonInfo.text;
const button = ControlFactory.CreateButton(buttonElement);
button.click({}, () => {
this.controller.ListOption(buttonInfo.option);
});
button.Position = {
Width: buttonInfo.width || "100",
Top: buttonInfo.top || "0",
Left: buttonInfo.left || "0"
};
const contentElement = this.controller.GetContentElement();
contentElement.Add(button);
}
Script examples
70 | Infor M3 H5 Development Guide
public run(): void {
// Parse the script argument string and return if the arguments are
invalid.
if (!this.parseArgs(this.args)) {
return;
}
this.log.Info("Running...");
// Add the option buttons to the panel.
for (let button of this.buttons) {
this.addButton(button);
}
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleOptionButton(args).run();
}
}
H5SamplePreviewListHeader.ts
This example is a program-specific script loaded from the MNEAI element of an H5 panel. This script
searches for two specific elements that contain the headers and the row content to be displayed in a
table. When this script is loaded in CRS020/F, a table with one row of data is displayed.
class H5SamplePreviewListHeader {
private controller: IInstanceController;
private log: IScriptLog;
private args: string;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
this.args = scriptArgs.args;
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
Script examples
Infor M3 H5 Development Guide | 71
new H5SamplePreviewListHeader(args).run();
}
private run(): void {
//Check panel
if (this.controller.GetPanelName() !== "CRA020F0") {
this.log.Error("Script should run in CRS020/F.");
return;
}
this.buildGrid();
}
private buildGrid(): void {
let options, grid;
const content = this.controller.GetContentElement();
const header = this.getHeader();
const columns = this.getColumns(header);
const data = this.getData(columns);
const $list: IList = $("<div>", {
"class": "inforDataGrid",
"id": "crs020FGrid",
"width": "auto",
"height": "500px"
});
$list.Position = new PositionElement();
$list.Position.Width = "97%";
$list.Position.Top = "250";
$list.Position.Left = "10";
content.Add($list);
options = Configuration.Current.ListConfig('id', columns, data);
options["forceFitColumns"] = true;
options["autoHeight"] = true;
grid = $("#crs020FGrid").inforDataGrid(options);
grid.render();
}
private getHeader(): string[] {
const wwsfhl = this.controller.GetElement("WWSFHL");
//Split on capital letters
return wwsfhl[0].textContent.split(/(?=[A-Z])/);
}
private getColumns(headers: string[]): any[] {
Script examples
72 | Infor M3 H5 Development Guide
const columns = [];
for (let header of headers) {
let column = {
id: "C" + (columns.length + 1),
name: header,
field: header
};
columns.push(column);
}
return columns;
}
private getData(columns: any[]): any[] {
const rows = [];
const wwsfll = this.controller.GetElement("WWSFLL");
const data = wwsfll[0].value.split(" ");
const row = { id: "R1" };
for (let i = 0; i < columns.length; i++) {
row[columns[i]["field"]] = data[i];
}
rows.push(row);
return rows;
}
}
H5SampleShowOnMap.ts
This is a program-specific script for OIS002/F. It adds a custom button element in the panel that
opens a location in Google Maps depending on the latitude, longitude, and zoom values specified in
the text fields.
class H5SampleShowOnMap {
private controller: IInstanceController;
private log: IScriptLog;
private $host: JQuery;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
}
/**
* Script initialization function.
Script examples
Infor M3 H5 Development Guide | 73
*/
public static Init(args: IScriptArgs): void {
new H5SampleShowOnMap(args).run();
}
private run(): void {
this.$host = this.controller.ParentWindow;
this.addButton();
}
private addButton(): void {
const buttonElement = new ButtonElement();
buttonElement.Name = "showMap";
buttonElement.Value = "Show Map";
buttonElement.Position = new PositionElement();
buttonElement.Position.Top = 0;
const contentElement = this.controller.GetContentElement();
const button = contentElement.CreateElement(buttonElement);
const geoX = ScriptUtil.FindChild(this.$host, "WFGEOX");
button.attr("style", "margin-left: 5px");
geoX.after(button);
button.click(() => {
this.showMap();
});
}
private showMap(): void {
const lat = ScriptUtil.GetFieldValue("WFGEOX", this.controller);
const lng = ScriptUtil.GetFieldValue("WFGEOY", this.controller);
const zoom = ScriptUtil.GetFieldValue("WFGEOZ", this.controller);
if (!(lat && lng)) {
this.log.Info("Coordinates required.");
return;
}
let x = lat.replace(",", ".");
let y = lng.replace(",", ".");
let z = zoom ? zoom : 15;
if (x.indexOf("-") > -1) {
x = x.replace("-", "");
x = "-" + x;
}
Script examples
74 | Infor M3 H5 Development Guide
if (y.indexOf("-") > -1) {
y = y.replace("-", "");
y = "-" + y;
}
const url = "https://maps.google.com/maps?z=" + z + "&t=m&q=loc:" + x
+ "+" + y + "&output=embed";
ScriptUtil.Launch(url);
}
}
H5SampleMFormsAutomation.ts
This example retrieves the user ID from the user context, creates an automation that starts MNS150,
and opens the user in change mode.
class H5SampleMFormsAutomation {
private controller: IInstanceController;
private log: IScriptLog;
constructor(args: IScriptArgs) {
this.controller = args.controller;
this.log = args.log;
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleMFormsAutomation(args).run();
}
private run(): void {
if (this.controller.GetProgramName() === "MNS150") {
this.log.Error("Adding this script will cause an infinite loop.
Try adding it to a different program.");
return;
}
this.addButton();
}
private addButton(): void {
Script examples
Infor M3 H5 Development Guide | 75
const run = new ButtonElement();
run.Name = "run";
run.Value = "Run Automation";
run.Position = new PositionElement();
run.Position.Top = 3;
run.Position.Left = 1;
run.Position.Width = 5;
const contentElement = this.controller.GetContentElement();
const $run = contentElement.AddElement(run);
$run.click({}, () => {
const auto = new MFormsAutomation();
auto.addStep(ActionType.Run, "MNS150");
auto.addStep(ActionType.Key, "ENTER");
auto.addField("W1USID", ScriptUtil.GetUserContext("USID"));
auto.addStep(ActionType.ListOption, "2");
const uri = auto.toEncodedUri();
ScriptUtil.Launch(uri);
});
}
}
H5SampleRegexValidator.ts
This script validates the content of the configured fields on a panel and shows a validation message
for the first validation that fails. Validation runs on Enter or Next, and on failure, the request will be
cancelled and the user will not be able to continue until the validation errors have been addressed.
/**
* Configuration example:
* Validate that the WRYREF field is not blank on the CRS610/E panel.
* Note that the backslash character has been escaped with an additional
backslash character.
*
* { "names": ["WRYREF"], "regex": "^$|\\s+", "message": "Your ref 1 may not
be blank" }
*/
class H5SampleRegexValidator {
private scriptName = "H5SampleRegexValidator";
private controller: IInstanceController;
private log: IScriptLog;
private args: string;
private detachRequesting: Function;
Script examples
76 | Infor M3 H5 Development Guide
private detachRequested: Function;
private validations: IValidationInfo[];
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
this.args = scriptArgs.args;
}
private parseArgs(args: string): boolean {
try {
// The argument string should be either an array of
IValidationInfo or a single IValidationInfo object on JSON format.
const json: any = JSON.parse(args);
let validations: IValidationInfo[];
if (json.length > 0) {
// Assume it's an array of validations
validations = json;
} else {
// Assume it's a single validation object
validations = [json];
}
// Validate that all mandatory properties are set.
for (let validation of validations) {
if (!validation.regex || !validation.message ||
!validation.names) {
this.log.Error("Invalid argument string " + args);
return false;
}
}
this.validations = validations;
} catch (ex) {
this.log.Error("Failed to parse argument string " + args, ex);
return false;
}
return true;
}
private validateFields(): boolean {
try {
for (var validation of this.validations) {
const regExp = new RegExp(validation.regex);
for (var name of validation.names) {
const value = this.controller.GetValue(name);
if (value === null || value === undefined) {
Script examples
Infor M3 H5 Development Guide | 77
// Skip fields that does not exist on the current
panel.
this.log.Debug("The field " + name + " does not
exist on the panel.");
continue;
}
if (regExp.test(value)) {
this.controller.ShowMessage(validation.message);
return false;
}
}
}
return true;
} catch (ex) {
this.log.Error("Failed to validate fields", ex);
// Return true if the script crashes to avoid getting stuck on
a panel.
return true;
}
}
private logEvent(eventName: string, args: RequestEventArgs): void {
this.log.Info("Event: " + eventName + " Command type: " +
args.commandType + " Command value: " + args.commandValue);
}
private detachEvents(): void {
this.detachRequesting();
this.detachRequested();
}
private attachEvents(controller: IInstanceController): void {
this.detachRequesting = controller.Requesting.On((e) => {
this.onRequesting(e);
});
this.detachRequested = controller.Requested.On((e) => {
this.onRequested(e);
});
}
private onRequesting(args: CancelRequestEventArgs): void {
// Only validate for the enter key (next button).
if (args.commandType === "KEY" && args.commandValue === "ENTER") {
if (!this.validateFields()) {
args.cancel = true;
}
}
Script examples
78 | Infor M3 H5 Development Guide
}
private onRequested(args: RequestEventArgs): void {
this.detachEvents();
}
public run(): void {
if (!this.parseArgs(this.args)) {
return;
}
this.log.Info("Running...");
// Attach events.
this.attachEvents(this.controller);
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleRegexValidator(args).run();
}
}
H5SampleRequestTracer.ts
This script logs the command type and command value for the Requesting, Requested and
RequestCompleted events on a panel. It uses the InstanceCache to ensure that the script is
attached only once for a program instance.
class H5SampleRequestTracer {
private scriptName = "H5SampleRequestTracer";
private controller: IInstanceController;
private log: IScriptLog;
constructor(args: IScriptArgs) {
this.controller = args.controller;
this.log = args.log;
}
private logEvent(eventName: string, args: RequestEventArgs): void {
this.log.Info("Event: " + eventName + " Command type: " +
args.commandType + " Command value: " + args.commandValue);
Script examples
Infor M3 H5 Development Guide | 79
}
private attachEvents(controller: IInstanceController): void {
controller.Requesting.On((e) => {
this.onRequesting(e);
});
controller.Requested.On((e) => {
this.onRequested(e);
});
controller.RequestCompleted.On((e) => {
this.onRequestCompleted(e);
});
}
private onRequesting(args: CancelRequestEventArgs): void {
this.logEvent("Requesting", args);
}
private onRequested(args: RequestEventArgs): void {
this.logEvent("Requested", args);
}
private onRequestCompleted(args: RequestEventArgs): void {
this.logEvent("RequestCompleted", args);
}
public run(): void {
const controller = this.controller;
const key = this.scriptName;
const cache = InstanceCache;
// Check the instace cache to see if this script has already
attached to this program instance.
if (cache.ContainsKey(controller, key)) {
// The script is already attached to this instance.
return;
}
this.log.Info("Running...");
// Add a key to the instance cache to prevent other instances of
this script on the same program instance.
cache.Add(controller, key, true);
// Attach events.
this.attachEvents(controller);
}
Script examples
80 | Infor M3 H5 Development Guide
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleRequestTracer(args).run();
}
}
H5SampleCancelRequest.ts
This example shows how to cancel a server request and is built for the E-panel in POS015. The
script subscribes to the Requesting event and when that event is raised it checks the name of the
project leader. If the name is invalid, it cancels the request and shows an error message.
class H5SampleCancelRequest {
private controller: IInstanceController;
private log: IScriptLog;
private unsubscribeRequesting;
private unsubscribeRequested;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleCancelRequest(args).run();
}
private run(): void {
this.unsubscribeRequesting = this.controller.Requesting.On((e) => {
this.onRequesting(e);
});
this.unsubscribeRequested = this.controller.Requested.On((e) => {
this.onRequested(e);
});
}
private onRequesting(args: CancelRequestEventArgs): void {
this.log.Info("onRequesting");
if (args.commandType === "KEY" && args.commandValue === "F12") {
return; // The user should be allowed to go back
Script examples
Infor M3 H5 Development Guide | 81
}
const $host = this.controller.ParentWindow;
const fullName = ScriptUtil.GetFieldValue("WWTX40");
if (fullName && fullName.indexOf("Infor") >= 0) {
this.controller.ShowMessage(fullName + " is not a valid project
leader.");
args.cancel = true;
}
}
private onRequested(args: RequestEventArgs): void {
this.log.Info("onRequested");
this.unsubscribeRequested();
this.unsubscribeRequesting();
}
}
H5SampleOpenFieldHelp.ts
This example displays through a dialog box the field help of the corresponding element argument
attached to it. The script adds a click event to the attached element which opens the field help of the
element based on the argument supplied. When there is no argument, the script will use the element
name where it is attached.
class H5SampleOpenFieldHelp {
public static Init(args: IScriptArgs): void {
const element = args.elem;
const controller = args.controller;
const fieldHelp = args.args;
const response = controller.Response;
const $host = controller.ParentWindow;
if (element) {
let $elem = ScriptUtil.FindChild($host, element.Name);
if ($elem.length > 0) {
ScriptUtil.AddEventHandler($elem, "click", (event) => {
const helpElement = $("#" + (fieldHelp || element.Name));
controller.RenderEngine.OpenFieldHelp(response, $host,
controller, helpElement);
});
}
Script examples
82 | Infor M3 H5 Development Guide
}
else {
ConfirmDialog.ShowMessageDialog({
dialogType: "Error",
header: "H5 Sample Field Help Button",
message: "No element connected"
});
}
}
}
H5SampleCustomColumns.ts
This script adds a column to the grid and populates the new column with dummy data.
class H5SampleCustomColumns {
private controller: IInstanceController;
private unsubscribeReqCompleted;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleCustomColumns(args).run();
}
private run(): void {
const list = this.controller.GetGrid();
const customColumnNum = list.getColumns().length + 1;
this.appendColumn(list, customColumnNum);
this.populateData(list, customColumnNum);
this.attachEvents(this.controller, list, customColumnNum);
}
private appendColumn(list: IActiveGrid, columnNum: number) {
const columnId = "C" + columnNum;
let columns = list.getColumns();
let newColumn = {
id: columnId,
Script examples
Infor M3 H5 Development Guide | 83
field: columnId,
name: "Custom Column " + columnNum,
width: 100
}
if (columns.length < columnNum) {
columns.push(newColumn);
}
list.setColumns(columns);
}
private populateData(list: IActiveGrid, columnNum: number) {
const columnId = "C" + columnNum;
for (let i = 0; i < list.getData().getLength(); i++) {
let newData = {};
newData[columnId] = "Dummy Data" + i;
newData["id_" + columnId] = "R" + (i + 1) + columnId;
$.extend(list.getData().getItem(i), newData);
}
let columns = list.getColumns();
list.setColumns(columns);
}
private attachEvents(controller: IInstanceController, list: IActiveGrid,
columnNum: number) {
this.unsubscribeReqCompleted = controller.RequestCompleted.On((e) =>
{
//Populate additional data on scroll
if (e.commandType === "PAGE" && e.commandValue === "DOWN") {
this.populateData(list, columnNum);
} else {
this.detachEvents();
}
});
}
private detachEvents() {
this.unsubscribeReqCompleted();
}
}
H5SampleMIService.ts
This script executes M3 API calls to retrieve user data using the MIService utility.
Caution:
Script examples
84 | Infor M3 H5 Development Guide
Some minifiers report an error on the occurrence of Promise.catch as catch is a reserved word. To
work around this, you can pass the catch function as the second parameter to the then function
instead.
class H5SampleMIService {
private controller: IInstanceController;
private log: IScriptLog;
private args: string;
private usid: string;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
this.args = scriptArgs.args;
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleMIService(args).run();
}
private run(): void {
this.usid = ScriptUtil.GetUserContext("USID");
this.addButton();
}
private addButton(): void {
const run = new ButtonElement();
run.Name = "run";
run.Value = "Execute MI calls";
run.Position = new PositionElement();
run.Position.Top = 3;
run.Position.Left = 1;
run.Position.Width = 5;
const contentElement = this.controller.GetContentElement();
const $run = contentElement.AddElement(run);
$run.click({}, () => {
this.executeByRequest();
this.executeByTransaction();
this.executeWithOptionalArgs();
this.executeMultiple();
});
}
Script examples
Infor M3 H5 Development Guide | 85
private executeByRequest(): void {
const myRequest = new MIRequest();
myRequest.program = "MNS150MI";
myRequest.transaction = "GetUserData";
//Fields that should be returned by the transaction
myRequest.outputFields = ["CONO", "DIVI", "DTFM"];
//Input to the transaction
myRequest.record = { USID: this.usid };
MIService.Current.executeRequest(myRequest).then(
(response: IMIResponse) => {
//Read results here
for (let item of response.items) {
this.log.Info(`1: Company: ${item.CONO}`);
}
}).catch((response: IMIResponse) => {
//Handle errors here
this.log.Error(response.errorMessage);
});
}
private executeByTransaction(): void {
const program = "MNS150MI";
const transaction = "GetUserData";
const record = { USID: this.usid };
const outputFields = ["USID", "CONO", "DIVI", "DTFM"];
MIService.Current.execute(program, transaction, record,
outputFields).then(
(response: IMIResponse) => {
//Read results here
for (let item of response.items) {
this.log.Info(`2: Division: ${item.DIVI}`);
}
}).catch((response: IMIResponse) => {
//Handle errors here
this.log.Error(response.errorMessage);
});
}
private executeWithOptionalArgs(): void {
const myRequest = new MIRequest();
myRequest.program = "MNS150MI";
myRequest.transaction = "GetUserData";
myRequest.includeMetadata = true;
//Convert data to number and date as defined in the metadata; default
is false
myRequest.typedOutput = true;
Script examples
86 | Infor M3 H5 Development Guide
//Default is 33
myRequest.maxReturnedRecords = 10;
//Default is 55000
myRequest.timeout = 60000;
MIService.Current.executeRequest(myRequest).then(
(response: IMIResponse) => {
//Since CONO is numeric based on the metadata, this will read
"999 is a number"
//If request.typedOutput = false, everything will be a string
and this will read "999 is a string"
this.log.Info(`3: ${response.item.CONO} is a ${typeof
response.item.CONO}`);
//Read metadata
const metadata = response.metadata;
for (let field in metadata) {
let info: IMIMetadataInfo = metadata[field];
this.log.Info(`3: ${field}: ${info.description}
(${MIDataType[info.type]})`);
}
}, (response: IMIResponse) => {
//Alternatively, pass a second function to then instead of
using catch
//Handle errors here
this.log.Error(response.errorMessage);
});
}
private executeMultiple(): void {
const myRequest1 = new MIRequest();
myRequest1.program = "MNS150MI";
myRequest1.transaction = "GetUserData";
//Fields that should be returned by the transaction
myRequest1.outputFields = ["CONO", "DIVI", "DTFM"];
//Input to the transaction
myRequest1.record = { USID: this.usid };
const myRequest2 = new MIRequest();
myRequest2.program = "MNS150MI";
myRequest2.transaction = "LstUserData";
//Fields that should be returned by the transaction
myRequest2.outputFields = ["USID", "TX40", "USTP"];
myRequest2.maxReturnedRecords = 5;
const myPromise1 = MIService.Current.executeRequest(myRequest1);
const myPromise2 = MIService.Current.executeRequest(myRequest2);
Promise.all([myPromise1, myPromise2]).then(
Script examples
Infor M3 H5 Development Guide | 87
response => {
//Read results here
const response1 = response[0];
const response2 = response[1];
for (let item of response1["items"]) {
this.log.Info(`4: DTFM: ${item.DTFM}`);
}
for (let item of response2["items"]) {
this.log.Info(`4: USID: ${item.USID}`);
}
}).catch((response: IMIResponse) => {
//Handle errors here
this.log.Error(response.errorMessage);
});
}
}
H5SampleImageFromList.ts
This script shows an image when a list row is selected, it gets the text in the first column to build a
URL to an image. The image is loaded and displayed next to the list. The base URL to the images
are retrieved from the script arguments. For the script to work properly, there must be images in the
folder of the URL whose names (not including the file extension) match the values of the first column
in the list.
class H5SampleImageFromList {
private imgLink = "";
private controller: IInstanceController;
private content: IContentElement;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.imgLink = scriptArgs.args;
this.content = this.controller.GetContentElement();
}
public static Init(args: IScriptArgs): void {
new H5SampleImageFromList(args).run();
}
private run(): void {
if (!this.imgLink) {
ConfirmDialog.ShowMessageDialog({
dialogType: "Error",
Script examples
88 | Infor M3 H5 Development Guide
header: "No Argument",
message: "Please provide url of the location of the images.
Example: http://server/images/"
});
return;
}
//Add eventhandlers
const list = this.controller.GetGrid();
const handler = (e, args) => { this.onSelectionChanged(e, args); };
list.onSelectedRowsChanged.subscribe(handler);
}
private addImage(src: string): void {
const contentBody = this.content.GetContentBody();
const height = contentBody.height();
const width = contentBody.width()/2 - 20;
const style = `z-index:2000;
display: block;
max-width:${width}px;
overflow: hidden;
position:absolute;
left:50%;
max-height:${height}px;
top:0px;`;
const $image = $(`<div id='newImg' style='${style}'><img
style='width:100%;' src='${src}'></img></div>`);
contentBody.append($image);
}
private updateImage(src: string): void {
const newImg = this.content.GetContentBody().find("#newImg");
if (newImg) {
newImg.remove();
}
this.addImage(src);
}
private onSelectionChanged(e: any, args: any): void {
const grid = args.grid;
const selected = grid.getSelectedRows();
if (selected.length < 1) {
// No row was selected
return;
}
Script examples
Infor M3 H5 Development Guide | 89
// Get the index of the first selected row
const rowIndex = selected[0];
// Get item number of selected row
const imageName = ListControl.ListView.GetValueByColumnIndex(0);
//Show Image
this.updateImage(this.imgLink + imageName + ".jpg");
}
}
H5SampleDrillback.ts
This script takes a customer ID from the script arguments and launches CRS610/E for this customer
using a standard Ming.le drillback URL. The drillback is invoked using the Infor Ming.le CE
JavaScript API.
class H5SampleDrillback {
private controller: IInstanceController;
private log: IScriptLog;
private content: IContentElement;
private customer: string;
constructor(scriptArgs: IScriptArgs) {
this.controller = scriptArgs.controller;
this.log = scriptArgs.log;
this.customer = scriptArgs.args;
}
/**
* Script initialization function.
*/
public static Init(args: IScriptArgs): void {
new H5SampleDrillback(args).run();
}
private run(): void {
if (!this.customer) {
this.log.Error("Enter a customer ID in the script arguments.");
return;
}
this.content = this.controller.GetContentElement();
Script examples
90 | Infor M3 H5 Development Guide
this.addButton();
}
private invokeDrillback() {
const userContext = ScriptUtil.GetUserContext();
const acctEntity =
`${userContext.CurrentCompany}_${userContext.CurrentDivision}`;
const viewId =
`Program=CRS610;TableName=OCUSMA;Option=5;Panel=E;KeyNames=OKCONO,OKCUNO`;
const drillback =
`?LogicalId=lid://infor.m3.1&AccountingEntity=${acctEntity}&ViewId=${encodeUR
IComponent(viewId)}&ID1=${this.customer}`;
//Fire the drillback message using the Infor Ming.le CE JavaScript
API
infor.companyon.client.sendPrepareDrillbackMessage(drillback);
}
private addButton(): void {
const run = new ButtonElement();
run.Name = "run";
run.Value = "Invoke Drillback";
run.Position = new PositionElement();
run.Position.Top = 3;
run.Position.Left = 1;
run.Position.Width = 5;
const $run = this.content.AddElement(run);
$run.click(() => {
this.invokeDrillback();
});
}
}
Infor M3 H5 Development Guide | 91
Chapter 11 Appendix
11
Node.js
Node.js should be installed to be able to use the web server included in the SDK samples in
developing scripts. You can skip this section if you have a working Node.js installation or if you do
not want to use the web server.
Install Node.js
Download and install Node.js from http://nodejs.org/
When the installation is complete you can follow the steps in the next two sections to verify that
installations works. Note that the instructions are for Microsoft Windows operating systems only.
Refer to the Node.js documentation for other operating systems.
Verify the Node package manager
Follow these steps to verify that the Node package manager works.
1 Verify that the following folder exists and create it manually if not.
C:\Users\<userid>\AppData\Roaming\npm
You need to show Hidden items in Windows Explorer to be able to see the AppData folder.
2 Open a Windows Command Prompt window.
3 Run the following command.
npm -version
4 Verify that a version number is printed, such as 2.15.8.
If the command fails, verify that the npm directory has been created. See previous step, and
create it if necessary.
When the directory has been created, retry the “npm version” command.
Appendix
92 | Infor M3 H5 Development Guide
On some operating systems, the command might complete even if the npm folder is missing.
In these cases, the installation of the node packages will fail. This can be solved by manually
creating the npm folder.
On some operating systems, you might have to restart the computer after adding the npm
folder.
Verify the Node executable
Follow these steps to verify that Node executable works.
1 Open a Windows Command Prompt window.
2 Run the following command.
node -v
3 Verify that a version number is printed, such as v4.4.7.
If the command fails, it could be that the node directory is not on the Windows path.
Add the following directory to the Windows System Path.
o C:\Program Files\nodejs
Close the command Window, start a new one and test node v again.
o The command should succeed this time.
To apply the new Windows path, the computer might have to be restarted.
TypeScript
Follow these steps to install the TypeScript compiler. If you choose to use Visual Studio, you can
skip this part as the IDE already includes a compiler plugin.
1 Open a Windows Command Prompt window.
2 Run the following command:
npm install -g ty[email protected]
3 Verify installation. A version number should be printed when you run the following command:
npm typescript -version