NetSuite UI Customization Made Simple: A Decision-Tree Approach

March 11, 2024 | 7 minute read
Mohammed Kassem
SuiteCloud Advocate
Text Size 100%:

Making NetSuite UI customizations doesn't have to be a complex undertaking – it can actually be quite straightforward. This guide will show you how to use a decision-tree approach to streamline the process of creating NetSuite UI customizations, helping you avoid unnecessary complexity and sub-optimal paths. You’ll learn about my favorite three-tiered approach starting with the basic modifications and gradually progressing to more sophisticated customizations. This strategy ensures your UI enhancements are both highly usable and manageable, tailored precisely to your business's unique requirements and the specific needs of your users.


What’s the best NetSuite UI customization path for your use case?

The Decision Tree: A Roadmap for Success

The decision tree below outlines three levels of complexity associated with NetSuite UI customization. From left to right, each level offers increasing control and flexibility but also requires a corresponding increase in effort and developer expertise. As you move through the levels, consider your specific needs and comfort level to determine the most suitable approach for your customization goals.

UI-Customization-Decision-Tree

Level 1: Leverage Your Existing NetSuite UI

Start your customization journey by taking advantage of the flexibility of the standard NetSuite UI. This approach keeps things simple and requires minimal coding knowledge. Here's how:

  • Static Customization: Use SuiteBuilder's built-in form customization capabilities to add or remove fields, modify labels, and adjust field sizes within existing forms.
  • Simple Dynamic Changes: Want to go a step further? Consider using SuiteScript or SuiteFlow options. They both allow you to dynamically modify field properties, such as display type (for example change from text to a select list) or its mandatory/optional status based on specific criteria. You can achieve this in the beforeLoad entry point of a SuiteScript User Event script or through a series of Before Record Load triggered actions in SuiteFlow.

 

SuiteScript: User Event beforeLoad

A SuiteScript User Event script's beforeLoad function can be used to dynamically modify form fields when the form is loaded. Here's an example of adding a select field dynamically to a form using SuiteScript:

/**

 * @NApiVersion 2.1

 * @NScriptType UserEventScript

*/

 

define(['N/record', 'N/ui/serverWidget'], function(record, serverWidget) {

    function beforeLoad(context) {

        var form = context.form;

        var selectField = form.addField({

            id: 'custpage_select_field',

            type: serverWidget.FieldType.SELECT,

            label: 'Dynamic Select Field',

            container: 'custom_tab'

        });

        selectField.addSelectOption({

            value: 'option1',

            text: 'Option 1'

        });

        selectField.addSelectOption({

            value: 'option2',

            text: 'Option 2'

        });

        selectField.defaultValue = 'option1';

    }

    return {

        beforeLoad: beforeLoad

    };

});

SuiteFlow: Before Record Load

SuiteFlow allows for the configuration of field behavior without code. However, SuiteScript can be used within SuiteFlow for more complex logic. Here's an example of a SuiteScript action that can be triggered in a workflow:

/**

 * @NApiVersion 2.1

 * @NScriptType WorkflowActionScript

*/

 

define(['N/record'],

    function(record) {

        function onAction(scriptContext) {

            var newRecord = scriptContext.newRecord;

 

            // Perform some dynamic action here

            // For example, set the value of a custom field based on some condition

            if (someCondition) {

                newRecord.setValue({

                    fieldId: 'custom_field_id',

                    value: 'new_value'

                });

            }

            // Save the changes

            newRecord.save();

        }

        return {

            onAction: onAction

        };

    });

Level 2: Building on Existing Record Forms

If you need slightly more control over the UI layout but want to keep things relatively simple, consider this approach:

  • Inline HTML Fields: Leverage SuiteBuilder to create an Inline HTML field. This allows you to use custom HTML code within existing forms. You can use this to display default values containing record fields embedded in your custom HTML.
  • Dynamic Inline HTML and SuiteScript: For more dynamic functionalities, you can combine Inline HTML with SuiteScript. Imagine using the beforeLoad entry point of a User Event script to query data and generate a chart that displays within a custom subtab created through Inline HTML.

 

 

Inline HTML Fields

SuiteBuilder lets you add HTML fields on NetSuite forms through the NetSuite UI. Here’s how:

  1. Navigate to Customization > Lists, Records, & Fields > Record Types > New.
  2. Choose the form where you want to add the Inline HTML field.
  3. Add a new field and select the type as 'Inline HTML'.
  4. In the field's default value, you can input your HTML code.

