=================================
Front-end Libraries & Utilities
=================================
Third-party Libraries
=====================
jQuery
------
**Documentation**: https://api.jquery.com/
Core JavaScript library for DOM manipulation and AJAX requests.
.. code-block:: javascript
:caption: Common jQuery patterns used in the project
// Document ready
$(document).ready(function() {
// Initialize components
});
// AJAX request
$.ajax({
url: '/api/endpoint/',
method: 'POST',
data: {
'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val(),
'field': 'value'
},
success: function(response) {
console.log('Success:', response);
}
});
jQuery MultiFile
----------------
**Documentation**: https://multifile.fyneworks.com/
A jQuery plugin for handling multiple file selections in forms, allowing users to select multiple files and manage them before upload.
.. code-block:: html
:caption: Basic HTML for MultiFile
.. code-block:: javascript
:caption: Initializing MultiFile (often automatic with class 'multi')
// If not automatically initialized by class 'multi'
$('input[type=file].multi').MultiFile();
jQuery Sortable
---------------
**Documentation**: (No official documentation found, likely a custom or very old script)
A jQuery plugin for making lists and grids sortable via drag and drop.
.. code-block:: html
:caption: Basic HTML for Sortable list
Item 1
Item 2
Item 3
.. code-block:: javascript
:caption: Initializing Sortable
$('#sortable-list').sortable();
jQuery Mark.js
--------------
**Documentation**: https://markjs.io/
A JavaScript library for highlighting text with custom search terms.
.. code-block:: javascript
:caption: Basic Mark.js usage
// Highlight all occurrences of "lorem"
var instance = new Mark(document.querySelector(".context"));
instance.mark("lorem");
QueryBuilder
------------
**Documentation**: http://querybuilder.js.org/
A jQuery plugin to create complex query builders with a drag-and-drop interface.
.. code-block:: html
:caption: Basic HTML for QueryBuilder
.. code-block:: javascript
:caption: Initializing QueryBuilder
$('#builder').queryBuilder({
filters: [{
id: 'name',
label: 'Name',
type: 'string'
}, {
id: 'age',
label: 'Age',
type: 'integer'
}]
});
Bootstrap
---------
**Documentation**: https://getbootstrap.com/docs/3.4/
**Note**: The project uses Bootstrap 3.x, not 5.x as previously stated.
Bootstrap provides the core CSS framework and responsive grid system.
.. code-block:: html
:caption: Basic Bootstrap grid usage
Left column
Right column
.. code-block:: javascript
:caption: Bootstrap modal usage (Bootstrap 3.x)
$('#myModal').modal('show');
Bootstrap Datepicker
--------------------
**Documentation**: https://github.com/eternicode/bootstrap-datepicker
**Note**: This is an older version of the library, compatible with Bootstrap 3.x.
Provides date selection functionality with Bootstrap styling.
.. code-block:: javascript
:caption: Initialize datepicker
$('.datepicker').datepicker({
format: 'yyyy-mm-dd',
autoclose: true,
todayHighlight: true
});
.. code-block:: html
:caption: HTML markup for datepicker
Bootstrap Multiselect
---------------------
**Documentation**: https://github.com/davidstutz/bootstrap-multiselect
Transforms select elements into multiselect dropdowns.
.. code-block:: javascript
:caption: Initialize multiselect
$('#example-multiselect').multiselect({
includeSelectAllOption: true,
nonSelectedText: 'Select options',
nSelectedText: ' selected',
allSelectedText: 'All selected'
});
.. code-block:: html
:caption: HTML markup for multiselect
Chart.js
--------
**Documentation**: https://www.chartjs.org/docs/latest/
Flexible JavaScript charting library.
.. code-block:: javascript
:caption: Create a basic chart
const ctx = document.getElementById('myChart').getContext('2d');
const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr'],
datasets: [{
label: 'Sales',
data: [12, 19, 3, 5],
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
Chart.js Adapter Date-Fns
-------------------------
**Documentation**: https://www.chartjs.org/chartjs-adapter-date-fns/
Date adapter for Chart.js that uses date-fns for date parsing, formatting, and manipulation.
.. code-block:: javascript
:caption: Configuring Chart.js with date-fns adapter
// Ensure date-fns and adapter are loaded
// Chart.js will automatically use the adapter if date-fns is available
const myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['2023-01-01', '2023-01-02'],
datasets: [{
label: 'My Dataset',
data: [10, 20]
}]
},
options: {
scales: {
x: {
type: 'time',
time: {
unit: 'day'
}
}
}
}
});
Chart.js Plugin Annotation
--------------------------
**Documentation**: https://www.chartjs.org/chartjs-plugin-annotation/
A Chart.js plugin that enables drawing annotations on charts, such as lines, boxes, and ellipses.
.. code-block:: javascript
:caption: Adding a simple line annotation
const myChart = new Chart(ctx, {
// ... chart configuration
options: {
plugins: {
annotation: {
annotations: {
line1: {
type: 'line',
xMin: 100,
xMax: 100,
borderColor: 'rgb(255, 99, 132)',
borderWidth: 2
}
}
}
}
}
});
Chart.js Plugin Chart Boxplot
-----------------------------
**Documentation**: https://sgratzl.github.io/chartjs-chart-boxplot/
A Chart.js plugin for rendering box and violin plots.
.. code-block:: javascript
:caption: Example of a boxplot chart
const myChart = new Chart(ctx, {
type: 'boxplot', // or 'violin'
data: {
labels: ['Dataset 1', 'Dataset 2'],
datasets: [{
label: 'My Boxplot',
data: [[10, 20, 30, 40, 50], [15, 25, 35, 45, 55]]
}]
},
options: {
// ... options specific to boxplot
}
});
Chart.js Plugin Datalabels
--------------------------
**Documentation**: https://chartjs-plugin-datalabels.netlify.app/
A Chart.js plugin to display labels on data elements.
.. code-block:: javascript
:caption: Enabling datalabels on a chart
const myChart = new Chart(ctx, {
// ... chart configuration
options: {
plugins: {
datalabels: {
color: '#fff',
formatter: function(value, context) {
return value;
}
}
}
}
});
Other Third-party Libraries
---------------------------
Moment.js
---------
**Documentation**: https://momentjs.com/docs/
Date and time manipulation library.
.. code-block:: javascript
:caption: Common moment.js usage
// Format dates
const formatted = moment().format('YYYY-MM-DD HH:mm:ss');
// Parse and manipulate dates
const nextWeek = moment().add(7, 'days');
// Relative time
const timeAgo = moment(date).fromNow(); // "2 hours ago"
Toastr
------
**Documentation**: https://github.com/CodeSeven/toastr
Notification library for displaying toast messages.
.. code-block:: javascript
:caption: Toastr notification examples
// Success message
toastr.success('Operation completed successfully!');
// Error message
toastr.error('An error occurred. Please try again.');
// Warning message
toastr.warning('Please check your input.');
// Info message
toastr.info('Processing your request...');
// Configure toastr options
toastr.options = {
"closeButton": true,
"progressBar": true,
"positionClass": "toast-top-right",
"timeOut": "5000"
};
HTMX
----
**Documentation**: https://htmx.org/docs/
Enables AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML.
.. code-block:: html
:caption: HTMX usage examples
.. code-block:: javascript
:caption: HTMX event handling
// Listen for HTMX events
document.addEventListener('htmx:afterRequest', function(event) {
if (event.detail.successful) {
toastr.success('Request completed successfully');
}
});
HTML2Canvas
-----------
**Documentation**: https://html2canvas.hertzen.com/
Used for capturing screenshots of DOM elements.
.. code-block:: javascript
:caption: Capture element as image
html2canvas(document.querySelector('#capture-area')).then(canvas => {
// Convert to image
const imgData = canvas.toDataURL('image/png');
// Create download link
const link = document.createElement('a');
link.download = 'screenshot.png';
link.href = imgData;
link.click();
});
Canvas2Image
------------
A utility for converting canvas elements to image files. It works in conjunction with html2canvas.
.. code-block:: javascript
:caption: Example usage (assuming Canvas2Image is globally available)
// After html2canvas generates a canvas:
html2canvas(document.querySelector("#my-element")).then(function(canvas) {
// Save as PNG
Canvas2Image.saveAsPNG(canvas);
// Or convert to JPEG and append to body
// document.body.appendChild(Canvas2Image.convertToJPEG(canvas, 800, 600));
});
PDF Viewer (pdf.js)
-------------------
**Documentation**: https://mozilla.github.io/pdf.js/
Mozilla's PDF.js for displaying PDF documents in the browser.
.. code-block:: javascript
:caption: Initialize PDF viewer
// Load PDF document
pdfjsLib.getDocument('/path/to/document.pdf').promise.then(function(pdf) {
// Render first page
pdf.getPage(1).then(function(page) {
const canvas = document.getElementById('pdf-canvas');
const context = canvas.getContext('2d');
const viewport = page.getViewport({scale: 1.5});
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({
canvasContext: context,
viewport: viewport
});
});
});
DOMPurify
---------
**Documentation**: https://github.com/cure53/DOMPurify
A DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.
.. code-block:: javascript
:caption: Basic DOMPurify usage
var cleanHtml = DOMPurify.sanitize(dirtyHtml);
console.log(cleanHtml);
SheetJS
-------
**Documentation**: https://sheetjs.com/
A JavaScript library for reading and writing spreadsheet files (Excel, CSV, etc.).
.. code-block:: javascript
:caption: Reading an Excel file (example with input type="file")
document.getElementById('file-input').addEventListener('change', function(e) {
var reader = new FileReader();
reader.onload = function(e) {
var data = new Uint8Array(e.target.result);
var workbook = XLSX.read(data, {type: 'array'});
// Process workbook
console.log(workbook.SheetNames);
};
reader.readAsArrayBuffer(e.target.files[0]);
});
Local Utilities
=====================================
meg_dialog.js
-------------
Custom dialog/modal utility for consistent popup behavior, likely built on top of Bootstrap modals.
.. code-block:: javascript
:caption: meg_dialog.js usage
// Show confirmation dialog
MegDialog.confirm({
title: 'Confirm Action',
message: 'Are you sure you want to delete this item?',
onConfirm: function() {
// Perform delete action
console.log('Confirmed');
},
onCancel: function() {
console.log('Cancelled');
}
});
// Show info dialog
MegDialog.info({
title: 'Information',
message: 'Operation completed successfully',
autoClose: 3000
});
requestUtils.js
---------------
Utility functions for handling AJAX requests and API calls, often including CSRF token handling and loading indicators.
.. code-block:: javascript
:caption: requestUtils.js usage
// Make authenticated API request
RequestUtils.post('/api/endpoint/', {
data: { field: 'value' },
success: function(response) {
console.log('Success:', response);
},
error: function(xhr, status, error) {
toastr.error('Request failed: ' + error);
}
});
// GET request with loading indicator
RequestUtils.get('/api/data/', {
showLoader: true,
target: '#content-area'
});
ellipsis.js
-----------
Utility for truncating text with ellipsis based on container width.
.. code-block:: javascript
:caption: ellipsis.js usage
// Initialize ellipsis on elements
$('.truncate-text').ellipsis({
lines: 2,
ellipClass: 'ellipsis-marker'
});
.. code-block:: html
:caption: HTML markup for ellipsis
This is a very long text that will be truncated with ellipsis
toggle-radios.js
----------------
Utility for enhanced radio button behavior and styling, possibly transforming standard radio buttons into toggle-like buttons.
.. code-block:: javascript
:caption: toggle-radios.js usage
// Initialize toggle radios
$('.toggle-radio-group').toggleRadios({
activeClass: 'active',
onChange: function(value, element) {
console.log('Selected value:', value);
}
});
.. code-block:: html
:caption: HTML markup for toggle radios
infinite-scroll-table.js
------------------------
Implements infinite scrolling for Answer table widget using IntersectionObserver API for progressive data loading.
.. code-block:: html
:caption: HTML markup for infinite scroll sentinel
.. code-block:: javascript
:caption: Configuration
var CONFIG = {
MAX_RETRIES: 2, // Retry failed requests up to 2 times
RETRY_DELAY: 1000, // Wait 1 second between retries
DEBOUNCE_DELAY: 100, // Debounce scroll events by 100ms
ROOT_MARGIN: '200px', // Start loading 200px before reaching bottom
AJAX_TIMEOUT: 60000 // Request timeout: 60 seconds (1 minute)
};
color_field.js
--------------
Custom utility for enhancing `` fields with a consistent bordered swatch and paintbrush icon.
.. code-block:: javascript
:caption: color_field.js usage
// Automatically initializes all color inputs on document ready.
// Example HTML:
//
$(document).ready(function() {
// ... color_field.js logic ...
});
Other Scripts in megforms/static/js
-----------------------------------
This section lists other notable JavaScript files in the project's static directories. These are typically custom scripts for specific functionalities within the application.
* **megforms.js**: Core script for the `megforms` application, containing global configurations, common functions, or initialization logic.
.. code-block:: javascript
:caption: Example megforms.js usage (illustrative)
// Example of a common function that might be in megforms.js
function showGlobalMessage(message, type = 'info') {
toastr[type](message);
}
// Example of initialization logic
$(document).ready(function() {
// Global setup for AJAX error handling
$(document).ajaxError(function(event, xhr, settings, thrownError) {
if (xhr.status === 403) {
showGlobalMessage('Permission denied.', 'error');
}
});
});
* **audio_playback.js**: Handles audio playback functionality.
.. code-block:: javascript
:caption: Example audio_playback.js usage (illustrative)
function playAudio(audioUrl) {
const audio = new Audio(audioUrl);
audio.play();
}
// Event listener for a play button
$(document).on('click', '.play-audio-btn', function() {
const url = $(this).data('audio-url');
playAudio(url);
});
* **audit-select.js**: Script related to selection logic for audits.
.. code-block:: javascript
:caption: Example audit-select.js usage (illustrative)
$(document).on('change', '#audit-dropdown', function() {
const selectedAuditId = $(this).val();
console.log('Audit selected:', selectedAuditId);
// Further actions like loading data for the selected audit
});
* **audits-list.js**: Manages the display and interaction of audit lists.
.. code-block:: javascript
:caption: Example audits-list.js usage (illustrative)
// function to refresh the audit list table
function refreshAuditList(filters) {
// AJAX call to fetch filtered audit data and update table
console.log('Refreshing audit list with filters:', filters);
}
$(document).ready(function() {
refreshAuditList({}); // Load initial list
});
* **btn-group-mobile.js**: Provides specific behavior or styling for button groups on mobile devices.
.. code-block:: javascript
:caption: Example btn-group-mobile.js usage (illustrative)
// Logic to collapse/expand button groups on small screens
$(document).on('click', '.mobile-btn-group-toggle', function() {
$(this).next('.btn-group-mobile-content').slideToggle();
});
* **calendar-layout.js**: Enhances calendar displays for responsiveness across different screen sizes.
.. code-block:: javascript
:caption: Example calendar-layout.js usage (illustrative)
// Adjust calendar view based on screen width
$(window).on('resize', function() {
if ($(window).width() < 768) {
$('#calendar').fullCalendar('changeView', 'listWeek');
} else {
$('#calendar').fullCalendar('changeView', 'month');
}
}).resize(); // Trigger on load
* **conditional-logic.js**: Implements conditional display or behavior based on form inputs or other criteria.
.. code-block:: javascript
:caption: Example conditional-logic.js usage (illustrative)
// Show/hide a field based on another field's value
$(document).on('change', '#field-A', function() {
if ($(this).val() === 'show_B') {
$('#field-B-container').show();
} else {
$('#field-B-container').hide();
}
});
* **copy_auditors.js**: Functionality for copying auditor information.
.. code-block:: javascript
:caption: Example copy_auditors.js usage (illustrative)
// Button click to copy auditor data from one field to another
$(document).on('click', '#copy-auditors-btn', function() {
const sourceAuditors = $('#source-auditors').val();
$('#destination-auditors').val(sourceAuditors);
toastr.success('Auditors copied!');
});
* **dashboard-filter.js**: Manages filtering options and behavior on dashboards.
.. code-block:: javascript
:caption: Example dashboard-filter.js usage (illustrative)
// Apply filters to dashboard widgets
$(document).on('click', '#apply-dashboard-filters', function() {
const dateRange = $('#dashboard-date-range').val();
const status = $('#dashboard-status-filter').val();
// Trigger updates on various dashboard widgets
console.log('Applying dashboard filters:', { dateRange, status });
});
* **dependant-field.js**: Handles logic for form fields that depend on the values of other fields.
.. code-block:: javascript
:caption: Example dependant-field.js usage (illustrative)
// Populate options of a dropdown based on selection in another dropdown
$(document).on('change', '#country-select', function() {
const countryId = $(this).val();
// AJAX call to get cities for the selected country
$.get('/api/cities/' + countryId, function(data) {
$('#city-select').empty().append('');
data.forEach(city => {
$('#city-select').append(``);
});
});
});
* **excanvas.js**: A Google project that provides HTML5 Canvas support for Internet Explorer 7 and 8. (Note: This is an older polyfill and may not be necessary for modern browsers).
.. code-block:: javascript
:caption: Example excanvas.js usage (illustrative - typically automatic)
// No direct usage example as it's a polyfill that patches browser APIs.
// It would be included in the HTML for older IE versions:
//
// Then, standard Canvas API calls would work in IE.
var ctx = document.getElementById('myCanvas').getContext('2d');
ctx.fillRect(0, 0, 100, 100);
* **export-form.js**: Manages the functionality for exporting data from forms.
.. code-block:: javascript
:caption: Example export-form.js usage (illustrative)
// Handle form submission for data export
$(document).on('submit', '#export-options-form', function(e) {
e.preventDefault();
const format = $('#export-format').val();
const data = $(this).serialize();
console.log(`Exporting data in ${format} format with data: ${data}`);
// Trigger file download or API call
});
* **header-toolbar-controller.js**: Controls the behavior and interactions of a header toolbar.
.. code-block:: javascript
:caption: Example header-toolbar-controller.js usage (illustrative)
// Toggle a side navigation menu from a toolbar button
$(document).on('click', '#menu-toggle-btn', function() {
$('#side-nav').toggleClass('open');
$('body').toggleClass('nav-open');
});
* **institutions-dialog.js**: Manages a dialog for selecting or displaying institutions.
.. code-block:: javascript
:caption: Example institutions-dialog.js usage (illustrative)
// Open a modal dialog to select institutions
$(document).on('click', '#open-institution-dialog', function() {
// Assuming a global function or object for the dialog
InstitutionsDialog.show({
onSelect: function(selectedInstitutions) {
console.log('Selected institutions:', selectedInstitutions);
}
});
});
* **issue-form.js**: Handles the logic and interactions for forms related to issues.
.. code-block:: javascript
:caption: Example issue-form.js usage (illustrative)
// Validate and submit an issue creation/edit form
$(document).on('submit', '#issue-creation-form', function(e) {
e.preventDefault();
if ($(this).valid()) { // Assuming jQuery Validate or similar
const issueData = $(this).serializeArray();
console.log('Submitting issue:', issueData);
// AJAX call to save issue
} else {
toastr.error('Please correct form errors.');
}
});
* **issues-table.js**: Manages the display and interaction of tables listing issues.
.. code-block:: javascript
:caption: Example issues-table.js usage (illustrative)
// Initialize a DataTables instance for issues
$(document).ready(function() {
$('#issues-table').DataTable({
ajax: '/api/issues',
columns: [
{ data: 'id' },
{ data: 'title' },
{ data: 'status' }
]
});
});
* **navbar.js**: Script for navigation bar behavior, such as responsiveness or dropdowns.
.. code-block:: javascript
:caption: Example navbar.js usage (illustrative)
// Toggle mobile navigation menu
$(document).on('click', '.navbar-toggler', function() {
$('.navbar-collapse').toggleClass('show');
});
* **print.js**: Provides custom printing functionalities.
.. code-block:: javascript
:caption: Example print.js usage (illustrative)
// Trigger custom print of a specific area
$(document).on('click', '#print-report-btn', function() {
// Assuming a print utility function
PrintUtility.printElement('#report-content');
});
* **qip-table-sorting.js**: Implements sorting functionality for tables related to Quality Improvement Plans (QIP).
.. code-block:: javascript
:caption: Example qip-table-sorting.js usage (illustrative)
// Apply custom sorting to a QIP table column
$(document).on('click', '#qip-table th.sortable', function() {
const column = $(this).data('column');
const direction = $(this).data('direction') === 'asc' ? 'desc' : 'asc';
console.log(`Sorting QIP table by ${column} in ${direction} order.`);
// Re-render table with sorted data
});
* **query-builder-customisations.js**: Customizations or extensions for the QueryBuilder library.
.. code-block:: javascript
:caption: Example query-builder-customisations.js usage (illustrative)
// Add a custom operator to QueryBuilder
QueryBuilder.define('custom_operator', function(options) {
// ... custom operator logic
});
// Override a default template
QueryBuilder.templates.group = '
Custom Group Template
';
* **report-rule-form.js**: Handles forms for defining rules in reports.
.. code-block:: javascript
:caption: Example report-rule-form.js usage (illustrative)
// Save a report rule
$(document).on('submit', '#report-rule-form', function(e) {
e.preventDefault();
const ruleConfig = $(this).serialize();
console.log('Saving report rule:', ruleConfig);
// AJAX call to save rule
});
* **responsive-tabs-functions.js**: Core functions for responsive tab components.
.. code-block:: javascript
:caption: Example responsive-tabs-functions.js usage (illustrative)
// Function to activate a specific tab
function activateTab(tabId) {
$('.responsive-tab-content').hide();
$(`#${tabId}`).show();
$('.responsive-tab-nav .nav-link').removeClass('active');
$(`[data-tab-id="${tabId}"]`).addClass('active');
}
* **responsive-tabs-settings.js**: Configuration settings for responsive tabs.
.. code-block:: javascript
:caption: Example responsive-tabs-settings.js usage (illustrative)
// Define settings for responsive tabs
const responsiveTabConfig = {
breakpoint: 768, // Switch to accordion below this width
animationSpeed: 300
};
// This file would typically be loaded before responsive-tabs.js
// and its settings would be consumed by the main tab logic.
* **responsive-tabs.js**: Implements responsive tab behavior.
.. code-block:: javascript
:caption: Example responsive-tabs.js usage (illustrative)
// Initialize responsive tabs on a container
$(document).ready(function() {
$('#my-responsive-tabs').responsiveTabs(responsiveTabConfig); // Assuming config from settings.js
});
* **sortable-table-columns.js**: Enables sorting of table columns.
.. code-block:: javascript
:caption: Example sortable-table-columns.js usage (illustrative)
// Make table columns sortable
$(document).ready(function() {
$('#my-data-table').find('th.sortable').on('click', function() {
const column = $(this).data('column');
const currentDirection = $(this).data('direction') || 'asc';
const newDirection = currentDirection === 'asc' ? 'desc' : 'asc';
console.log(`Sorting table by ${column} in ${newDirection} order.`);
// Logic to re-sort table rows
$(this).data('direction', newDirection);
});
});
* **sticky.js**: Implements sticky elements (e.g., headers) that remain visible when scrolling.
.. code-block:: javascript
:caption: Example sticky.js usage (illustrative)
// Make an element sticky when scrolling past it
$(document).ready(function() {
$('#sticky-header').sticky({
topSpacing: 0,
zIndex: 100
});
});
* **table-children.js**: Manages interactions or display of child rows/elements within tables.
.. code-block:: javascript
:caption: Example table-children.js usage (illustrative)
// Toggle visibility of child rows in a table
$(document).on('click', '.toggle-child-row', function() {
const row = $(this).closest('tr');
row.next('.child-row').toggle();
$(this).toggleClass('open');
});
* **table-headers.js**: Handles specific behaviors or styling for table headers.
.. code-block:: javascript
:caption: Example table-headers.js usage (illustrative)
// Fix table headers on scroll
$(document).ready(function() {
$('#scrollable-table').on('scroll', function() {
$(this).find('thead th').css('transform', 'translateY(' + this.scrollTop + 'px)');
});
});
* **toast-status.js**: Likely a custom script to display status messages using Toastr.
.. code-block:: javascript
:caption: Example toast-status.js usage (illustrative)
// Display a success toast message after an action
function showSuccessStatus(message) {
toastr.success(message);
}
// Display an error toast message
function showErrorStatus(message) {
toastr.error(message);
}
* **user-groups-form.js**: Manages forms related to user groups.
.. code-block:: javascript
:caption: Example user-groups-form.js usage (illustrative)
// Handle submission of user group creation/edit form
$(document).on('submit', '#user-group-form', function(e) {
e.preventDefault();
const formData = $(this).serialize();
console.log('Saving user group:', formData);
// AJAX call to save user group
});