💼 Business Requirement
After a backend action (button click → Suitelet → record update), users return to the record in View mode and need a clear confirmation banner (“Prices refreshed”, “Rates recalculated”, “Sync complete”). This must work without client scripts and should be environment-safe and lightweight.
🧠 Solution Approach (Server-Side Only)
- Use a User Event (beforeLoad) on the target record type.
- In View mode, call
form.addPageInitMessage(...)to show a banner. - Use a simple URL flag (e.g.,
&updated=T) set by the Suitelet (or any backend action) to decide when to display the message. - Optional: add a custom button on the form that calls a Suitelet, performs the work, then redirects back adding the flag.
This pattern is recommended by SuiteRep and works great when you want a no-client-script UX banner rendered by the platform.
🧩 User Event (beforeLoad) — Display banner in View mode
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
* @description Show an info banner on View if the URL has &updated=T
*/
define(['N/ui/serverWidget', 'N/ui/message', 'N/url'], (serverWidget, message, url) => {
function beforeLoad(ctx) {
if (ctx.type !== ctx.UserEventType.VIEW) return;
// Read the URL for a simple boolean flag ?updated=T
const req = ctx.request; // available in beforeLoad only
const updated = (req && String(req.parameters.updated || '').toUpperCase() === 'T');
// Add a custom button that calls a Suitelet to perform the action
ctx.form.addButton({
id: 'custpage_refresh_prices',
label: 'Refresh Prices',
functionName: `window.location='${makeSuiteletUrl(ctx.newRecord.id)}'`
});
// If the Suitelet redirected back with updated=T, show the banner
if (updated) {
ctx.form.addPageInitMessage({
type: message.Type.INFORMATION, // INFORMATION | WARNING | ERROR | CONFIRMATION
title: 'Success',
message: 'Prices were refreshed successfully.',
duration: 7000 // ms; optional, auto-dismiss
});
}
}
function makeSuiteletUrl(internalId) {
// Build a relative Suitelet URL with the record id as a param
// Replace script/deploy with your IDs
const scriptId = 'customscript_sl_refresh_prices';
const deployId = 'customdeploy_sl_refresh_prices';
// For simplicity use net-new path; feel free to use N/url.resolveScript if preferred
return `/app/site/hosting/scriptlet.nl?script=${scriptId}&deploy=${deployId}&id=${encodeURIComponent(internalId)}`;
}
return { beforeLoad };
});
Why this works: form.addPageInitMessage() renders a banner as the page loads (server-side). The SuiteRep article shows exactly this pattern and emphasizes using View mode + addPageInitMessage for clean UX without client scripts.
🧩 Suitelet — Do the work, then redirect with a flag
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
* @description Loads record, performs updates, then redirects back with &updated=T
*/
define(['N/record', 'N/redirect'], (record, redirect) => {
function onRequest(ctx) {
const recId = ctx.request.parameters.id;
if (!recId) return redirect.toTaskLink({ id: 'LIST_PURCHASE_ORDERS' }); // fallback
// Example: perform your backend work here
// const rec = record.load({ type: record.Type.ESTIMATE, id: recId, isDynamic: true });
// ... compute new rates ...
// rec.save({ enableSourcing: true, ignoreMandatoryFields: true });
// Redirect back to the record in View mode and set the flag
redirect.toRecord({
type: record.Type.ESTIMATE, // change to your record type
id: recId,
parameters: { updated: 'T' }
});
}
return { onRequest };
});
This is the classic “do work → redirect → show banner” loop described by SuiteRep (their real-world example updates Estimate rates and confirms after page reload).
✅ Testing Checklist
- Click Refresh Prices → Suitelet runs and redirects back.
- The record opens in View with
?updated=T→ banner appears for ~7s. - Change
message.Typeto WARNING/ERROR/CONFIRMATION for other scenarios. - Remove the URL param and confirm the banner does not show.
🔧 Variations & Tips
- Use
url.resolveScript({ scriptId, deploymentId, params })if you want domain-safe links across roles and data centers. - Add multiple buttons for different backend actions; set different flags (
&recalc=T,&synced=T) and messages accordingly. - Prefer server-side banners for actions initiated by Suitelets/Scheduled scripts. Use
N/ui/messageclient-side only when you need real-time DOM updates (editing forms), per SuiteRep’s note about client vs server contexts.
📌 Summary
With one User Event (beforeLoad) and a small Suitelet, you can deliver crisp, server-side confirmation banners in View mode—no client script required. This improves feedback loops after backend automations (price refreshes, syncs, recalcs) and follows a pattern validated by the SuiteRep team.
Leave a Reply