Expand your SuiteScript skills in the Sustainable SuiteScript community for NetSuite developers.

1 How to write your first SuiteScript - for non-developers

Created: May 2, 2017

Disclaimer:

This article is targeted at people who have never written code before. If you're already a developer, and especially if you already know SuiteScript 1.0, these concepts should all be known to you. We'll be focusing primarily on some very basic programming concepts and definitions.

In order to write SuiteScript, we need to learn some programming. Put very simply, programming is writing a sequence of "statements" that the computer - or in our case, NetSuite - will follow. There are thousands of different programming languages, each with its own syntax that determines the format and vocabulary of our statements. Specifically with SuiteScript, we will be writing in the JavaScript language.

So let's write our first script.

Open up any text editor. While we're just getting started, any simple text editor like Notepad, Wordpad, or TextMate will do.

Storing Data

On the first line, we write:

var message = "Hello, Eric!";

This statement is called a "variable declaration". In programming, we use "variables" to store specific pieces of data and reference them later with a specific name. This statement declares a variable named message and assigns it a text value. This will actually be the text of the message we want to display to the user. Feel free to replace my name with yours.

Let's break down this statement in detail.

We indicate that we are declaring a variable by stating the var at the beginning of the statement, then we give our variable a name. This name can be just about anything we want, with a few rules and exceptions. Usually the name will give us some indication of what data will be stored in our variable. We can use this name later to easily reference the same piece of data without having to recreate the actual data.

Next, we assign the data we want to store to our variable by using the single = and specifying the value. Text values, like our message here, are indicated by the double quotes and are called Strings. Everything between the double quotes will be the text of our message when it gets displayed.

Lastly, we use the semi-colon to indicate the end of the statement.

So we have just defined a variable that represents the message we want to display, and we've stored the actual message to be displayed in that variable.

Defining Behaviour

Now we want to actually display that message. On the next line, we add:

alert(message);

This statement involves what's known as a "function". While we use variables to define data, we use functions to group statements together to define repeatable behaviour. Functions can receive data as inputs and also return data as outputs. In this statement, alert is a function that receives our message variable as input.

Variables define data; functions define behaviour.

Some functions are defined for us by the JavaScript language, as is the case with this alert function. Some are defined and given to us by NetSuite, and we can also write our own custom functions.

The alert function defines the behaviour of popping up a message in the browser. You have most certainly seen the alert function in action all over the internet, and I'd bet you'll recognize it immediately once we test this out.

At this point, we actually have valid JavaScript that could be executed in a browser to display a message to the user, but it's not a valid NetSuite script yet. There are still a few more things we need to add so that NetSuite knows how to read and execute our script.

The first thing we need to do is wrap our message and alert behaviour into our own function. This will give our message display behaviour a name that we can then tell NetSuite about.

function showMessage() {
var message = "Hello, Eric!";
alert(message);
}

Similarly to variables and the var keyword, when we declare our own function, we use the function keyword, then give our function a name. In this case, we've named our function showMessage. The empty parentheses that follow our function name would be where we define any data inputs to our function, but showMessage does not need any inputs, so the parentheses remain empty.

The statements that make up the behaviour, or business logic, of our function are called the "body", and we use the curly braces here to identify and surround the body of the function.

By placing our message logic into a function, we've given it a name that NetSuite can reference, and we don't have to re-write the same logic each time we want to display our message.

Structuring Code

The next step in creating a valid NetSuite script is to wrap our business logic in what is called a "module". NetSuite requires that all scripts are formatted as modules, so we need to add some appropriate boilerplate to define our module.

define([], function () {
function showMessage() {
var message = "Hello, Eric!";
alert(message);
}
});

We define a custom module using the define function that is provided by NetSuite. Our module can also load other modules that are provided perhaps by NetSuite, or our own custom modules. The empty square brackets you see represent an empty list where we would import those other modules. Once all of the other modules are loaded, NetSuite executes this function with no name (also called an anonymous function). Since we don't have any modules to load, the list remains empty.

Notice that anywhere we have an opening symbol like a parenthesis or square bracket or curly brace, there is always a corresponding closing symbol to match. The last line of our script here is simply balancing out all previously opening symbols with closing ones.

At this point, with all of our code aligned at the left of the file, it's not very easy to see the various levels of hierarchy we have. We have a module, which contains a function, which in turn contains a body of statements. While the computer, or NetSuite, can understand this just fine, we can make our code quite a bit easier for humans to read by using indentation to indicate hierarchy where appropriate.

define([], function () {
    function showMessage() {
        var message = "Hello, Eric!";
        alert(message);
    }
});

Now we can visually see the hierarchy of our script; it's much easier on the eyes and makes it simpler to follow the structure mentally.

Defining Output

We have just two more elements to add to this file so NetSuite can recognize it as a valid script.

First, we need to define our module's output.

return {
    pageInit: showMessage
};

This return statement defines the output of our module. We use this output to associate our business logic to specific events dispatched by NetSuite. There are dozens of different events dispatched by NetSuite that SuiteScript developers can respond to with scripts. A large part of being a SuiteScript developer is knowing what those events are, when they get fired, and which ones are best to leverage for your application.

