Replacing Ext JS Modal with Vanilla JavaScript and CSS

Purpose

This article provides a guide to replace an Ext JS-based modal implementation with a lightweight, modern solution using vanilla JavaScript and CSS. The new approach eliminates dependency on Ext JS, improves maintainability, and enhances performance while preserving the original functionality of displaying a “Terms and Conditions” modal with accept/cancel options.

Scope

This solution applies to web applications requiring a modal dialog for user confirmation, such as accepting terms and conditions, without relying on external libraries like Ext JS. It includes styling, event handling, and integration with existing record-updating logic (e.g., NetSuite custom records).

Steps to Implement

  • Remove Ext JS DependencyIdentify and remove the Ext JS modal code from your script.
  • Ensure no other Ext JS dependencies remain that might conflict with the new implementation.
  • Add the New Modal CodeInsert the provided HTML, CSS, and JavaScript code into your script or webpage where the modal is needed.
  • Customize the message variable to display the appropriate content (e.g., Terms and Conditions text).
  • Test the ModalVerify the modal displays correctly with the overlay, header, body, and footer.
  • Test both the “Accept” and “Cancel” button actions to ensure they behave as expected.
  • If integrated with NetSuite, confirm the custom record field updates and UI elements toggle visibility correctly.
  • Deploy and MonitorDeploy the updated code to your environment.
  • Monitor for any styling or functionality issues in different browsers (e.g., Chrome, Firefox, Edge).

Updated Code

Below is the modern replacement for the Ext JS modal:

javascript

Collapse

Wrap

Copy

// Define the modal content (e.g., Terms and Conditions text)

const message = "Please read and accept the Terms and Conditions below..."; // Replace with actual content

// Create the modal HTML structure with updated styles

const modalHTML = `

<style>

/* Style for the modal overlay */

.modal-overlay {

position: fixed;

top: 0;

left: 0;

width: 100%;

height: 100%;

background-color: rgba(0, 0, 0, 0.5);

display: flex;

justify-content: center;

align-items: center;

z-index: 1000;

}

/* Style for the modal box */

.modal-box {

background-color: #fff;

width: 80%;

max-width: 600px;

height: 550px;

display: flex;

flex-direction: column;

border-radius: 8px;

box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);

overflow: hidden;

}

/* Style for the modal header */

.modal-header {

background-color: #607799;

color: #fff;

padding: 10px;

font-size: 16px;

font-weight: bold;

border-radius: 8px 8px 0 0;

}

/* Style for the modal body */

.modal-body {

font-family: Arial, sans-serif;

font-size: 14px;

line-height: 1.5;

color: #333;

padding: 10px;

overflow-y: auto;

flex: 1;

}

/* Style for the modal footer */

.modal-footer {

background-color: #f1f1f187;

padding: 4px;

text-align: left;

border-top: 1px solid #c5bebe30;

padding-left: 10px;

}

.modal-footer button {

border-radius: 5px;

border-color: #80808073;

font-size: var(–nsn-uif-refreshed-font-size-regular);

font-weight: 600;

padding: var(–nsn-uif-refreshed-size-3-xs) var(–nsn-uif-refreshed-size-2-xs) !important;

}

/* Button hover effect */

.modal-footer button:hover {

background-color: rgb(205, 206, 207);

}

</style>

<div id=”modal” class=”modal-overlay” style=”display: flex;”>

<div class=”modal-box”>

<div class=”modal-header”>Terms and Conditions</div>

<div class=”modal-body”>${message}</div>

<div class=”modal-footer”>

<button class=”yes”>I have read and accept the terms and service</button>

<button class=”no”>Cancel</button>

</div>

</div>

</div>

`;

// Append the modal to the body

document.body.insertAdjacentHTML('beforeend', modalHTML);

// Handle "Accept" button click

document.querySelector('.modal-footer .yes').addEventListener('click', function () {

// Update custom record (NetSuite-specific logic, adjust as needed)

let rec = currentRecord.get();

rec.setValue({

fieldId: "custrecord_vr_svo_terms_cond",

value: true,

});

// Toggle UI elements (assumes jQuery is available)

let $button = jQuery("[id^='custpage_terms_accept_button']");

$button.hide();

let $buttonLine = jQuery("[id^='tr_custpage_terms_accept_button']");

$buttonLine.hide();

let $buttonAcceptSecondary = jQuery("[id^='secondarycustpage_terms_accept_button']");

$buttonAcceptSecondary.hide();

let $button1 = jQuery("[id^='multibuttonsubmit']");

$button1.show();

let $button2 = jQuery("[id^='secondarysubmitter']");

$button2.show();

let $button3 = jQuery("[id^='tdbody_submitter']");

$button3.show();

// Close the modal

document.getElementById('modal').remove();

});

// Handle "Cancel" button click

document.querySelector('.modal-footer .no').addEventListener('click', function () {

console.log("User canceled");

// Close the modal

document.getElementById('modal').remove();

});

Key Improvements

  1. No External Dependencies: Eliminates reliance on Ext JS, reducing overhead.
  2. Modern CSS: Uses Flexbox for layout and includes responsive design principles (e.g., max-width, overflow-y: auto).
  3. Simplified Logic: Event listeners are attached directly to DOM elements, improving readability.
  4. Preserved Functionality: Retains the original behavior, including record updates and UI toggling (e.g., for NetSuite environments).

Troubleshooting

  • Modal Doesn’t Display: Check if document.body.insertAdjacentHTML is executed at the right time (e.g., after DOM is loaded).
  • Buttons Don’t Work: Ensure no duplicate IDs or conflicting event listeners exist in your codebase.
  • Styling Issues: Adjust CSS properties (e.g., z-index, width) if the modal is obscured or misaligned.

Additional Notes

  • If currentRecord or jQuery is unavailable in your environment, replace the NetSuite-specific logic with your application’s equivalent.
  • Customize the message variable with your actual Terms and Conditions content.
  • For production use, consider adding error handling (e.g., try-catch blocks) around record updates.

Leave a comment

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