diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index 730d0349d..26af3298f 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -86,88 +86,108 @@ function makeVisible(el) { el.style.visibility = "visible"; } -// TODO: Write caption here +/** + * Creates and adds a modal dialog to the DOM with customizable attributes and content. + * + * @param {string} action - The action type or identifier used to create a unique modal ID. + * @param {string} id - A unique identifier for the modal, appended to the action for uniqueness. + * @param {string} ariaLabelledby - The ID of the element that labels the modal, for accessibility. + * @param {string} ariaDescribedby - The ID of the element that describes the modal, for accessibility. + * @param {string} modalHeading - The heading text displayed at the top of the modal. + * @param {string} modalDescription - The main descriptive text displayed within the modal. + * @param {string} modalSubmit - The HTML content for the submit button, allowing customization. + * @param {HTMLElement} wrapper_element - Optional. The element to which the modal is appended. If not provided, defaults to `document.body`. + * @param {boolean} forceAction - Optional. If true, adds a `data-force-action` attribute to the modal for additional control. + * + * The modal includes a heading, description, submit button, and a cancel button, along with a close button. + * The `data-close-modal` attribute is added to cancel and close buttons to enable closing functionality. + */ function addModal(action, id, ariaLabelledby, ariaDescribedby, modalHeading, modalDescription, modalSubmit, wrapper_element, forceAction) { - const modal = document.createElement('div'); - modal.setAttribute('class', 'usa-modal'); - modal.setAttribute('id', `${action}-${id}`); - modal.setAttribute('aria-labelledby', ariaLabelledby); - modal.setAttribute('aria-describedby', ariaDescribedby); - if (forceAction) - modal.setAttribute('data-force-action', ''); + const modal = document.createElement('div'); + modal.setAttribute('class', 'usa-modal'); + modal.setAttribute('id', `${action}-${id}`); + modal.setAttribute('aria-labelledby', ariaLabelledby); + modal.setAttribute('aria-describedby', ariaDescribedby); + if (forceAction) + modal.setAttribute('data-force-action', ''); - modal.innerHTML = ` -
-
-

- ${modalHeading} -

-
-

- ${modalDescription} -

-
- + modal.innerHTML = ` +
+
+

+ ${modalHeading} +

+
+

+ ${modalDescription} +

+
+ -
- ` - if (wrapper_element) { - wrapper_element.appendChild(modal); - } else { - document.body.appendChild(modal); - } + +
+ ` + if (wrapper_element) { + wrapper_element.appendChild(modal); + } else { + document.body.appendChild(modal); + } } /** * Helper function that creates a dynamic accordion navigation - * @param {string} action + * @param {string} action - The action type or identifier used to create a unique DOM IDs. * @param {string} unique_id - An ID that when combined with action makes a unique identifier * @param {string} modal_button_text - The action button's text * @param {string} screen_reader_text - A screen reader helper */ function generateKebabHTML(action, unique_id, modal_button_text, screen_reader_text) { - // The first block displays regiular buttons on mobile. The class visible-mobile-flex controls this. - // The second block build a kebob triggered accordion on larger screens, controlled by hidden-mobile-flex. - const kebab = ` + + const generateModalButton = (mobileOnly = false) => ` - ` : ''} + ${modal_button_text} ${screen_reader_text} + `; + + // Main kebab structure + const kebab = ` + ${generateModalButton(true)}
@@ -184,23 +204,15 @@ function generateKebabHTML(action, unique_id, modal_button_text, screen_reader_t
- ` - return kebab + `; + + return kebab; } + /** * Toggles expand_more / expand_more svgs in buttons or anchors * @param {Element} element - DOM element @@ -219,9 +231,9 @@ function toggleCaret(element) { } /** - * Helper function that scrolls to an element + * Helper function that scrolls to an element, identified by a class or an id. * @param {string} attributeName - The string "class" or "id" - * @param {string} attributeValue - The class or id name + * @param {string} attributeValue - The class or id used name to identify the element */ function ScrollToElement(attributeName, attributeValue) { let targetEl = null; @@ -1118,7 +1130,11 @@ function uswdsUnloadModals() { window.modal.off(); } -class LoadTableBase { +/** + * Base table class which handles search, retrieval, rendering and interaction with results. + * Classes can extend the basic behavior of this class to customize display and interaction. + */ +class BaseTable { constructor(itemName) { this.itemName = itemName; this.sectionSelector = itemName + 's'; @@ -1151,13 +1167,13 @@ class LoadTableBase { } /** - * Generalized function to update pagination for a list. - * @param {number} currentPage - The current page number (starting with 1). - * @param {number} numPages - The total number of pages. - * @param {boolean} hasPrevious - Whether there is a page before the current page. - * @param {boolean} hasNext - Whether there is a page after the current page. - * @param {number} total - The total number of items. - */ + * Generalized function to update pagination for a list. + * @param {number} currentPage - The current page number (starting with 1). + * @param {number} numPages - The total number of pages. + * @param {boolean} hasPrevious - Whether there is a page before the current page. + * @param {boolean} hasNext - Whether there is a page after the current page. + * @param {number} total - The total number of items. + */ updatePagination( currentPage, numPages, @@ -1247,9 +1263,12 @@ class LoadTableBase { } /** - * A helper that toggles content/ no content/ no search results - * - */ + * A helper that toggles content/ no content/ no search results based on results in data. + * @param {Object} data - Data representing current page of results data. + * @param {HTMLElement} dataWrapper - The DOM element to show if there are results on the current page. + * @param {HTMLElement} noDataWrapper - The DOM element to show if there are no results period. + * @param {HTMLElement} noSearchResultsWrapper - The DOM element to show if there are no results in the current filtered search. + */ updateDisplay = (data, dataWrapper, noDataWrapper, noSearchResultsWrapper) => { const { unfiltered_total, total } = data; if (unfiltered_total) { @@ -1666,7 +1685,7 @@ class LoadTableBase { } } -class DomainsTable extends LoadTableBase { +class DomainsTable extends BaseTable { constructor() { super('domain'); @@ -1732,7 +1751,7 @@ class DomainsTable extends LoadTableBase { } } -class DomainRequestsTable extends LoadTableBase { +class DomainRequestsTable extends BaseTable { constructor() { super('domain-request'); @@ -1942,7 +1961,7 @@ class DomainRequestsTable extends LoadTableBase { } } -class MembersTable extends LoadTableBase { +class MembersTable extends BaseTable { constructor() { super('member'); @@ -2375,7 +2394,7 @@ class MembersTable extends LoadTableBase { } -class MemberDomainsTable extends LoadTableBase { +class MemberDomainsTable extends BaseTable { constructor() { super('member-domain');