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 forms
  • INTEGER
  • IMAGE – lists, sublists, and forms only
  • LABEL
  • 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
Netsuite report list style.
Netsuite grid list style.
Netsuite normal list style
Netsuite plain list style

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

post image via Pixabay

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

Leave a Reply

%d bloggers like this: