Netsuite : SuiteScript Cheat Sheet
Some “cheat codes” for working in SuiteScript to save from “drilling” through endless documentation to find simple answers. Sorry casual visitors, this post will require access to Oracle Netsuite to be able to follow most of the Suite Answers links.
n/UI
The NetSuite UI API had 3 modules:
- dialog – typical web dialog boxes
- message – basic message notification boxes
- serverWidget – to build compound interfaces like Forms, Lists, and Assisstants
n/UI/serverWidget
This API provides some built-in user interface elements that render forms, lists, and “wizards” (Oracle calls them Assistants) that mirror the NetSuite style and UX guide.
n/UI/serverWidget Subtypes
There are 3 basic UI types built into Netsuite that you can leverage in your scriptlets.
Forms – a typical HTML style form
Lists – a typical HTML style data table
Assistant – a basic multi-step “wizard”
Scriptlets can also output raw HTML. It takes a lot more work to get this to integrate smoothly with the Netsuite UI/UX, but it provides a lot more options on how to style your applet.
n/UI/serverWidget Field Types
The reference property is serverWidget.FieldType.<entry>
Many of these are not supported with sublists.
CHECKBOX
CURRENCY
DATE
DATETIME
– cannot use with addField()DATETIMETZ
EMAIL
FILE
FLOAT
HELP
INLINEHTML
– “write only” for formsINTEGER
IMAGE
– lists, sublists, and forms onlyLABEL
LONGTEXT
MULTISELECT
PASSWORD
PERCENT
PHONE
SELECT
RADIO
RICHTEXT
TEXT
TEXTAREA
TIMEOFDAY
URL
Example usage in a list element:
const list = serverWidget.createList( { title: 'Web Orders' });
list.style = serverWidget.ListStyle.REPORT;
list.addColumn( { id: 'id', label: 'ID', type: serverWidget.FieldType.TEXT });
list.addColumn( { id: 'tranid', label: 'TxID', type: serverWidget.FieldType.TEXT });
list.addColumn( { id: 'entity', label: 'Customer', type: serverWidget.FieldType.TEXT });
list.addColumn( { id: 'trandate', label: 'Date', type: serverWidget.FieldType.DATE });
n/UI/serverWidget List Styles
- GRID – column sort headers
- NORMAL
- PLAIN
- REPORT – static headers, adds title above list grid
UI serverWidget Lists vs. Forms
- Lists does not have a mechanism for tabs.
- Lists do not appear to have “outside list” (top of list) INLINE HTML elements.
- Forms can add fields that include hidden HTML elements, such as remote script references.
- Form Sublists are like very limited list presentations, but far from a full Lists implementation
Methods (partial List)
Forms
- addButton()
- addField() – can output “hidden” HTML
- addSublist() — note, not a full features list like serverWidget.List
- addTab()
- addSubTab()
Lists
- addButton()
- addColumn()
- addRow()
- addRows()
- addPageLink()
n/Search
Use the search.create() method to setup a NetSuite search object. It will not limit results, so for most typical data sets you’ll want to match this with a range or pagination method to pull data. The create method is rather generic and will try to “grab everything”, so you’ll likely need to limit the “run” results to a handful or record with getRange(). You’ll also likely want to add filters. Oddly, there does not appear to be any sort of data ordering options available to the search.create() method.
Here is an example of pulling records from cash sale transactions in NetSuite, limiting the returned data set to a few specific columns.
create() sets up a new search object, run() executes the search, and getRange() fetches a subset of the results from the server.
/**
* Get the online (web) orders
*
* From Netsuite Transactions/Cash Sales List
* billaddress - Billing tab "Billing Address" field
* custbodyoriginaladdrexx - Shipping tab custom field "Original Address"
*
* @var {seearch.Result.[]} resultArray
*
* @returns {*}
*/
const fetchOnlineOrders = () => {
const resultArray = search.create({
type: search.Type.CASH_SALE,
title: 'Web Order',
columns: ['recordType', 'tranid', 'entity', 'trandate', 'billaddress', 'custbodyoriginaladdrexx']
}).run().getRange( { start: 0, end: 25 });
return resultArray;
}
NetSuite SuiteScript Errors & Hidden Meanings
SuiteScript errors are wonderfully vague and often rather useless. There are some tricks to know about SuiteScript that will help keep your apps from barfing random messages instead of generating useful reports.
SuiteScript Error: SSS_MISSING_REQD_ARGUMENT
What this is probably trying to tell you is that your field value is EMPTY.
Even an empty string like latitude=” will fail when trying to add this to a sublist. You probably need a non-empty fallback value on a field value string.
The actual output:
{
"type": "error.SuiteScriptError",
"name": "SSS_MISSING_REQD_ARGUMENT",
"message": "Sublist.setSublistValue: Missing a required argument: options.value",
"stack": [
"Error",
" at Object.onRequest (/SuiteScripts/d2c_testlet/d2c_Testlet.js:104:18)"
],
"cause": {
"name": "SSS_MISSING_REQD_ARGUMENT",
"message": "Sublist.setSublistValue: Missing a required argument: options.value"
},
"id": "",
"notifyOff": false,
"userFacing": true
}
Culprit: adding a row to a Form Sublist with a record that returned a null (empty) value in a custom field.
// -- This fails if the field has never been set
list.setSublistValue({
id: 'custbody_shipping_lng',
line,
value: onlineOrders[line].getValue('custbody_shipping_lng')
});
// -- Do this instead to provide a "fallback" default
// -- note, "n/a" is shown here for visibility can be any non-empty string
list.setSublistValue({
id: 'custbody_shipping_lng',
line,
value: onlineOrders[line].getValue('custbody_shipping_lng') || 'n/a'
});
SuiteScript Error: INVALID_FLD_VALUE
This will happen if you set your UI/serverWidget render type to something like FLOAT when you set your fallback value to a string. If you try setting a sublist value like the example above to ‘ ‘ (a single space, or ‘n/a’) , SuiteScript will throw an error like the one below. It cannot render an empty space in a field that has been set to render ‘as float’.
{
"type": "error.SuiteScriptError",
"name": "INVALID_FLD_VALUE",
"message": "You have entered an Invalid Field Value for the following field: custbody_shipping_lat",
"stack": [
"Error\n at Object.onRequest (/SuiteScripts/d2c_testlet/d2c_Testlet.js:99:18)"
],
"cause": {
"type": "internal error",
"code": "INVALID_FLD_VALUE",
"details": "You have entered an Invalid Field Value for the following field: custbody_shipping_lat",
"userEvent": null,
"stackTrace": [
"Error\n at Object.onRequest (/SuiteScripts/d2c_testlet/d2c_Testlet.js:99:18)"
],
"notifyOff": false
},
"id": "",
"notifyOff": false,
"userFacing": true
}
There are two options, render the column as text or change the fallback to ‘0.0’.
// -- this breaks
list.addField( { id: 'custbody_shipping_lng', label: 'Lng', type: serverWidget.FieldType.FLOAT });
...
list.setSublistValue({
id: 'custbody_shipping_lng',
line,
value: onlineOrders[line].getValue('custbody_shipping_lng') || ' '
});
// -- this works
list.addField( { id: 'custbody_shipping_lng', label: 'Lng', type: serverWidget.FieldType.TEXT });
...
list.setSublistValue({
id: 'custbody_shipping_lng',
line,
value: onlineOrders[line].getValue('custbody_shipping_lng') || ' '
});
// -- this also works
list.addField( { id: 'custbody_shipping_lng', label: 'Lng', type: serverWidget.FieldType.FLOAT });
...
list.setSublistValue({
id: 'custbody_shipping_lng',
line,
value: onlineOrders[line].getValue('custbody_shipping_lng') || '0.0'
});