Search code examples
javascriptnetsuitesuitescript2.0

Display field on record load based on loaded record property


I have a custom Hyperlink field on my Sales Orders that I wanted hidden until that order has an Item Fulfillment record that has shipped. This field only needs displayed when viewing a record. What I can't figure out is how to both: check that the record has the Item Fulfillment AND set the display of the field.

I thought that a ClientScript was the right way to go, since this is purely a UI thing, but per the docs, ClientScripts only run when creating, or editing a record, not when viewing it, so that won't work.

I then tried UserEvents, but they only have 3 trigger points: beforeLoad, beforeSubmit and afterSubmit. I tried to use beforeLoad, and while it does look like I could toggle the display there, at this point the record hasn't been loaded, so I don't think I can check if it has an Item Fulfillment yet.

How can I change the display of a record field in View mode based on a property of the record?

The code I have so far,

/**
 * @NApiVersion 2.x
 * @NScriptType ClientScript
 */
define(
    ['N/log', 'N/search', 'N/ui/serverWidget'],
    /**
     * @param {log} log The log SuiteScript module
     * @param {search} search The search SuiteScript module
     * @param {serverWidget} serverWidget The ui.serverWidget SuiteScript module
     * @returns {Object} Our list of Client Script callbacks
     */
    function (log, search, serverWidget) {
        /**
         * Function to be executed after page is initialized.
         *
         * @param {Object} scriptContext The context of the page when this function is called
         * @param {Record} scriptContext.currentRecord - Current form record
         * @param {string} scriptContext.mode - The mode in which the record is being accessed (create, copy, or edit)
         *
         * @since 2015.2
         */
        function pageInit(scriptContext) {
            const currRecord = scriptContext.currentRecord;
            /** @type {search.Type[]} */
            const shipmentRecords = search.create({
                type: search.Type.ITEM_FULFILLMENT,
                filters: [
                    ["createdfrom", search.Operator.IS, currRecord.getValue("tranid")],
                ],
                columns: ["internalid"],
            }).run().getRange(0, 1);

            if (shipmentRecords.length > 0) {
                currRecord.getField({
                    fieldId: "custbody_my_dynamic_link",
                }).updateDisplayType({
                    displayType: serverWidget.FieldDisplayType.NORMAL,
                });
            }
        }

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

Solution

  • Since you need to control the display on record view, you will need a User Event script with beforeLoad trigger. When you view a record, the record of course already exists and you can absolutely get field values from the record. So your code would look like this:

    /**
     * @NApiVersion 2.1
     * @NScriptType UserEventScript
    */
      define(['N/log', 'N/record', 'N/ui/serverWidget', 'N/search'],
    /**
    * @param{log} log
    * @param{record} record
    * @param{serverWidget} serverWidget
    * @param{search} search
    */
    (log, record, serverWidget, search) => {
        /**
         * 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) => {
            if (scriptContext.type == scriptContext.UserEventType.VIEW)
            {
                const currRecord = scriptContext.newRecord;
                const shipmentRecords = search.create({
                        type: search.Type.ITEM_FULFILLMENT,
                        filters: [["createdfrom", search.Operator.IS, currRecord.getValue("tranid")]],
                        columns: ["internalid"],
                    }).run().getRange(0, 1);
    
                    
                    if (shipmentRecords.length > 0) {
                        const currForm = scriptContext.form;
                        currForm.getField({
                            id: "custbody_my_dynamic_link",
                        }).updateDisplayType({
                            displayType: serverWidget.FieldDisplayType.NORMAL,
                        });
                    }
    
            }
        }
        return {beforeLoad}
    });
    

    Before toggling the display type, you need to specify the form, because the field display is property of the form, not of the record itself.

    You can control the VIEW context either in the script itself (as is here), or select it in the Event Type field of the script deployment record.