FSM Mobile Scripting and Customization
Use standard FSM configuration for supported form behavior, resource permissions, and presentation. Imported JavaScript, JSON, and CSS are one option for custom functionality or reusable files. Configure imports under the literal root key "routes/mobile" in the field service configuration record.
The customer or partner owns the custom code, its support, and its compatibility after FSM releases, including hot fixes. Account for its effects on security, data integrity, performance, accessibility, and the user experience. Custom code manages its own data, state, persistence, localization, and authentication. It does not inherit an FSM extension API.
For customization tasks, see the following topics:
Choosing a Customization Method
The following table compares customization methods.
|
Requirement |
Method |
|---|---|
|
Display a section heading. |
Use a |
|
Control resource create, edit, or delete actions. |
Use resource permission properties. Hiding controls with CSS does not control permissions. |
|
Display formatted instructions. |
Use semantic HTML in an event body or a read-only |
|
Calculate an element property from form data. |
Use an FSM Mobile expression and, where useful, an imported pure function. |
|
Supply reusable static data or custom styles. |
Import JSON or CSS. |
|
Add independent interactivity to custom content. |
Import page JavaScript using standard browser APIs. |
|
Access a custom Suitelet from a tab. |
Use the tab's article mapping without an iframe. Its creator retains the responsibilities described for custom code. |
For element and resource properties, see FSM Mobile Element Reference and FSM Mobile Resource Properties Reference. For expression syntax, binding, evaluation, accepted result types, and pure synchronous function rules, see FSM Expressions and Template Tags.
Properties and Defaults
The following table describes import properties and their defaults.
|
Property or Entry |
Accepted Value |
Standard Default |
Effect |
|---|---|---|---|
|
|
Object of import IDs and File Cabinet paths. |
|
Registers files to load with the FSM Mobile page. |
|
An entry in |
Unique ID as the property name and an absolute File Cabinet path ending in |
No entries. |
Identifies the file and its loading mechanism. |
The following table describes how each imported file type loads.
|
File Type |
Loading Behavior |
|---|---|
|
JavaScript |
Loads as a deferred page script. It defines its own exposed functions and globals. The import ID does not create a function or namespace. |
|
JSON |
Parses into a global variable named after the import ID. |
|
CSS |
Loads as an external stylesheet. Selectors are defined inside the file. It supplies no expression value. |
Default JSON
The standard configuration registers no custom imports:
{
"routes/mobile": {
"import": {}
}
}
Changing Registered Imports
To change registered imports:
-
Store the files in a suitable account-managed File Cabinet location. Keep customer files outside product-managed SuiteBundle folders. Validate JSON before uploading it.
-
Add an
importentry for each file using its actual absolute File Cabinet path. -
Save and activate the configuration. For instructions, see FSM Configuration.
-
Reload FSM Mobile while online to obtain the configuration and files.
The folder and file names in the following example are illustrative. Any suitable account-managed location can be used. The configured path must match the actual file:
{
"routes/mobile": {
"import": {
"customCalculations_v1": "/SuiteScripts/FSMCustom/custom-calculations.js",
"customRates_v1": "/SuiteScripts/FSMCustom/custom-rates.json",
"customStyles_v1": "/SuiteScripts/FSMCustom/custom-styles.css"
}
}
}
Imports are added to the page in registration order. Put a shared script before scripts that use it. Deferred scripts execute after document parsing, in their document order. Script execution order does not mean every FSM Mobile resource has rendered. For more information, refer to the script element's defer behavior.
Import and Function Naming Conventions
The following table distinguishes file paths, import IDs, and function names.
|
Name |
Example |
Meaning |
|---|---|---|
|
File Cabinet path |
|
Locates the file. It need not match an import ID or function name. |
|
JavaScript import ID |
|
Identifies the script registration. |
|
JavaScript function name |
|
Identifies the callable function exposed by that script. |
|
JSON import ID |
|
Identifies both the registration and the global data variable. |
|
CSS import ID |
|
Identifies the stylesheet registration. It does not rename its selectors. |
Use distinct IDs, consistently cased. A simple convention is a letter or underscore followed by letters, digits, or underscores. JSON import IDs must be valid JavaScript variable names and must not be reserved words.
Prefix custom globals and HTML IDs, names, classes, and data attributes with custom. Avoid collisions with browser globals, other imports, form elements, and shared URIs. The global namespace is shared and is not guaranteed to be empty. An import ID does not isolate a script's globals.
Imported Functions and JSON Data
The complete custom-calculations.js file can contain:
function customLineTotal(quantity, unitPrice) {
if (quantity === null || unitPrice === null) return null;
return Math.round(quantity * unitPrice * 100) / 100;
}
An element can call it in a value expression:
{
"value": "customLineTotal(quantity.value, unitPrice.value)"
}
This property fragment assumes available Number elements named quantity and unitPrice. Registering the file does not call the function. Calls use customLineTotal, independently of the import ID and file name. Keep expression functions synchronous and free of side effects. Pass form inputs as arguments. For detailed expression mechanics, see FSM Expressions and Template Tags.
The complete custom-rates.json file can contain:
{
"standard": 125,
"premium": 175
}
With the ID customRates_v1, a Number element can use this property fragment:
{
"value": "hours.value === null ? null : hours.value * customRates_v1.standard"
}
The local hours.value supplies the changing input. Imported JSON is static data, rather than an FSM Mobile element that changes by itself. A resource mapping determines whether a calculated result is saved to NetSuite.
When Changes Apply
Updating imported files is separate from Refresh Data, which reloads task data. To protect work that has not synchronized, see Refresh and Synchronization in FSM Mobile before using Refresh Data.
FSM Mobile caches downloaded imports for offline use. Changing file contents while retaining the import ID can leave a device using its cached version. Large imports increase app download size and time.
To replace an imported file:
-
Upload the revised file to the File Cabinet.
-
Replace its effective import registration with a different versioned ID, such as
customButton_v2. Preserve other imports and avoid unintentionally loading both versions. -
For JSON, update references to the old ID because it is also the global variable name. For JavaScript, change calls only when exposed function names change. For CSS, change content classes only when selectors change.
-
Save and activate the configuration, then reload FSM Mobile while online to obtain the files.
Omitting a property from a fragment retains an inherited value. For merge and removal rules, see FSM Configuration. File changes do not replace code already running in an open page. Offline devices need to reconnect and download the revised files. Import caching does not automatically cache remote images, linked pages, or other dependencies. A comment placed in inject is not a substitute for this update procedure.
Dependencies and Limits
Restrict configuration access to trained, authorized employees. Use administrator-controlled files and retain their source and deployed import IDs. Treat imports as public browser resources: do not put passwords, tokens, or confidential data in imports. File Cabinet permissions govern file management. These permissions do not make data delivered to a browser secret.
Keep custom code external to FSM. Do not modify browser APIs or the JavaScript runtime, FSM JavaScript, app state or database, endpoints, sign-in, or navigation. Do not create custom FSM routes or use window.config, internal selectors, component methods, or stored session data as extension contracts. Use only the data deliberately passed to your own content and your own custom storage or services.
Browser scripts do not acquire the server deployment's execution role. Server-side template tags use their separate context and deployment permissions. Browser imports do not expose their functions to those tags. See FSM Expressions and Template Tags, FSM Script Reference, and Configuring the FSM Module Securely.
The inject property can insert HTML into the page head. Use it only under clear FSM product-team guidance. It is planned for removal. It is not enforced as comments-only. Do not add hot-swap overrides of standard product functions. Ask FSM support whether an existing override is still required before removing it.
Large searches, shared lookup lists, and performance measurement have separate owners. For guidance, see FSM Searches and Field Mapping, FSM Configuration, and Capturing FSM Performance Data. Do not assume that a large JSON import is the appropriate data-loading design.