Skip to content

Commit

Permalink
Refactor trap focus in modal JS
Browse files Browse the repository at this point in the history
  • Loading branch information
jguo144 committed Nov 22, 2024
1 parent b5e20cf commit 6e82d42
Showing 1 changed file with 35 additions and 64 deletions.
99 changes: 35 additions & 64 deletions ckanext/opendata_theme/opengov_custom_theme/assets/js/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,88 +8,59 @@ $(document).on('keydown', function (e) {
}
});

this.ckan.module('resource-view-embed', function ($) {
var modal;
var self;

function initialize() {
self = this;
modal = $('#embed-'+this.options.id)
$('body').append(modal);
this.el.on('click', _onClick);
$('textarea', modal).on('focus', _selectAllCode).on('mouseup', _preventClick);
$('input', modal).on('keyup change', _updateValues);
_updateEmbedCode();

// Trap focus when modal is shown
modal.on('shown.bs.modal', _trapFocus);
modal.on('hidden.bs.modal', _restoreFocus);
}

function _onClick (event) {
event.preventDefault();
modal.modal('show');
}

function _selectAllCode () {
$('textarea', modal).select();
}

function _updateValues () {
self.options.width = $('[name="width"]', modal).val();
self.options.height = $('[name="height"]', modal).val();
_updateEmbedCode();
}

function _updateEmbedCode () {
$('[name="code"]', modal).val(_embedCode());
}

function _preventClick (event) {
event.preventDefault();
}
// Trap focus inside modal
$(document).ready(function () {
$('a[data-module="api-info"]').on('click', function () {
const modal = $(`#api-info-embed`);
if (modal.length) {
// Trap focus within the modal
trapFocus(modal);
// When closed remove event handlers
modal.find('.close').on('click', function () {
modal.off('keydown');
});
}
});

function _embedCode () {
return '<iframe width="' + self.options.width + '" height="' + self.options.height + '" src="' + self.options.url + '" frameBorder="0"></iframe>';
}
$('a[data-module="resource-view-embed"]').on('click', function () {
const modalId = $(this).data('module-id');
const modal = $(`#embed-${modalId}`);
if (modal.length) {
// Trap focus within the modal
trapFocus(modal);
// When closed remove event handlers
modal.find('.close').on('click', function () {
modal.off('keydown');
});
}
});

// Trap focus
function _trapFocus() {
function trapFocus(modal) {
const focusableElements = modal.find('a, button, input, textarea');
const firstElement = focusableElements.first();
const lastElement = focusableElements.last();

// Focus on first element when the modal opens
modal.on('shown.bs.modal', function () {
firstElement.focus();
});

modal.on('keydown', function (e) {
if (e.key === 'Tab') {
if (e.shiftKey) { // Shift + Tab
if (e.shiftKey) {
// Shift + Tab
if (document.activeElement === firstElement[0]) {
e.preventDefault();
lastElement.focus();
}
} else { // Tab
} else {
// Tab
if (document.activeElement === lastElement[0]) {
e.preventDefault();
firstElement.focus();
}
}
}
});

// Move focus to the modal
firstElement.focus();
}

function _restoreFocus() {
modal.off('keydown');
}

return {
initialize: initialize,
options: {
id: 0,
url: '#',
width: 700,
height: 400
}
}
});

0 comments on commit 6e82d42

Please sign in to comment.