Overview
While customizing a checkout flow in SuiteCommerce Advanced (SCA), developers often introduce modal dialogs (like “Change Shipping Address” or “Edit Address”) for a better user experience. However, you may encounter situations where the modals do not appear, or appear broken or frozen — even though they worked previously.
This article documents a real-world troubleshooting walkthrough where a previously working modal setup stopped functioning, and how to diagnose and resolve the issue step-by-step.
💥 The Problem
The customization involved extending the OrderWizardModuleAddress to:
- Show modals for shipping and billing address selection
- Allow editing addresses via a modal triggered within another modal
Everything worked until recently — suddenly, modals were no longer visible or functioning, and calling:
js
$('#shippingAddressModal').length
in the browser console returned 0, confirming that the modal DOM wasn’t even rendered.
🧩 Initial Hypothesis
“It must be a JavaScript bug or Bootstrap issue.”
But further debugging revealed something deeper…
🔎 Step-by-Step Diagnosis
✅ 1. Check if Modal DOM Exists
js
$('#shippingAddressModal').length
This returned 0, confirming that the modal wasn’t present in the DOM at runtime — meaning Bootstrap or jQuery couldn’t possibly show it.
✅ 2. Inspect the Handlebars Template
The modal’s HTML was wrapped inside nested conditional blocks like:
handlebars
{{#if isShipping}}
{{#if showChangeShipAddOption}}
<!-- Modal HTML -->
{{/if}}
{{/if}}
These conditions were controlled by the getContext() function in the JS view extension:
js
getContext: _.wrap(OrderWizardModuleAddress.prototype.getContext, function (fn) {
const context = fn.apply(this, _.toArray(arguments).slice(1));
context.isShipping = true;
context.showChangeShipAddOption = !!this.addressId;
return context;
});
⚠️ 3. Context Was Not Reflecting Expected Values
Console logging the context revealed:
js showChangeShipAddOption: false
This was because this.addressId was null, causing !!this.addressId to evaluate to false, which blocked the modal from rendering entirely.
🧰 Solutions and Fixes
✅ 1. Make showChangeShipAddOption Less Strict
Instead of relying solely on addressId, consider using:
js context.showChangeShipAddOption = this.getAddressesToShow().length > 0;
This ensures that as long as there are addresses available, the option to change addresses (and the modal) will render.
✅ 2. Ensure Modal Binding Happens After View Render
If you’re using jQuery to bind modal triggers:
js
$('.open-edit-address').on('click', function () {
$('#shippingAddressModal').modal('hide');
$('#editAddressModal').modal('show');
});
You must bind it after the view is rendered, or the element won’t exist yet. Use:
js
initialize: function () {
this.on('afterViewRender', this.handleModalEvents, this);
}
✅ 3. Verify Bootstrap JS is Present
Check in console:
js typeof $.fn.modal // should return 'function'
If it returns undefined, then Bootstrap JS is not loaded — and modals won’t work.
✅ 4. Debug Stacking and Backdrops
When using nested modals or multiple modals, ensure your z-index handling is clean:
$('.modal').on('shown.bs.modal', function () {
const zIndex = 1050 + ($('.modal:visible').length * 10);
$(this).css('z-index', zIndex);
});
Also, always remove lingering backdrops on modal close:
js
$('.modal').on('hidden.bs.modal', function () {
$('.modal-backdrop').remove();
});
🧪 Bonus: Manual Modal Testing
If you suspect rendering issues, inject a test modal directly in the template:
<div id="shippingAddressModal" class="modal fade"> <div class="modal-dialog"><div class="modal-content"><p>Modal Test Content</p></div></div> </div>
Then run:
$('#shippingAddressModal').modal('show');
If this works, your modal behavior is fine — it’s a rendering condition issue.
🏁 Final Thoughts
This issue is a classic example of where template logic, context data, and lifecycle timing all intersect. Even in a robust platform like SuiteCommerce Advanced, a single missing value (like addressId) can quietly break entire UI components if not guarded correctly.
Always check:
- Is the modal HTML rendered?
- Are event handlers bound after render?
- Is Bootstrap fully loaded?
- Are your context conditions solid?
✨ Pro Tip
Wrap your modal rendering logic with data availability checks, not just selection state:
context.showChangeShipAddOption = !!this.addressId || this.getAddressesToShow().length > 0;
This provides a more resilient and user-friendly experience.