$(document).ready(function() {
// Initialize Bootstrap collapse functionality
$('[data-toggle="collapse"]').on('click', function(e) {
e.preventDefault();
var target = $(this).data('target');
var $target = $(target);
// Toggle the collapse
$target.collapse('toggle');
// Update the button state
var $button = $(this);
var $icon = $button.find('.fa');
if ($target.hasClass('show')) {
$button.removeClass('collapsed');
$icon.removeClass('fa-plus').addClass('fa-minus');
} else {
$button.addClass('collapsed');
$icon.removeClass('fa-minus').addClass('fa-plus');
}
});
// Handle collapse events
$('.collapse').on('show.bs.collapse', function() {
var $button = $('[data-target="#' + $(this).attr('id') + '"]');
var $icon = $button.find('.fa');
$button.removeClass('collapsed');
$icon.removeClass('fa-plus').addClass('fa-minus');
});
$('.collapse').on('hide.bs.collapse', function() {
var $button = $('[data-target="#' + $(this).attr('id') + '"]');
var $icon = $button.find('.fa');
$button.addClass('collapsed');
$icon.removeClass('fa-minus').addClass('fa-plus');
});
// Initialize filter UI state on page load
updateFilterUI();
// Infinite Scroll Implementation
var currentPage = 1;
var isLoading = false;
var hasMoreProducts = true;
var loadMoreThreshold = 200; // pixels from bottom to trigger load
var scrollTimeout;
var infiniteScrollEnabled = true;
// Function to load more products
function loadMoreProducts() {
if (isLoading || !hasMoreProducts || !infiniteScrollEnabled) return;
isLoading = true;
$('#infinite-scroll-loader').show();
$('.product-wrapper-grid').addClass('loading');
// Build the AJAX URL with current parameters
var url = 'index.php?route=product/category|loadMoreProducts';
var urlParams = new URLSearchParams(window.location.search);
var category_id = $('#category_id').val();
urlParams.set('category_id', category_id);
var filter_param = $('#filter_param').val();
urlParams.set('filter_param', filter_param);
var filter = $('#filter').val();
urlParams.set('filter', filter);
var sort = $('#sort').val();
urlParams.set('sort', sort);
var order = $('#order').val();
urlParams.set('order', order);
// Add current URL parameters
urlParams.set('page', currentPage + 1);
// Add the parameters to the URL
url += '&' + urlParams.toString();
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
success: function(response) {
if (response.products && response.products.length > 0) {
// Append new products to the grid
var $productGrid = $('.product-wrapper-grid-row');
response.products.forEach(function(product) {
var productHtml = generateProductHtml(product);
$productGrid.append(productHtml);
});
currentPage++;
hasMoreProducts = response.has_more;
// If no more products, show end message
if (!hasMoreProducts) {
$('#end-of-products').show();
}
} else {
hasMoreProducts = false;
$('#end-of-products').show();
}
},
error: function(xhr, status, error) {
console.error('Error loading more products:', error);
// Fallback to regular pagination on error
$('#fallback-pagination').show();
},
complete: function() {
isLoading = false;
$('#infinite-scroll-loader').hide();
$('.product-wrapper-grid').removeClass('loading');
}
});
}
if ('IntersectionObserver' in window) {
const loadTrigger = document.getElementById('load-more-trigger');
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
loadMoreProducts();
}
}, {
root: null,
rootMargin: '200px', // preload before reaching end
threshold: 0
});
if (loadTrigger) {
observer.observe(loadTrigger);
}
}
// Function to generate product HTML
function generateProductHtml(product) {
var style_view = $('#style-view-toggle').find('.active').data('style-view');
var grid_size = 'col-xl-4';
if(style_view == 2){
grid_size = 'col-xl-6';
} else if(style_view == 3){
grid_size = 'col-xl-4';
} else if(style_view == 4){
grid_size = 'col-xl-3';
} else {
grid_size = 'col-xl-4';
}
var html = '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
From
';
html += '' + product.sale_price + '
';
html += '';
html += '
';
html += '
';
html += '
';
html += '
';
html += '';
html += '';
html += '';
html += '';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
';
return html;
}
// Initialize infinite scroll on page load
// Check if we have more than one page of products
var totalProducts = parseInt($('#category_product_total').val()) || 0;
var productsPerPage = parseInt($('#category_limit').val()) || 12;
var totalPages = Math.ceil(totalProducts / productsPerPage);
if (totalPages <= 1) {
// Only one page, show end message
hasMoreProducts = false;
$('#end-of-products').show();
}
// View Mode Toggle Functionality
var infiniteScrollEnabled = true;
$('#infinite-scroll-toggle').on('click', function() {
if (!infiniteScrollEnabled) {
infiniteScrollEnabled = true;
$(this).removeClass('btn-outline-secondary').addClass('btn-outline-primary active');
$('#pagination-toggle').removeClass('btn-outline-primary active').addClass('btn-outline-secondary');
$('#fallback-pagination').hide();
$('#infinite-scroll-loader').show();
$('#end-of-products').show();
}
});
$('#pagination-toggle').on('click', function() {
if (infiniteScrollEnabled) {
infiniteScrollEnabled = false;
$(this).removeClass('btn-outline-secondary').addClass('btn-outline-primary active');
$('#infinite-scroll-toggle').removeClass('btn-outline-primary active').addClass('btn-outline-secondary');
$('#fallback-pagination').show();
$('#infinite-scroll-loader').hide();
$('#end-of-products').hide();
}
});
// Colour dot click handler — swap product card image to selected metal colour
$(document).on('click', '.color-panel-item', function(e) {
e.stopPropagation();
var color = $(this).data('color');
var productId = $(this).data('product-id');
var $container = $('.thumb-img-' + productId);
$container.find('img').each(function() {
var src = $(this).attr('src') || '';
if (src) {
src = src.replace(/_ww_|_yy_|_rr_/g, '_' + color + '_');
$(this).attr('src', src);
}
});
});
// Update scroll handler to respect toggle state with debouncing
$(window).off('scroll.infinite').on('scroll.infinite', function() {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function() {
if (infiniteScrollEnabled && $(window).scrollTop() + $(window).height() >= $(document).height() - loadMoreThreshold) {
loadMoreProducts();
}
}, 100); // 100ms debounce
});
// Function to update filter UI state
function updateFilterUI() {
var filter_param = $('#filter_param').val();
var filter = $('#filter').val();
// Parse current filter parameters
var activeFilterIds = [];
if (filter_param) {
var filtered_param = [];
if (filter_param.indexOf('_') !== -1) {
var filter_param_arr = filter_param.split("_");
filter_param_arr.forEach(function(param) {
if (param.indexOf('.') !== -1) {
var exp_data = param.split(".");
if (exp_data[1]) {
filtered_param.push(exp_data[1]);
}
} else {
filtered_param.push(param);
}
});
} else {
if (filter_param.indexOf('.') !== -1) {
var exp_data = filter_param.split(".");
if (exp_data[1]) {
filtered_param.push(exp_data[1]);
}
} else {
filtered_param.push(filter_param);
}
}
activeFilterIds = filtered_param;
}
if (filter) {
var filterIds = filter.split(',');
filterIds.forEach(function(filterId) {
if (filterId && activeFilterIds.indexOf(filterId) === -1) {
activeFilterIds.push(filterId);
}
});
}
// Remove all active/selected states
$('.category-box, .category-a-box, .js_filter_option, .filter-checkbox').removeClass('selected active').prop('checked', false);
activeFilterIds.forEach(function(filterId) {
$('.category-box[data-filter-id="' + filterId + '"]').addClass('selected');
$('.category-a-box[data-filter-id="' + filterId + '"]').addClass('selected');
$('.js_filter_option[data-filter-id="' + filterId + '"]').addClass('active');
$('.filter-checkbox[id="checkbox' + filterId + '"]').prop('checked', true);
});
}
// AJAX Filter Functionality
function applyFilters(updateUrl = true) {
$('.product-wrapper-grid').addClass('loading');
$('#infinite-scroll-loader').show();
var category_id = $('#category_id').val();
var filter_param = $('#filter_param').val();
var filter = $('#filter').val();
var sort = $('#sort').val();
var order = $('#order').val();
var stone_price_min = $('#stone_price_min').val() || '0';
var stone_price_max = $('#stone_price_max').val() || '50000';
var url = 'index.php?route=product/category|loadMoreProducts';
var urlParams = new URLSearchParams();
urlParams.set('category_id', category_id);
urlParams.set('filter_param', filter_param);
urlParams.set('filter', filter);
//urlParams.set('stone_price_min', stone_price_min);
//urlParams.set('stone_price_max', stone_price_max);
urlParams.set('sort', sort);
urlParams.set('order', order);
urlParams.set('page', 1); // Reset to first page for new filters
url += '&' + urlParams.toString();
// Make AJAX request to get filtered products
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
success: function(response) {
// Clear existing products
$('.product-wrapper-grid-row').empty();
currentPage = 1;
hasMoreProducts = true;
if (response.products && response.products.length > 0) {
var $productGrid = $('.product-wrapper-grid-row');
response.products.forEach(function(product) {
var productHtml = generateProductHtml(product);
$productGrid.append(productHtml);
});
currentPage++;
hasMoreProducts = response.has_more;
if (!hasMoreProducts) {
$('#end-of-products').show();
} else {
$('#end-of-products').hide();
}
} else {
hasMoreProducts = false;
$('#end-of-products').show();
}
// if (updateUrl) {
// var newUrl = window.location.pathname;
// var params = [];
// if (category_id) params.push('path=' + category_id);
// if (filter_param) params.push('filter_param=' + filter_param);
// if (filter) params.push('filter=' + filter);
// //if (stone_price_min != '0') params.push('stone_price_min=' + stone_price_min);
// //if (stone_price_max != '50000') params.push('stone_price_max=' + stone_price_max);
// if (sort) params.push('sort=' + sort);
// if (order) params.push('order=' + order);
// if (params.length > 0) {
// newUrl += '?' + params.join('&');
// }
// window.history.pushState({}, '', newUrl);
// }
updateFilterUI();
},
error: function(xhr, status, error) {
console.error('Error applying filters:', error);
location.reload(); // Fallback to full page reload on error
},
complete: function() {
$('.product-wrapper-grid').removeClass('loading');
$('#infinite-scroll-loader').hide();
}
});
}
// Handle price range slider changes
$(document).on('slidechange', '.slider-price-range', function(event, ui) {
var minValue = ui.values[0];
var maxValue = ui.values[1];
// Update hidden inputs
$('#stone_price_min').val(minValue);
$('#stone_price_max').val(maxValue);
// Update display values
$('.span_stone_price_min').text('£' + minValue);
$('.span_stone_price_max').text('£' + maxValue);
applyFiltersWithCarat(minValue, maxValue, true);
});
// Function to apply filters with carat range
function applyFiltersWithCarat(minPrice, maxPrice, updateUrl = true) {
$('.product-wrapper-grid').addClass('loading');
$('#infinite-scroll-loader').show();
var category_id = $('#category_id').val();
var filter_param = $('#filter_param').val();
var filter = $('#filter').val();
var sort = $('#sort').val();
var order = $('#order').val();
var url = 'index.php?route=product/category|loadMoreProducts';
var urlParams = new URLSearchParams();
urlParams.set('category_id', category_id);
urlParams.set('filter_param', filter_param);
urlParams.set('filter', filter);
urlParams.set('stone_price_min', minPrice);
urlParams.set('stone_price_max', maxPrice);
urlParams.set('sort', sort);
urlParams.set('order', order);
urlParams.set('page', 1);
url += '&' + urlParams.toString();
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
success: function(response) {
$('.product-wrapper-grid-row').empty();
currentPage = 1;
hasMoreProducts = true;
if (response.products && response.products.length > 0) {
var $productGrid = $('.product-wrapper-grid-row');
response.products.forEach(function(product) {
var productHtml = generateProductHtml(product);
$productGrid.append(productHtml);
});
currentPage++;
hasMoreProducts = response.has_more;
if (!hasMoreProducts) {
$('#end-of-products').show();
} else {
$('#end-of-products').hide();
}
} else {
hasMoreProducts = false;
$('#end-of-products').show();
}
// if (updateUrl) {
// var newUrl = window.location.pathname;
// var params = [];
// if (category_id) params.push('path=' + category_id);
// if (filter_param) params.push('filter_param=' + filter_param);
// if (filter) params.push('filter=' + filter);
// //if (minPrice != '0') params.push('stone_price_min=' + minPrice);
// //if (maxPrice != '50000') params.push('stone_price_max=' + maxPrice);
// if (sort) params.push('sort=' + sort);
// if (order) params.push('order=' + order);
// if (params.length > 0) {
// newUrl += '?' + params.join('&');
// }
// window.history.pushState({}, '', newUrl);
// }
updateFilterUI();
},
error: function(xhr, status, error) {
console.error('Error applying filters:', error);
location.reload();
},
complete: function() {
$('.product-wrapper-grid').removeClass('loading');
$('#infinite-scroll-loader').hide();
}
});
}
});
const slider = document.getElementById('categoryStyleSlider');
const scrollAmount = 150;
document.querySelector('.left-arrow').addEventListener('click', () => {
slider.scrollBy({ left: -scrollAmount, behavior: 'smooth' });
});
document.querySelector('.right-arrow').addEventListener('click', () => {
slider.scrollBy({ left: scrollAmount, behavior: 'smooth' });
});
document.addEventListener('DOMContentLoaded', function () {
const toggleButtons = document.querySelectorAll('.read-more-toggle');
toggleButtons.forEach(button => {
button.addEventListener('click', function () {
const container = this.closest('.read-more-container');
container.classList.toggle('expanded');
if (container.classList.contains('expanded')) {
this.textContent = 'Read Less';
} else {
this.textContent = 'Read More';
}
});
});
});