Dynamic Inline HTML with SuiteScript

For dynamic content, you can use SuiteScript in conjunction with Inline HTML fields. Below is a SuiteScript beforeLoad example that could generate a dynamic chart and insert it into an Inline HTML field on a form:

/**

 * @NApiVersion 2.1

 * @NScriptType UserEventScript

*/

 

define(['N/ui/serverWidget'], function(serverWidget) {

    function beforeLoad(context) {

        var form = context.form;

       

        // Assuming an Inline HTML field with id 'custpage_chart_field' already exists on the form

        var inlineHtmlField = form.getField({

            id: 'custpage_chart_field'

        });

       

        // Dynamically generate chart HTML

        var chartHtml = '<div id="chart-container">...</div>'; // You would generate this based on your data

       

        // Set the content of the Inline HTML field

        inlineHtmlField.defaultValue = chartHtml;

       

        // Add any additional scripts you need for rendering the chart

        // This could be a link to a CDN for a charting library like Chart.js or any custom script

        form.clientScriptModulePath = 'path/to/your/client/script.js';

    }

    return {

        beforeLoad: beforeLoad

    };

});

In this example, beforeLoad is used to inject HTML for a chart into an existing Inline HTML field. The form.clientScriptModulePath is used to include any additional JavaScript needed to render the chart, which could be from a third-party charting library or custom JavaScript that you write.

Level 3: Building Entirely New Interfaces

For situations requiring entirely new interfaces, explore building a Suitelet script. Even with Suitelets, it’s possible to take a minimally complex approach by leveraging the built-in functionalities:

Starting Simple with the Form Object

Here's how you can create a Suitelet that utilizes NetSuite's Form object to maintain a standard UI look and feel:

/**

 * @NApiVersion 2.1

 * @NScriptType Suitelet

*/

 

define(['N/ui/serverWidget'], function(serverWidget) {

    function onRequest(context) {

        var form = serverWidget.createForm({

            title: 'Custom Suitelet Form'

        });

 

        // Add standard NetSuite fields to the form

        form.addField({

            id: 'custpage_field1',

            type: serverWidget.FieldType.TEXT,

            label: 'Field Label'

        });

 

        // Set up standard NetSuite buttons

        form.addSubmitButton({

            label: 'Submit Button'

        });

 

        context.response.writePage(form);

    }

    return {

        onRequest: onRequest

    };

});

Inline HTML Within Suitelets

Once you're comfortable with the Form object, you can introduce Inline HTML fields to inject specific HTML content:

// Continuing from the previous example...

// Add an Inline HTML field to the form

var inlineHtmlField = form.addField({

    id: 'custpage_html_field',

    type: serverWidget.FieldType.INLINEHTML,

    label: 'Inline HTML'

});

 

// Inject custom HTML into the Inline HTML field
inlineHtmlField.defaultValue = '<div>Hello, this is custom HTML content within a Suitelet!</div>';

Fully Custom HTML Suitelets

For complete customization, you can use Suitelet to create a custom HTML page with third-party JavaScript libraries:

/**

 * @NApiVersion 2.1

 * @NScriptType Suitelet

*/

 

define([], function() {

    function onRequest(context) {

        var html = '<!DOCTYPE html><html><head><title>Custom Page</title></head><body>';

        html += '<h1>My Custom Suitelet Page</h1>';

 

        // Include a third-party library, for example, a CDN link to jQuery

        html += '<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>';

 

        // Add custom JavaScript using the third-party library

        html += '<script>$(document).ready(function() { alert("jQuery is working!"); });</script>';

        html += '</body></html>';

        context.response.write(html);

    }

    return {

        onRequest: onRequest

    };

});

In the above examples, the Suitelet starts by presenting a form similar to standard NetSuite forms. It progresses to include custom HTML content and ultimately showcases how to build a fully custom HTML page that can leverage external JavaScript libraries to extend its functionality. Although we have more flexibility at this stage, we have more tech debt to maintain.

Conclusion

Every NetSuite UI customization journey is unique, and the decision-tree approach ensures you can find the perfect balance between simplicity and advanced functionality. Start with the basics and gradually move towards more sophisticated customizations as needed, always keeping your business needs and user experience at the forefront.

Remember, starting small and gradually increasing complexity as needed is always recommended. This ensures a smooth transition and minimizes the risk of introducing errors into your NetSuite environment.

Mohammed Kassem

SuiteCloud Advocate