NetSuite Services Blog - Integration, News, Release Notes, & Pro Tips

Adding a Custom Button on a Record (Part 2): The Trident Technique

Written by Bryan Willman | Jul 31, 2015 6:53:36 PM

When a more complex behavior is required that a NetSuite workflow is not well suited for, we turn to the Trident Technique. The Trident Technique is a SuiteScript design pattern to trigger either a Suitelet, RESTlet or Scheduled Script when a button is clicked by introducing 3 scripts on the target record. The three scripts that make up the trident are:

  1. User Event Script – Used to create the button when the form is loaded (typically in either view, or edit mode)
  2. Client Script – Client function handles click event and calls third script
  3. Suitelet/RESTlet/Scheduled Script – The third script called by client script performs the business logic required when the button is pressed

One thing to note is that we do not actually have to deploy the client script on the record, we just need to create the Client Script record. However, you can if you would like to show the relationship between the script and the record. The choice of script to use for the third script type will depend on the metering and real-time requirements.

In the next example, we help a client create a print view on a purchase order that hides the prices so that it can be sent to technicians to completed services for the customer and obtain signature after the work on the order is completed. The solution we devised is to switch forms on a Purchase Order between the standard form that shows prices and back to new custom form view which hides prices on the Purchase Order with the click of a new button. With the new Purchase Order form that hides prices, we can be then print out the PDF form and send it to technicians to complete services for the customer on the record and obtain their signature when the work is completed. This solution illustrates how the trident technique is used to allow the user to switch views on a Purchase Order from showing prices to another view that hides prices for printing, and back again to showing the original purchase order form type.

To achieve this, we first created a new Purchase Order form and modified the PDF template to fit the requirements of the request to hide all prices on the purchase order form and add a customer signature section at the bottom of the form. This form we called ‘Purchase Order – No Prices’ and we added a new script parameter to hold the ID of the newly created form. We then added a new hidden transaction body field on the Purchase Order form to store the previous form id (‘custbody_previous_po_cust_form_id’). Lastly, we deployed the code changes in a single JavaScript file for all three trident scripts:

 

1) User Event Script – Toggle Prices on PO (UE)
A before load user event script deployed on the Purchase Order will be created that will create a client side button and add it to the form. The button will have a client-side function attached to it.

/**
* User Event script that creates the Toggle Print button on the Purchase Order
*/
function beforeLoad_createButton(type, form, request)
{
    if (type == 'view' || type == 'edit')
    {
        var prevCustomForm = nlapiGetFieldValue('custbody_previous_po_cust_form_id');
        if (prevCustomForm != null && prevCustomForm != '142') {
            // If No Print View
            form.setScript('customscript_print_po_view_cs'); // id of client script
            form.addButton('custpage_rolland_print_po_view1', 'Print View (With Prices)', 'callSuitelet()');
        }
    } else {
        form.setScript('customscript_print_po_view_cs'); // id of client script
        form.addButton('custpage_print_po_view2', 'Print View (No Prices)', 'callSuitelet()');
    }
}

2) Client Script – Toggle Prices on PO (CS)

A client script will be created, but it will not be deployed. This client script will be called by the button click, which is added to the form in the User Event Script. The purpose of the client event script is simply to trigger the third script, a Suitelet when the button is clicked.

/**
* Client Function to call Suitelet
*/
function callSuitelet()
{
    var id = nlapiGetRecordId();
    // Pass Purchase Order Id (paramname = poid)
    window.location = nlapiResolveURL('SUITELET', 'customscript_print_po_view_sl', 'customdeploy_print_po_view_sl')+'&poid='+id;
    return true;
}

3) Suitelet – Toggle Prices on PO (SUI)

This suitelet will toggle the Custom Form field on the Purchase Order between the previous form and the ‘Purchase Order – No Price’ form.

/**
 * Suitelet that changes the PO Form Type
 */
function changePOType(request, response)
{
    var funcName = 'changePOType';
    var id = request.getParameter('poid');
    nlapiLogExecution(LOG._DEBUG, funcName, 'id = ' + id);

    var poRecord = nlapiLoadRecord('purchaseorder', id);
    var customform = poRecord.getFieldValue('customform');
    var prevFormType = poRecord.getFieldValue('custbody_previous_po_cust_form_type');
    nlapiLogExecution(LOG._DEBUG, funcName, 'customform = ' + customform);
    nlapiLogExecution(LOG._DEBUG, funcName, 'prevFormType = ' + prevFormType);

    if (customform == '142') {
        // Set to previous form type
        if (prevFormType != null)
            poRecord.setFieldValue('customform', prevFormType);
        poRecord.setFieldValue('custbody_previous_po_cust_form_type', '142');
        nlapiLogExecution(LOG._DEBUG, funcName, 'custom form = ' + prevFormType);
    } else {
        // Set to No Price Print View
        poRecord.setFieldValue('customform', '142');
        poRecord.setFieldValue('custbody_previous_po_cust_form_type', customform);
        nlapiLogExecution(LOG._DEBUG, funcName, 'custom form = 142');
    }

    nlapiSubmitRecord(poRecord, false, true);
    nlapiLogExecution(LOG._DEBUG, funcName, 'Submitted the PO now redirecting...');
    nlapiSetRedirectURL('RECORD', 'purchaseorder', id, false);
}

While the trident technique requires JavaScript/SuiteScript knowledge, it is the most flexible method of providing button automation in NetSuite.  We showed how we can add complex conditional logic to determine when to show or hide the button on the form.  We also showed how we could call a server-side script by triggering the client-side button-click event.  In the example we provided, we called a Suitelet that took the user away from the original form and then redirected them back to the original form after manipulating the record.  We could also use this technique to perform an AJAX call to perform a server-side callback without taking the user away from the current page.

Be sure to check out the first post in this set on Adding a Custom Button using a Workflow Action Script.