Whenever a user loads a record in Edit mode within the NetSuite UI, NetSuite dispatches an event named pageInit. By defining our module's output this way, we are telling NetSuite to execute our showMessage function whenever it fires a pageInit event.

Tagging the Script

The last thing we must add to our script file is called a "comment". Comments allow developers to essentially write "notes-to-self" (or to any other humans). While a script is actually executing, any comments are completely ignored by the computer.

In our comment, we add a few special tags that NetSuite will be able to read and then automatically create an appropriate Script record.

At the top of our file, we add:

/**
@NApiVersion 2.0
@NScriptType ClientScript
@NModuleScope Public
*/

The NApiVersion tag defines which version of SuiteScript we are using. Currently there are versions 1.0 and 2.0; as of NetSuite version 2016.2, SuiteScript 1.0 is still supported but should be considered obsolete. All new development should be done in SuiteScript 2.0.

The NScriptType tag tells NetSuite which type of script we want to create; there are a dozen script types we can create, and each one comes with its own set of events and criteria.

The NModuleScope tag defines the accessibility rules for our module.

At this point, our full script file should look something like this:

/**
@NApiVersion 2.0
@NScriptType ClientScript
@NModuleScope Public
*/
define([], function () {
    function showMessage() {
        var message = "Hello, Eric!";
        alert(message);
    }

    return {
        pageInit: showMessage
    };
});

Deploying to NetSuite

Now it's finally time to see your code in action!

  1. Save your file as "yourName.js"
  2. In NetSuite, Navigate to Customization > Scripting > Scripts > New
  3. Give the Script a Name
  4. Switch to the Deployments tab
  5. On the first line, select Customer for Applies To
  6. Save the Script record

Deployments tell NetSuite which record types we would like our Script to execute for. In our case, we want our Client Script to run on Customer records. Be aware that Client Scripts, like the one we just built, will only run in Edit mode, not in View mode.

Now just edit any Customer record in your account, and you should see your message!

Great work getting to this point! Now that we have our file uploaded to NetSuite and our Script record created and deployed, it'll be much faster to modify our code. From here on out, we only need to change the source file, not the entire Script record.

While displaying this message is nice, it isn't very practical. Let's go back to our code and change it into a real-world scenario.

Let's say that we'd like our message to very clearly alert our Sales Reps when the Customer has not provided an email address. In order to do that, our Script will need to read the email field from the record and ensure it is not empty.

First let's modify our message slightly. Our message will only be displayed when there is no email address provided for the Customer.

We replace our original message with:

var message = "This customer has not provided an email address.";

Adding Function Inputs

Next, we need to add an input to our showMessage function. Remember our function will get called by NetSuite on the pageInit event. Whenever NetSuite calls a function on pageInit, it passes an input object into that function with some contextual information. The function can then use that input to read data from the current record.

We change our showMessage declaration like so:

function showMessage(context) {

We can name this input whatever we wish; I've called it context.

Reading Data from the Record

When NetSuite passes this context object to us, it attaches a currentRecord property to it that contains all of the information on the record the user is currently editing. We want to read the email field from that record.

To do that, we use the "dot" operator to drill down into the data object. The context object has a currentRecord property with all the record information on it, and the currentRecord property subsequently has a getValue function defined on it that lets us read data from a particular field on the record. In this case, we'll ask the script to read the email field. Add a new line after our message declaration:

var email = context.currentRecord.getValue({
    "fieldId": "email"
});

We've read the value from the email field on currentRecord and stored that value inside a variable named email.

Conditional Logic

Now we only want to display our message if the email field is empty, so we need a way to only perform our call to alert under certain conditions. We do this with an if statement.

if () {
    alert(message);
}

We wrap our call to alert inside this if statement. Similarly to our function declaration, the if statement has some empty parentheses and some braces that delineate its body. Inside the parentheses is where we put the condition(s) for executing the code within the body.

We only want to display our message if the email field is empty. If the field is empty, then our email variable will also be empty. To check if a text value is empty, we use the NOT operator, which is an exclamation point.

if (!email) {
    alert(message);
}

You can essentially read this as

"If the contents of the email variable are empty, alert the user with the contents of the message variable."

There are tons of rules dictating how the NOT operator works, and there are many other operators you can use to build conditionals like this, but that is all well beyond the scope of this article.

Updating the Script

The final version of our script should look something like:

/**
@NApiVersion 2.0
@NScriptType ClientScript
@NModuleScope Public
*/
define([], function () {
    function showMessage(context) {
        var message = "This customer has not provided an email address.";
        var email = context.currentRecord.getValue({
            "fieldId": "email"
        });

        if (!email) {
            alert(message);
        }
    }

    return {
        pageInit: showMessage
    };
});

Let's upload these changes to our script.

  1. Save your changes
  2. Select all > Copy
  3. On our Script record, find the Source File and click Edit
  4. Select all > Paste
  5. Save
  6. Edit a Customer with an email address
  7. No message should be displayed
  8. Edit a Customer without an email address
  9. Your message should be displayed

If this is your first time reading and writing code, then I know there are tons of questions swirling around. Don't worry! That's normal. You've taken your first steps into a much larger world. If you stay tuned right here, you'll get more and more comfortable in code.