File manager - Edit - /home/webapp69.cm.in.th/u69319090028/Shop/assets/js/app.js
Back
/** * CARGOO Marketplace App JavaScript * Customer UX/UI Interactivity & Handlers */ const CARGOO_BASE_URL = (() => { try { const s = document.querySelector('script[src*="app.js"]'); return s ? new URL(s.src, window.location.origin).pathname.replace(/\/assets\/js\/app\.js.*/, '') : ''; } catch (e) { return ''; } })(); document.addEventListener('DOMContentLoaded', function () { // 1. Password Show / Hide Toggle document.querySelectorAll('.btn-toggle-password').forEach(function (btn) { btn.addEventListener('click', function () { const targetId = this.getAttribute('data-target'); const input = document.getElementById(targetId); const icon = this.querySelector('i'); if (input) { if (input.type === 'password') { input.type = 'text'; if (icon) { icon.classList.remove('bi-eye'); icon.classList.add('bi-eye-slash'); } } else { input.type = 'password'; if (icon) { icon.classList.remove('bi-eye-slash'); icon.classList.add('bi-eye'); } } } }); }); // 2. Avatar Cropper & Upload Logic const avatarInput = document.getElementById('avatarInput'); const avatarPreview = document.getElementById('avatarPreview'); const cropperModalEl = document.getElementById('cropperModal'); const imageToCrop = document.getElementById('imageToCrop'); const btnCropAndSave = document.getElementById('btnCropAndSave'); const btnTriggerUpload = document.getElementById('btnTriggerUpload'); let cropper = null; if (avatarInput && avatarPreview && cropperModalEl) { const cropperModal = new bootstrap.Modal(cropperModalEl); // When the "Upload Avatar" custom button is clicked (if exposed), but currently we just rely on the input change avatarInput.addEventListener('change', function (e) { const file = e.target.files[0]; if (file) { if (file.size > 2 * 1024 * 1024) { alert('ขนาดไฟล์รูปภาพต้องไม่เกิน 2 MB'); avatarInput.value = ''; return; } const reader = new FileReader(); reader.onload = function (event) { imageToCrop.src = event.target.result; cropperModal.show(); }; reader.readAsDataURL(file); } }); cropperModalEl.addEventListener('shown.bs.modal', function () { cropper = new Cropper(imageToCrop, { aspectRatio: 1, viewMode: 1, dragMode: 'move', autoCropArea: 1, restore: false, guides: true, center: true, highlight: false, cropBoxMovable: true, cropBoxResizable: true, toggleDragModeOnDblclick: false, }); }); cropperModalEl.addEventListener('hidden.bs.modal', function () { if (cropper) { cropper.destroy(); cropper = null; } avatarInput.value = ''; // Reset input so same file can be selected again }); btnCropAndSave.addEventListener('click', function () { if (!cropper) return; const spinner = document.getElementById('cropSpinner'); spinner.classList.remove('d-none'); btnCropAndSave.disabled = true; // Get cropped image as a canvas, then convert to blob cropper.getCroppedCanvas({ width: 500, height: 500 }).toBlob((blob) => { if (!blob) { alert('เกิดข้อผิดพลาดในการครอบรูปภาพ'); spinner.classList.add('d-none'); btnCropAndSave.disabled = false; return; } const formData = new FormData(); // The original form has CSRF token const csrfToken = document.querySelector('input[name="csrf_token"]').value; formData.append('csrf_token', csrfToken); formData.append('avatar', blob, 'avatar.jpg'); fetch(CARGOO_BASE_URL + '/account/profile/avatar', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: formData }) .then(response => response.json()) .then(data => { spinner.classList.add('d-none'); btnCropAndSave.disabled = false; if (data.success) { // Update the preview image directly from the cropped canvas to save another network request // or just append timestamp to the returned filename avatarPreview.src = cropper.getCroppedCanvas().toDataURL('image/jpeg'); cropperModal.hide(); // Show brief success alert alert('อัปเดตรูปโปรไฟล์สำเร็จ!'); } else { alert('เกิดข้อผิดพลาด: ' + (data.message || 'ไม่สามารถอัปโหลดรูปโปรไฟล์ได้')); } }) .catch(err => { console.error(err); spinner.classList.add('d-none'); btnCropAndSave.disabled = false; alert('เกิดข้อผิดพลาดในการเชื่อมต่อกับเซิร์ฟเวอร์'); }); }, 'image/jpeg'); }); } // 3. Store Logo & Cover Live Previews const storeLogoInput = document.getElementById('storeLogoInput'); const logoPreview = document.getElementById('logoPreview'); const logoPlaceholder = document.getElementById('logoPlaceholder'); if (storeLogoInput && logoPreview) { storeLogoInput.addEventListener('change', function (e) { const file = e.target.files[0]; if (file) { if (file.size > 2 * 1024 * 1024) { alert('ขนาดไฟล์รูปภาพต้องไม่เกิน 2 MB'); storeLogoInput.value = ''; return; } const reader = new FileReader(); reader.onload = function (event) { logoPreview.src = event.target.result; logoPreview.classList.remove('d-none'); if (logoPlaceholder) logoPlaceholder.classList.add('d-none'); }; reader.readAsDataURL(file); } }); } const storeCoverInput = document.getElementById('storeCoverInput'); const coverPreview = document.getElementById('coverPreview'); const coverPlaceholder = document.getElementById('coverPlaceholder'); if (storeCoverInput && coverPreview) { storeCoverInput.addEventListener('change', function (e) { const file = e.target.files[0]; if (file) { if (file.size > 2 * 1024 * 1024) { alert('ขนาดไฟล์รูปภาพต้องไม่เกิน 2 MB'); storeCoverInput.value = ''; return; } const reader = new FileReader(); reader.onload = function (event) { coverPreview.src = event.target.result; coverPreview.classList.remove('d-none'); if (coverPlaceholder) coverPlaceholder.classList.add('d-none'); }; reader.readAsDataURL(file); } }); } // 4. Address Edit Modal Population document.querySelectorAll('.btn-edit-address').forEach(function (btn) { btn.addEventListener('click', function () { const addressData = JSON.parse(this.getAttribute('data-address')); const form = document.getElementById('editAddressForm'); if (form && addressData) { form.action = form.getAttribute('data-action-base') + '/' + addressData.id; form.querySelector('[name="recipient_name"]').value = addressData.recipient_name || ''; form.querySelector('[name="phone"]').value = addressData.phone || ''; form.querySelector('[name="house_number"]').value = addressData.house_number || ''; form.querySelector('[name="village"]').value = addressData.village || ''; form.querySelector('[name="alley"]').value = addressData.alley || ''; form.querySelector('[name="street"]').value = addressData.street || ''; form.querySelector('[name="sub_district"]').value = addressData.sub_district || ''; form.querySelector('[name="district"]').value = addressData.district || ''; form.querySelector('[name="province"]').value = addressData.province || ''; form.querySelector('[name="postal_code"]').value = addressData.postal_code || ''; form.querySelector('[name="note"]').value = addressData.note || ''; const defaultCb = form.querySelector('[name="is_default"]'); if (defaultCb) { defaultCb.checked = parseInt(addressData.is_default, 10) === 1; } } }); }); // 5. Product Detail Gallery: Thumbnail Clicker document.querySelectorAll('.gallery-thumbnail-item').forEach(function (thumb) { thumb.addEventListener('click', function () { const mainImg = document.getElementById('productMainImage'); const targetUrl = this.getAttribute('data-image-url'); if (mainImg && targetUrl) { mainImg.src = targetUrl; document.querySelectorAll('.gallery-thumbnail-item').forEach(t => t.classList.remove('active')); this.classList.add('active'); } }); }); // 6. Product Detail: Quantity Steppers const btnMinus = document.getElementById('btnQtyMinus'); const btnPlus = document.getElementById('btnQtyPlus'); const inputQty = document.getElementById('inputQuantity'); if (btnMinus && btnPlus && inputQty) { btnMinus.addEventListener('click', function () { let val = parseInt(inputQty.value, 10) || 1; if (val > 1) { inputQty.value = val - 1; } }); btnPlus.addEventListener('click', function () { let val = parseInt(inputQty.value, 10) || 1; let max = parseInt(inputQty.getAttribute('max'), 10) || 999; if (val < max) { inputQty.value = val + 1; } }); } // 7. Product Detail: Variant Buttons selection document.querySelectorAll('.variant-selector-btn').forEach(function (btn) { btn.addEventListener('click', function () { const group = this.closest('.variation-group'); if (group) { group.querySelectorAll('.variant-selector-btn').forEach(b => b.classList.remove('active')); this.classList.add('active'); } }); }); // 8. Wishlist AJAX Handler (Both Card Buttons & Detail Page Buttons) document.querySelectorAll('.btn-wishlist-card, .btn-wishlist-toggle').forEach(function (btn) { btn.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); const productId = this.getAttribute('data-product-id'); const icon = this.querySelector('i'); const textSpan = this.querySelector('.wishlist-text'); const formData = new FormData(); formData.append('product_id', productId); fetch(CARGOO_BASE_URL + '/api/v1/wishlist/toggle', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' }, body: formData }) .then(res => res.json()) .then(data => { if (data.need_login) { window.location.href = CARGOO_BASE_URL + '/login'; return; } if (data.success) { if (data.is_saved) { this.classList.add('active', 'text-danger'); if (icon) { icon.classList.remove('bi-heart'); icon.classList.add('bi-heart-fill'); } if (textSpan) textSpan.textContent = 'บันทึกแล้ว'; } else { this.classList.remove('active', 'text-danger'); if (icon) { icon.classList.remove('bi-heart-fill'); icon.classList.add('bi-heart'); } if (textSpan) textSpan.textContent = 'บันทึก'; } } }) .catch(err => { console.error('Wishlist error:', err); }); }); }); // 10. Product Create/Edit Multiple Images Previewer const prodImagesInput = document.getElementById('prodImages'); const previewContainer = document.getElementById('imagePreviewContainer'); if (prodImagesInput && previewContainer) { prodImagesInput.addEventListener('change', function (e) { previewContainer.innerHTML = ''; const files = Array.from(e.target.files); files.forEach((file, index) => { if (file.size > 2 * 1024 * 1024) { alert(`ไฟล์ "${file.name}" มีขนาดเกิน 2 MB`); return; } const reader = new FileReader(); reader.onload = function (event) { const thumbDiv = document.createElement('div'); thumbDiv.className = 'image-preview-thumb'; thumbDiv.innerHTML = ` <img src="${event.target.result}" alt="Preview"> ${index === 0 ? '<span class="badge bg-primary position-absolute bottom-0 start-0 m-1" style="font-size:0.6rem;">รูปหลัก</span>' : ''} `; previewContainer.appendChild(thumbDiv); }; reader.readAsDataURL(file); }); }); } // 11. Navbar Notification Dropdown Mark All As Read const btnNavMarkAllRead = document.getElementById('btnNavMarkAllRead'); if (btnNavMarkAllRead) { btnNavMarkAllRead.addEventListener('click', function (e) { e.preventDefault(); e.stopPropagation(); fetch(CARGOO_BASE_URL + '/api/v1/notifications/mark-all-read', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(res => res.json()) .then(data => { if (data.success) { const navBadge = document.getElementById('navNotifBadge'); if (navBadge) { navBadge.classList.add('d-none'); navBadge.textContent = '0'; } document.querySelectorAll('.notif-dropdown-item').forEach(item => { item.classList.remove('bg-primary-subtle', 'bg-opacity-25'); const title = item.querySelector('.fw-bold'); if (title) { title.classList.remove('text-primary'); title.classList.add('text-dark'); } }); document.querySelectorAll('.notif-item-row').forEach(row => { row.classList.remove('bg-primary-subtle', 'bg-opacity-25'); const unreadBadge = row.querySelector('.notif-unread-badge'); if (unreadBadge) unreadBadge.remove(); }); } }) .catch(err => console.error('Error marking all read:', err)); }); } });
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.3 |
proxy
|
phpinfo
|
Settings