* Tue Apr 22 2025 Brian Read <brianr@koozali.org> 11.0.0-2.sme
- Add some styling to the hardware information and quick navigation
This commit is contained in:
194
root/usr/share/smanager/themes/default/public/js/hwinfo.js
Normal file
194
root/usr/share/smanager/themes/default/public/js/hwinfo.js
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Table Navigation Dropdown - JavaScript Only Solution for Mojolicious Sites
|
||||
*
|
||||
* This script automatically creates a dropdown menu to navigate between tables
|
||||
* on a page without requiring any HTML modifications.
|
||||
*
|
||||
* Compatible with all modern browsers and IE11+.
|
||||
*
|
||||
* How to use:
|
||||
* 1. Add this script to your Mojolicious site using a <script> tag
|
||||
* 2. The script will automatically run when the page loads
|
||||
* 3. A dropdown menu will be created at the top of the page
|
||||
*/
|
||||
|
||||
(function() {
|
||||
// Function to run when DOM is fully loaded
|
||||
function initTableNavigation() {
|
||||
// Find all tables with class 'node' (based on your HTML structure)
|
||||
var tables = document.querySelectorAll('table.node');
|
||||
|
||||
if (!tables || tables.length === 0) {
|
||||
console.log('No tables found with class "node"');
|
||||
return;
|
||||
}
|
||||
|
||||
// Create container for the dropdown
|
||||
var navContainer = document.createElement('div');
|
||||
navContainer.style.position = 'sticky';
|
||||
navContainer.style.top = '0';
|
||||
navContainer.style.backgroundColor = '#fff';
|
||||
navContainer.style.padding = '10px 0';
|
||||
navContainer.style.marginBottom = '20px';
|
||||
navContainer.style.zIndex = '100';
|
||||
navContainer.style.borderBottom = '1px solid #ddd';
|
||||
navContainer.style.width = '300px';
|
||||
|
||||
// Create the select element
|
||||
var select = document.createElement('select');
|
||||
select.style.width = '100%';
|
||||
select.style.padding = '10px';
|
||||
select.style.fontSize = '16px';
|
||||
select.style.border = '1px solid #ddd';
|
||||
select.style.borderRadius = '4px';
|
||||
select.style.backgroundColor = '#f8f8f8';
|
||||
select.style.cursor = 'pointer';
|
||||
|
||||
// Add default option
|
||||
var defaultOption = document.createElement('option');
|
||||
defaultOption.value = '';
|
||||
defaultOption.textContent = '-- Jump to a table --';
|
||||
select.appendChild(defaultOption);
|
||||
|
||||
// Process each table and add to dropdown
|
||||
for (var i = 0; i < tables.length; i++) {
|
||||
var table = tables[i];
|
||||
|
||||
// Try to get table ID from the first row if it contains "id:"
|
||||
var tableId = 'table-' + i;
|
||||
var tableName = 'Table ' + (i + 1);
|
||||
|
||||
// Look for the ID in the table header
|
||||
var idCell = table.querySelector('thead td.first');
|
||||
var idValue = table.querySelector('thead td.second');
|
||||
|
||||
if (idCell && idValue && idCell.textContent.trim().toLowerCase() === 'id:') {
|
||||
// Get the ID value (might be in a div with class 'id')
|
||||
var idDiv = idValue.querySelector('.id');
|
||||
if (idDiv) {
|
||||
tableId = idDiv.textContent.trim();
|
||||
tableName = tableId;
|
||||
} else if (idValue.textContent.trim()) {
|
||||
tableId = idValue.textContent.trim();
|
||||
tableName = tableId;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to get a better name from the description if available
|
||||
var descRows = table.querySelectorAll('tbody tr');
|
||||
for (var j = 0; j < descRows.length; j++) {
|
||||
var descRow = descRows[j];
|
||||
var descCell = descRow.querySelector('td.first');
|
||||
var descValue = descRow.querySelector('td.second');
|
||||
|
||||
if (descCell && descValue &&
|
||||
descCell.textContent.trim().toLowerCase().includes('description') &&
|
||||
descValue.textContent.trim()) {
|
||||
tableName = descValue.textContent.trim() + ' (' + tableName + ')';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a unique ID for the table if it doesn't have one
|
||||
if (!table.id) {
|
||||
// Clean the ID to make it valid for HTML
|
||||
var safeId = tableId.replace(/[^a-z0-9]/gi, '_').toLowerCase();
|
||||
table.id = safeId;
|
||||
}
|
||||
|
||||
// Add option to dropdown
|
||||
var option = document.createElement('option');
|
||||
option.value = table.id;
|
||||
option.textContent = tableName;
|
||||
select.appendChild(option);
|
||||
|
||||
// Add scroll margin to the table
|
||||
table.style.scrollMarginTop = '70px';
|
||||
}
|
||||
|
||||
// Add event listener to the select element
|
||||
if (select.addEventListener) {
|
||||
// Modern browsers
|
||||
select.addEventListener('change', handleSelectChange);
|
||||
} else if (select.attachEvent) {
|
||||
// IE8 and below
|
||||
select.attachEvent('onchange', handleSelectChange);
|
||||
}
|
||||
|
||||
// Add the select to the container
|
||||
navContainer.appendChild(select);
|
||||
|
||||
// Insert the container at the top of the body or after the first heading
|
||||
var heading = document.querySelector('h1, h2');
|
||||
if (heading && heading.parentNode) {
|
||||
heading.parentNode.insertBefore(navContainer, heading.nextSibling);
|
||||
} else {
|
||||
var body = document.body;
|
||||
if (body.firstChild) {
|
||||
body.insertBefore(navContainer, body.firstChild);
|
||||
} else {
|
||||
body.appendChild(navContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to handle select change
|
||||
function handleSelectChange() {
|
||||
var selectedValue = this.value;
|
||||
if (selectedValue) {
|
||||
var element = document.getElementById(selectedValue);
|
||||
if (element) {
|
||||
// Scroll to the selected element
|
||||
scrollToElement(element);
|
||||
|
||||
// Highlight the selected table briefly
|
||||
var originalBackground = element.style.backgroundColor || '';
|
||||
element.style.backgroundColor = '#ffffd0';
|
||||
|
||||
// Use setTimeout for the highlight effect
|
||||
setTimeout(function() {
|
||||
element.style.backgroundColor = originalBackground;
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-browser scroll function
|
||||
function scrollToElement(element) {
|
||||
// Check if scrollIntoView is supported
|
||||
if (element.scrollIntoView) {
|
||||
// Try smooth scrolling if supported
|
||||
try {
|
||||
element.scrollIntoView({ behavior: 'smooth' });
|
||||
} catch (error) {
|
||||
// Fallback for browsers that don't support smooth scrolling
|
||||
element.scrollIntoView();
|
||||
}
|
||||
} else {
|
||||
// Manual scroll fallback
|
||||
var rect = element.getBoundingClientRect();
|
||||
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
var targetY = rect.top + scrollTop - 70; // 70px offset for the sticky header
|
||||
|
||||
window.scrollTo(0, targetY);
|
||||
}
|
||||
}
|
||||
|
||||
// Cross-browser DOM ready function
|
||||
function ready(fn) {
|
||||
if (document.readyState !== 'loading') {
|
||||
fn();
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('DOMContentLoaded', fn);
|
||||
} else {
|
||||
document.attachEvent('onreadystatechange', function() {
|
||||
if (document.readyState !== 'loading') {
|
||||
fn();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize when DOM is ready
|
||||
ready(initTableNavigation);
|
||||
})();
|
Reference in New Issue
Block a user