Learn to Take Control and Lock NetSuite Form Fields in Edit Mode

This article is relevant if you are looking for a way to get control over the locking (read only mode) of NetSuite form fields for specific situations where you are not satisfied with workflow locking methods.

Background

NetSuite’s form based customization generally works great. Yet, there are two major situations where the form based mode for managing the user experience is not ideal:

  1. Record State: Locking the record in question because it is in a specific state.
  2. Role Access: The role that is accessing the form needs specific behavior.
  3. Exception Fields: Most of the fields you want to lock, but not all of them.

The only way to get control over the record in a specific situations is to use Workflows or SuiteScript. Modifying forms for each user role can work but, as many NetSuite Administrators know, if you get a number of these, the ongoing form maintenance is cumbersome and error prone. Why not use your own logic to lock fields?

Solving the NetSuite Lock Fields to Read Only Challenge

For a recent client implementation where they leveraged our Record State Manager, we had situations where we wanted to lock down the sales order for edits while at the same time allow for some fields, such as the memo, to be edited after it had been approved. However, we also needed the ability to have specific roles edit the entire record as well.

One of our senior consultants produced the general SuiteScript 2.0 pattern to go after this challenge.

  1. Server Side: we can dynamically go over all the form fields and disable them before the page is rendered.
  2. Client Side: NetSuite does not quite go all the way server side (surprise, surprise), especially for list / column based fields. So we need some clients side helper scripts.

We want our script to do the heavy lifting work.  But we discovered that NetSuite’s provided libraries which dynamically let us query the list of fields seemed insufficient.   Instead of figuring out why the libraries were not returning the entire list of fields, we decided to create some helper list arrays to inform the script of “straggler” fields that were not getting our intended read-only behavior. Finally, we wanted a list of exceptions fields that should not get our read only locked down treatment.

Server Side SuiteScript 2.0 to Lock Fields

Here is the SuiteScript to lock down the fields.

/**
 *@NApiVersion 2.x
 *@NScriptType UserEventScript
 */
define(['N/log','N/record','N/search', 'N/runtime', 'N/ui/serverWidget'],

    function(log,record,search,runtime, serverWidget) {

		var scriptName = "v_UE_SOLockdown.";
        
        //hard code the roles that will not get locked down
        var ADMIN_ROLES = [3,1063];
		
        function beforeLoad(context) {

        	var funcName = scriptName + "beforeLoad";
        	
            //test record situation where we will perform lock
            if ((runtime.executionContext == runtime.ContextType.USER_INTERFACE) && (context.type == context.UserEventType.EDIT) && (context.newRecord.getValue("orderstatus") != "A")) {

            	
                if (ADMIN_ROLES.indexOf(runtime.getCurrentUser().role) >= 0)  {
                    return;  //exit the admin roles as specificed above
                }
                
            		
            	//get the list of fields available via NetSuite's library offer
                var REC = context.newRecord;
                var fieldList = REC.getFields();
            	
                //attack the fields that we can't get control of via NetSuite's standard field list lookup [don't know why; but get control anyways]
            	var OTHER_FIELDS = ["custbody_v_az_latest_ship_date","memo","otherrefnum"];
            	
	    		//spin through the lists and disable
	        	for (var i = 0; i < fieldList.length; i++) disableField(context, fieldList[i]); for (var f in OTHER_FIELDS) disableField(context, OTHER_FIELDS[f]); } } function disableField(context, fieldName) { var funcName = scriptName + "disableField " + fieldName; //create an exception list of fields that we do NOT want disabled var FIELDS_TO_EXCLUDE = ["custbody_v_order_notes"]; if (FIELDS_TO_EXCLUDE.indexOf(fieldName) >= 0){
        		return;
            }
        	
    		//get reference to the form field to disable it.
            var fld = context.form.getField(fieldName);
    		if (fld) {
				fld.updateDisplayType({displayType: serverWidget.FieldDisplayType.DISABLED});	        				
        		log.debug(funcName, "Disabling field");        			
    		} else
    			log.debug(funcName, "Unable to get reference to field");
        }
        
        return {
            beforeLoad: beforeLoad
        }
    }
);

Client Side SuiteScript 2.0 to Lock Fields

In the following script, we had to take control of the situation by accessing the browser’s DOM object to get references to the fields we care about. We discovered NetSuite supplied, but undocumented, Javascript functions to get control over field behavior. Keep in mind that this approach entails some risk as NetSuite does not officially provide support.

/**
 *@NApiVersion 2.x
 *@NScriptType ClientScript
 *@NModuleScope Public
*/
define(['N/record','N/search','N/runtime'],
	function(record, search, runtime){

		//create reference to lists we want to control via client side script
		var REC;
		var BODY_FIELD_LIST = ["shipaddresslist","shipmethod"];
		var ITEM_FIELD_LIST = ["item","quantity","description","amount","rate","price","class","taxcode","options"];
        var ADMIN_ROLES = [3,1063];

		function pageInit(context) {

        	REC = context.currentRecord;

        	if (!REC.id)
        		return;
        	
        	if (ADMIN_ROLES.indexOf(runtime.getCurrentUser().role) >= 0)
        		return;

        	//spin through the list of fields we want to disable
        	for (var f in BODY_FIELD_LIST) {
        		nsDisableField(context, null, BODY_FIELD_LIST[f]);
        	}

        	for (var f in ITEM_FIELD_LIST) {
        		
        		nsDisableField(context, "item", ITEM_FIELD_LIST[f]);
        	}

		}
				
		/* ----------------------------------------------------------------------------------------------------------------------------- */

		function nsDisableField(context,formId,fieldId,lineNbr){
			try {
				
				var fld;
				
				//using DOM referencing and NetSuite supplied functions, find the field and disable it
				if (formId) {
					fld = getFormElement(document.forms[formId+"_form"],getFieldName(fieldId));
					if (fld == null)
						fld = getFormElement( document.forms[formId+'_form'], getFieldName(fieldId)+lineNbr);
				}
				else
					fld = getFormElement(document.forms["main_form"],getFieldName(fieldId));
				
				if (isSelect(fld)){
					disableSelect(fld,true);				
				} else {
				    disableField(fld,true);
				}

				fld = REC.getField(fieldId);
				if (fld) {
					fld.isDisabled = true;
				}
			} catch (e) {
				;
			}
			
		}

    return {
        pageInit: pageInit
    };
    
});

 

Extend NetSuite Platform Capacities with Innovation Leadership

This article is designed to illustrate that we indeed can get control over the NetSuite environment, especially form driven situations. We must always remember that the NetSuite system sits inside the larger universe of software standards and constraints for which it must perform.  Thus, we too can work in that software universe to get the desired logic and behavior we want, if we are willing to work for it.  If you are the type of professional that respects the way we think and wants to be part of an organization that values creativity, ethics, autonomy and care, let’s have a conversation.

Be Sociable, Share!

Marty Zigman

Holding all three official certifications, Marty is Southern California's NetSuite expert and leads a team of senior professionals at Prolecto Resources, Inc. He is a former Deloitte & Touche CPA and has held CTO roles. For over 25 years, Marty has produced leadership in ERP, CRM and eCommerce business systems. Contact Marty to set up a conversation.

More Posts - Website - Twitter - Facebook - LinkedIn - Google Plus - YouTube

| Category: NetSuite, Technical | Leave a comment

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>