Organize Your JavaScript Properly
As your APEX application grows, JavaScript code scattered across Dynamic Actions, page-level Execute When Page Loads, and inline HTML becomes impossible to maintain. A namespace and utility library centralizes common functions, prevents global variable conflicts, and makes your code testable and reusable across pages.
Creating the Namespace
// File: /js/app.js (uploaded to Shared Components > Static Application Files)
var APP = APP || {};
APP.config = {
dateFormat: "YYYY-MM-DD",
maxFileSize: 10 * 1024 * 1024,
ajaxTimeout: 30000
};
APP.util = {
formatCurrency: function(value) {
return new Intl.NumberFormat('en-US', {
style: 'currency', currency: 'USD'
}).format(value || 0);
},
formatDate: function(dateStr) {
if (!dateStr) return '';
var d = new Date(dateStr);
return d.toLocaleDateString('en-US', {year:'numeric',month:'short',day:'numeric'});
},
isEmpty: function(val) {
return val === null || val === undefined || val === '' ||
(typeof val === 'string' && val.trim() === '');
},
copyToClipboard: function(text) {
return navigator.clipboard.writeText(text).then(function() {
apex.message.showPageSuccess("Copied to clipboard");
});
}
};
AJAX Wrapper With Standard Error Handling
APP.ajax = {
call: function(processName, params, options) {
var defaults = { dataType: "json", loadingIndicator: "#apex_wait_overlay" };
var opts = $.extend({}, defaults, options);
return apex.server.process(processName, params, {
dataType: opts.dataType,
loadingIndicator: opts.loadingIndicator,
success: function(data) {
if (data.error) {
apex.message.showErrors([{type:"error",location:"page",message:data.error}]);
if (opts.onError) opts.onError(data);
} else {
if (opts.onSuccess) opts.onSuccess(data);
}
},
error: function(jqXHR) {
apex.message.alert("Server error. Please try again.");
if (opts.onError) opts.onError(jqXHR);
}
});
}
};
// Usage across pages:
APP.ajax.call("GET_ORDER_TOTAL", {x01: orderId}, {
onSuccess: function(data) {
apex.item("P10_TOTAL").setValue(APP.util.formatCurrency(data.total));
}
});
Page-Specific Modules
APP.pages = APP.pages || {};
APP.pages.orderEntry = {
init: function() {
this.bindEvents();
this.setDefaults();
},
bindEvents: function() {
$("#P10_QUANTITY, #P10_PRICE").on("change", this.recalculate.bind(this));
},
setDefaults: function() {
if (apex.item("P10_STATUS").isEmpty()) {
apex.item("P10_STATUS").setValue("DRAFT");
}
},
recalculate: function() {
var qty = parseFloat(apex.item("P10_QUANTITY").getValue()) || 0;
var price = parseFloat(apex.item("P10_PRICE").getValue()) || 0;
apex.item("P10_TOTAL").setValue(APP.util.formatCurrency(qty * price));
}
};
// In page Execute When Page Loads:
APP.pages.orderEntry.init();
Loading the Library
Upload app.js to Shared Components, then Static Application Files. Reference it in the application’s User Interface, then JavaScript, then File URLs: #APP_FILES#js/app.js. This loads it on every page with browser caching. Page-specific modules can be in separate files loaded only on the pages that need them.