Scripts

SuiteAdvanced Scripts are geared toward admins who would like more control over NetSuite for their users.

Run JavaScript and CSS on any NetSuite page, not just scriptable records.

SuiteAdvanced must be installed for these scripts to run.

Contents

Instructions

Create .js and .css files in:

File Cabinet / SuiteScripts / SuiteAdvanced

Open SuiteScripts Folder

Multiple JavaScript and CSS files are supported. Use different files for different purposes.

Disable executing a file by editing the file and making it inactive.

Role Examples

Apply Logic Based on Role

Perform functions based on the internal ID of the current user’s role.

Role-Based Logic Example.js
/** @type {string} */
const roleId = document.documentElement.dataset.roleId;
console.log('roleId:', roleId);

switch (roleId) {
  // Administrator
  case '3':
    // Add logic here
    
    break;
  
  // CEO
  case '8':
    // Add logic here
    
    break;
  
  // Sales Manager
  case '9':
    // Add logic here
    
    break;
}

Apply Styles Based on Role

Apply style based on the internal ID of the current user’s role.

Role-Based Styles Example.css
/* Apply style for the Administrator role */
html[data-role-id="3"] {
  /* Add styles here */
  
}

/* Apply style for the CEO role */
html[data-role-id="8"] {
  /* Add styles here */
  
}

/* Apply style for the Sales Manager role */
html[data-role-id="9"] {
  /* Add styles here */
  
}

URL Path Examples

Apply Logic Based on URL Path

Perform functions based on the current URL path.

URL Path-Based Logic Example.js
switch (location.pathname) {
  // Dashboard
  case '/app/center/card.nl':
    // Add logic here
    
    break;
    
  // File Cabinet
  case '/app/common/media/mediaitemfolders.nl':
    // Add logic here
    
    break;
    
  // Saved Search Results
  case '/app/common/search/searchresults.nl':
    // Add logic here
    
    break;
}

Apply Styles Based on URL Path

Apply style based on the current URL path.

URL Path-Based Styles Example.css
/* Apply style to Dashboard */
html[data-path="/app/center/card.nl"] {
  /* Add styles here */
  
}

/* Apply style to File Cabinet */
html[data-path="/app/common/media/mediaitemfolders.nl"] {
  /* Add styles here */
  
}

/* Apply style to Saved Search Results */
html[data-path="/app/common/search/searchresults.nl"] {
  /* Add styles here */
  
}

Real World Examples

Hide NetSuite Annoyances

Hide parts of NetSuite that are annoying or confusing to users.

Hide Stuff.css
/* SuiteApps tab for non-Admins */
html:not(.admin-role) [data-walkthrough="Menu:SuiteApps"],

/* Support tab for non-Admins */
html:not(.admin-role) [data-walkthrough="Menu:Support"],

/* Floating Guided Learning launcher */
.ou-convergence-launcher, .ogl-rw-convergence-launcher {
  display: none !important;
}

Rearrange Center Tabs

Customize the order of Center Tabs.

Center Tabs Order.css
/* Optionally specify which role to apply this to */
html[data-role-id="3"] {

  [data-header-section="navigation"] [data-widget="MenuItem"] {
    /* Default all center tabs to the end */
    order: 100;

    &:has(>[aria-label="Recent Records"]),
    &:has(>[aria-label="Shortcuts"]),
    &:has(>[aria-label="Home"]),
    &[data-automation-id="suiteadvanced"] {
      /* Move "Recent Records", "Shortcuts", "Home", and "SuiteAdvanced" to the beginning */
      order: 0;
    }

    &:has(>[aria-label="Support"]) {
      /* Move "Support" to the first position */
      order: 1;
    }

    &:has(>[aria-label="Customization"]) {
      /* Move "Customization" to the second position */
      order: 2;
    }

    &:has(>[aria-label="Lists"]) {
      /* Move "Lists" to the third position */
      order: 3;
    }
  }

}

Costed Bill of Materials Inquiry: Default the Effective Date to Today

A client wanted to automate a common task on Costed Bill of Materials Inquiries.

However, NetSuite does not allow deploying SuiteScripts to this record type.

The requirements were to default the Effective Date field to today whenever the BOM sublist changes.

Costed BOM Inquiry – Default Effective Date Today.js
if (
  // URL path is Costed Bill of Materials Inquiry record
  location.pathname === '/app/accounting/transactions/manufacturing/costedbillofmaterialsinquiry.nl' &&
  // URL has no parameters, which means the record is in create mode
  !location.search
)
  // Add a listener for when the page has finished loading
  window.addEventListener('load', () => {
    
    // Load the N/currentRecord module with SuiteScript 2.X
    window.require?.(['N/currentRecord'], currentRecord => {
      
      /** @type {currentRecord.CurrentRecord} */
      const rec = currentRecord.get();
      
      /** @type {HTMLTableElement} */ // Get the BOM Items sublist table element
      const bomItemSublistEl = document.querySelector('#bomitems_splits');
      
      // Listen for changes to the sublist HTML
      new MutationObserver(() => {
        // Callback function runs when the sublist HTML changes
        
        // If there are no rows in the sublist, exit
        if (!bomItemSublistEl.querySelector('.uir-list-row-tr')) return;
        
        /** @type {Date} */ // Get the Effective Date from the record
        const currentEffectiveDate = rec.getValue({fieldId: 'effectivedate'});
        
        /** @type {Date} */ // Get today's date
        const today = new Date();
        
        // If the Effective Date is today, exit
        if (today.toDateString() === currentEffectiveDate?.toDateString()) return;
        
        // Set the Effective Date to today
        rec.setValue({fieldId: 'effectivedate', value: today});
        
      }).observe(bomItemSublistEl, {childList: true});
    });
  });