dga_feedback-2.0.0/js/admin.js
js/admin.js
/**
* @file
* Admin JavaScript for DGA Feedback submissions page.
*/
(function (Drupal, once) {
'use strict';
/**
* Initialize table sorting functionality.
*/
function initTableSorting() {
const table = document.getElementById('submissions-table');
if (!table) {
return;
}
const headers = table.querySelectorAll('th.sortable');
const tbody = table.querySelector('tbody');
if (!tbody) {
return;
}
headers.forEach(function (header) {
header.addEventListener('click', function (e) {
// Don't trigger if clicking on sort indicator
if (e.target.classList.contains('sort-indicator')) {
return;
}
const sortField = header.getAttribute('data-sort');
if (!sortField) {
return;
}
// Get current sort parameters from URL
const urlParams = new URLSearchParams(window.location.search);
const currentSort = urlParams.get('sort');
const currentOrder = urlParams.get('order') || 'DESC';
// Determine new sort direction
let newOrder = 'DESC';
if (currentSort === sortField && currentOrder === 'DESC') {
newOrder = 'ASC';
}
// Update URL parameters
urlParams.set('sort', sortField);
urlParams.set('order', newOrder);
urlParams.delete('page'); // Reset to first page when sorting
// Redirect with new parameters
window.location.search = urlParams.toString();
});
});
}
/**
* Initialize filter form enhancements.
*/
function initFilterForm() {
const form = document.getElementById('feedback-filters-form');
if (!form) {
return;
}
// Toggle filters visibility
const toggleButton = document.getElementById('toggle-filters');
const filtersContent = document.getElementById('filters-content');
if (toggleButton && filtersContent) {
toggleButton.addEventListener('click', function() {
const isExpanded = toggleButton.getAttribute('aria-expanded') === 'true';
if (isExpanded) {
filtersContent.style.display = 'none';
toggleButton.setAttribute('aria-expanded', 'false');
toggleButton.querySelector('.toggle-text').textContent = Drupal.t('Show Filters');
} else {
filtersContent.style.display = 'block';
toggleButton.setAttribute('aria-expanded', 'true');
toggleButton.querySelector('.toggle-text').textContent = Drupal.t('Hide Filters');
}
});
}
}
/**
* Initialize dropbutton functionality.
*/
function initDropbuttons() {
const dropbuttons = document.querySelectorAll('.dropbutton-wrapper');
dropbuttons.forEach(function (wrapper) {
const toggle = wrapper.querySelector('.dropbutton__toggle');
const widget = wrapper.querySelector('.dropbutton-widget');
const editLink = wrapper.querySelector('.dropbutton-action:first-child a');
if (!toggle || !widget) {
return;
}
// Remove any existing event listeners by cloning and replacing
const toggleClone = toggle.cloneNode(true);
toggle.parentNode.replaceChild(toggleClone, toggle);
// Add click handler to toggle button (arrow/caret)
toggleClone.addEventListener('click', function (e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
const isOpen = widget.classList.contains('open');
// Close all other dropbuttons first
document.querySelectorAll('.dropbutton-widget.open').forEach(function (openWidget) {
if (openWidget !== widget) {
openWidget.classList.remove('open');
const openToggle = openWidget.querySelector('.dropbutton__toggle');
if (openToggle) {
openToggle.setAttribute('aria-expanded', 'false');
}
}
});
// Toggle current dropbutton
if (isOpen) {
widget.classList.remove('open');
toggleClone.setAttribute('aria-expanded', 'false');
} else {
widget.classList.add('open');
toggleClone.setAttribute('aria-expanded', 'true');
}
}, true); // Use capture phase to ensure it fires first
// Ensure edit link doesn't interfere with toggle
if (editLink) {
editLink.addEventListener('click', function (e) {
// Don't prevent default - let edit link work normally
// But stop propagation if clicking on toggle area
if (e.target.closest('.dropbutton-toggle') || e.target.closest('.dropbutton__toggle')) {
e.preventDefault();
e.stopPropagation();
// Manually trigger toggle click
toggleClone.click();
}
});
}
});
// Close dropbuttons when clicking outside
document.addEventListener('click', function (e) {
if (!e.target.closest('.dropbutton-wrapper')) {
document.querySelectorAll('.dropbutton-widget.open').forEach(function (widget) {
widget.classList.remove('open');
const toggle = widget.querySelector('.dropbutton__toggle');
if (toggle) {
toggle.setAttribute('aria-expanded', 'false');
}
});
}
});
}
/**
* Initialize bulk operations functionality.
*/
function initBulkOperations() {
const selectAllCheckbox = document.getElementById('select-all-checkbox');
const checkboxes = document.querySelectorAll('.submission-checkbox');
const bulkOperationsWrapper = document.getElementById('bulk-operations-wrapper');
const bulkOperationsCount = document.getElementById('bulk-operations-count');
const bulkActionSelect = document.getElementById('bulk-action-select');
const bulkActionSubmit = document.getElementById('bulk-action-submit');
if (!selectAllCheckbox || !bulkOperationsWrapper) {
return;
}
// Update bulk operations UI
function updateBulkOperations() {
const checked = document.querySelectorAll('.submission-checkbox:checked');
const count = checked.length;
if (count > 0) {
bulkOperationsWrapper.style.display = 'block';
bulkOperationsCount.textContent = count;
// Update select all checkbox state
if (count === checkboxes.length) {
selectAllCheckbox.checked = true;
selectAllCheckbox.indeterminate = false;
} else if (count > 0) {
selectAllCheckbox.checked = false;
selectAllCheckbox.indeterminate = true;
} else {
selectAllCheckbox.checked = false;
selectAllCheckbox.indeterminate = false;
}
// Enable/disable submit button based on action selection
if (bulkActionSelect && bulkActionSubmit) {
bulkActionSubmit.disabled = !bulkActionSelect.value;
}
} else {
bulkOperationsWrapper.style.display = 'none';
selectAllCheckbox.checked = false;
selectAllCheckbox.indeterminate = false;
if (bulkActionSubmit) {
bulkActionSubmit.disabled = true;
}
}
}
// Select all checkbox handler
if (selectAllCheckbox) {
selectAllCheckbox.addEventListener('change', function () {
checkboxes.forEach(function (checkbox) {
checkbox.checked = selectAllCheckbox.checked;
});
updateBulkOperations();
});
}
// Individual checkbox handlers
checkboxes.forEach(function (checkbox) {
checkbox.addEventListener('change', function () {
updateBulkOperations();
});
});
// Bulk action select handler
if (bulkActionSelect && bulkActionSubmit) {
bulkActionSelect.addEventListener('change', function () {
bulkActionSubmit.disabled = !this.value;
});
}
// Bulk action submit handler
if (bulkActionSubmit) {
bulkActionSubmit.addEventListener('click', function (e) {
e.preventDefault();
const action = bulkActionSelect ? bulkActionSelect.value : '';
if (!action) {
return;
}
const checked = document.querySelectorAll('.submission-checkbox:checked');
if (checked.length === 0) {
alert(Drupal.t('No items selected.'));
return;
}
// Collect selected IDs
const ids = [];
checked.forEach(function (checkbox) {
ids.push(checkbox.value);
});
if (action === 'delete') {
const confirmMsg = Drupal.formatPlural(ids.length, 'Are you sure you want to delete @count selected item?', 'Are you sure you want to delete @count selected items?', {'@count': ids.length});
if (confirm(confirmMsg)) {
// Get bulk delete URL from settings
const bulkDeleteUrl = (typeof drupalSettings !== 'undefined' &&
drupalSettings.dgaFeedback &&
drupalSettings.dgaFeedback.bulkDeleteUrl)
? drupalSettings.dgaFeedback.bulkDeleteUrl
: '/admin/content/dga-feedback/bulk-delete';
// Create and submit form
const form = document.createElement('form');
form.method = 'POST';
form.action = bulkDeleteUrl;
form.style.display = 'none';
// Get CSRF token from settings
let csrfToken = '';
if (typeof drupalSettings !== 'undefined' && drupalSettings.csrfToken) {
csrfToken = drupalSettings.csrfToken;
}
// Add CSRF token if available
if (csrfToken) {
const csrfInput = document.createElement('input');
csrfInput.type = 'hidden';
csrfInput.name = 'form_token';
csrfInput.value = csrfToken;
form.appendChild(csrfInput);
}
// Add each selected ID
ids.forEach(function (id) {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'submissions[]';
input.value = id;
form.appendChild(input);
});
// Submit form
document.body.appendChild(form);
form.submit();
}
}
});
}
// Initial update
updateBulkOperations();
}
/**
* Initialize all admin functionality.
*/
Drupal.behaviors.dgaFeedbackAdmin = {
attach(context, settings) {
once('dgaFeedbackAdmin', 'body', context).forEach(function () {
initTableSorting();
initFilterForm();
initDropbuttons();
initBulkOperations();
});
},
};
})(Drupal, once);
