Freezing the Header and First Column in Sales Order Item Sublist

 Managing large sublists, such as the Sales Order Item sublist, can be challenging, especially when scrolling through numerous rows. Freezing the header and first column provides a better user experience by keeping key information in view as you scroll horizontally or vertically. Here is a solution that achieves this using a combination of User Event Script (UES) and Client Script (CS).

Key Features of the Solution

  1. Freezing the Header Row: Keeps column headers visible while scrolling vertically.
  2. Freezing the First Column: Ensures the first column remains visible while scrolling horizontally.
  3. Dynamic Height Adjustment: Automatically adjusts the sublist container’s height to fit within the viewport.

Implementation: Scripts Overview

The solution involves two scripts:

  1. User Event Script (UES): Injects the required HTML and JavaScript for freezing functionality into the form during the beforeLoad event.
  2. Client Script (CS): Initializes the freezing behavior on the page and line-level initialization.

UserEventScript

This script adds the custom JavaScript and jQuery-based logic to the Sales Order form during the beforeLoad event.

Key Functions:

Injecting JavaScript Logic: Adds an inline HTML field to embed a script for freezing the header and column.

Dynamic Styling: Adjusts the height of the container to optimize the scrolling area.

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
define(['N/record', 'N/search', 'N/ui/serverWidget'],
    /**
 * @param{record} record
 * @param{search} search
 * @param{serverWidget} serverWidget
 */
    (record, search, serverWidget) => {
        /**
         * Defines the function definition that is executed before record is loaded.
         * @param {Object} scriptContext
         * @param {Record} scriptContext.newRecord - New record
         * @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
         * @param {Form} scriptContext.form - Current form
         * @param {ServletRequest} scriptContext.request - HTTP request information sent from the browser for a client action only.
         * @since 2015.2
         */
        const beforeLoad = (scriptContext) => {
            try {
                // Set the client script file using the file path
                scriptContext.form.clientScriptModulePath = './jj_cs_freeze_header.js'; // Replace with your actual file path


                let htmlString = 
                '<script>' +
                '   function freezeHeadAndColumn() {' +
                '       (function ($, undefined) {' +
                '           $(function () {' +
                '               const windowHeight = $(window).height();' +
                '               const container = $('.uir-machine-table-container');' +


                                // Set container height for scrollable area
                '               if (container.height() < windowHeight) {' +
                '                   container.css('height', 'auto');' +
                '               } else {' +
                '                   container.css('height', '70vh');' +
                '               }' +


                '               container.bind('scroll', (event) => {' +
                '                   const headerElem = $(event.target).find('.uir-machine-headerrow, .uir-list-headerrow');' +


                                    // Freeze header row
                '                   headerElem.css('transform', `translate(0, ${event.target.scrollTop}px)`);' +
                '                   const rows = $(event.target).find('table tr');' +
                '                   rows.each((index, row) => {' +
                '                       const firstCell = $(row).find('th:first-child, td:first-child');' +


                                        // Freeze first column
                '                       firstCell.css('transform', `translate(${event.target.scrollLeft}px, 0)`);' +
                '                   });' +
                '               });' +
                '           });' +
                '       })(window.jQuery);' +
                '   }' +
                '   freezeHeadAndColumn();' +
                '</script>';


                scriptContext.form.addField({
                    type: 'inlinehtml',
                    id: 'custpage_stickyheaders_script',
                    label: 'Hidden'
                }).defaultValue = htmlString;
            } catch (err) {
                log.debug("error@beforeLoad", err);
            }
        }


        return { beforeLoad }


    });

ClientScript

This script ensures that the freezing behavior is activated during the pageInit and lineInit events.

Key Functions:

pageInit Event: Runs the freezing logic when the form loads.

lineInit Event: Ensures the freezing logic applies to inline sublist edits.

/**
 * @NApiVersion 2.x
 * @NScriptType ClientScript
 * @NModuleScope SameAccount
 */
define(['N/record'],
/**
 * @param{record} record
 */
function(record) {
    
    
    function activateFreeze(context) {
        freezeHeadAndColumn();
    }


    return {
        pageInit: activateFreeze,
        lineInit: activateFreeze
    };
    
});

Leave a comment

Your email address will not be published. Required fields are marked *