My Cart

1234
4566
123

Find Your Part By Brand and Model OR OEM Part Number

              Loading...
              Loading products...
              (function() { var STOREFRONT_TOKEN = '023adb4fad851d8f82aa1eefdb4ed95c'; var SHOP_DOMAIN = 'meckorn.com'; var API_URL = 'https://' + SHOP_DOMAIN + '/api/2025-01/graphql.json'; var PER_PAGE = 24; var allProducts = []; var selections = { brand: '', model: '', barLength: '', pitch: '', gauge: '', dl: '' }; var currentPage = 1; var QUERY = 'query GetChainProducts($cursor: String) {' + ' products(first: 50, after: $cursor, query: "product_type:*Chainsaw Chain*") {' + ' pageInfo { hasNextPage endCursor }' + ' edges { node {' + ' id title handle' + ' featuredImage { url altText }' + ' priceRange { minVariantPrice { amount currencyCode } }' + ' barLength: metafield(namespace: "custom", key: "bar_length") { value }' + ' pitch: metafield(namespace: "custom", key: "pitch") { value }' + ' gauge: metafield(namespace: "custom", key: "gauge") { value }' + ' driveLinks: metafield(namespace: "custom", key: "drive_links") { value }' + ' modelRef: metafield(namespace: "custom", key: "model") {' + ' references(first: 25) { nodes { ... on Metaobject {' + ' modelField: field(key: "model") { value }' + ' brandRef: field(key: "numbers") { reference { ... on Metaobject { displayName: field(key: "name") { value } } } }' + ' } } }' + ' }' + ' } } }' + '}'; function gql(query, variables) { return fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Shopify-Storefront-Access-Token': STOREFRONT_TOKEN }, body: JSON.stringify({ query: query, variables: variables || {} }) }).then(function(res) { return res.json(); }); } function fetchAllProducts() { var products = []; var cursor = null; var hasMore = true; function next() { if (!hasMore) return Promise.resolve(products); return gql(QUERY, { cursor: cursor }).then(function(data) { var conn = data && data.data && data.data.products; if (!conn) return products; conn.edges.forEach(function(edge) { var node = edge.node; var brands = [], models = []; var nodes = (node.modelRef && node.modelRef.references && node.modelRef.references.nodes) || []; nodes.forEach(function(mo) { var modelVal = mo.modelField && mo.modelField.value; if (modelVal) { modelVal.split(/[,\uff0c]/).forEach(function(s) { var t = s.trim(); if (t) models.push(t); }); } var brandName = mo.brandRef && mo.brandRef.reference && mo.brandRef.reference.displayName && mo.brandRef.reference.displayName.value; if (brandName && brands.indexOf(brandName) === -1) brands.push(brandName); }); products.push({ id: node.id, title: node.title, handle: node.handle, imageUrl: node.featuredImage ? node.featuredImage.url : null, imageAlt: node.featuredImage ? node.featuredImage.altText : node.title, price: node.priceRange && node.priceRange.minVariantPrice ? node.priceRange.minVariantPrice.amount : null, currency: node.priceRange && node.priceRange.minVariantPrice ? node.priceRange.minVariantPrice.currencyCode : null, _dims: { brand: brands, model: models, barLength: node.barLength && node.barLength.value ? [node.barLength.value] : [], pitch: node.pitch && node.pitch.value ? [node.pitch.value] : [], gauge: node.gauge && node.gauge.value ? [node.gauge.value] : [], dl: node.driveLinks && node.driveLinks.value ? [node.driveLinks.value] : [] } }); }); hasMore = conn.pageInfo.hasNextPage; cursor = conn.pageInfo.endCursor; return next(); }); } return next(); } function getOptions(dim) { var others = Object.keys(selections).filter(function(d) { return d !== dim; }); var compatible = allProducts.filter(function(p) { return others.every(function(d) { if (!selections[d]) return true; var vals = p._dims[d]; return !vals || vals.length === 0 || vals.indexOf(selections[d]) !== -1; }); }); var set = {}; compatible.forEach(function(p) { (p._dims[dim] || []).forEach(function(v) { if (v) set[v] = true; }); }); return Object.keys(set).sort(function(a, b) { return a.localeCompare(b, undefined, { numeric: true }); }); } function getMatched() { return allProducts.filter(function(p) { return Object.keys(selections).every(function(d) { if (!selections[d]) return true; var vals = p._dims[d]; return !vals || vals.length === 0 || vals.indexOf(selections[d]) !== -1; }); }); } function formatPrice(amount, currency) { if (!amount) return ''; try { return new Intl.NumberFormat(undefined, { style: 'currency', currency: currency || 'USD' }).format(amount); } catch(e) { return '$' + parseFloat(amount).toFixed(2); } } function renderDropdown(dim) { var input = document.querySelector('input[data-dim="' + dim + '"]'); var ul = document.querySelector('.cf-dropdown[data-dim="' + dim + '"]'); if (!input || !ul) return; var opts = getOptions(dim); var query = input.value.trim().toLowerCase(); var effectiveQuery = (query && query !== (selections[dim] || '').toLowerCase()) ? query : ''; var filtered = effectiveQuery ? opts.filter(function(o) { return o.toLowerCase().indexOf(effectiveQuery) !== -1; }) : opts; ul.innerHTML = ''; if (selections[dim]) { var li = document.createElement('li'); li.className = 'clear-item'; li.textContent = '— Clear selection —'; li.addEventListener('mousedown', function(e) { e.preventDefault(); selections[dim] = ''; input.value = ''; input.classList.remove('has-value'); updateAll(); }); ul.appendChild(li); } if (filtered.length === 0) { var li2 = document.createElement('li'); li2.className = 'no-match'; li2.textContent = effectiveQuery ? 'No matches' : 'No options available'; ul.appendChild(li2); } else { filtered.forEach(function(opt) { var li3 = document.createElement('li'); li3.textContent = opt; if (opt === selections[dim]) li3.classList.add('selected'); li3.addEventListener('mousedown', function(e) { e.preventDefault(); selections[dim] = opt; input.value = opt; input.classList.add('has-value'); ul.classList.remove('open'); updateAll(); }); ul.appendChild(li3); }); } } function renderResults() { var matched = getMatched(); var total = matched.length; var totalPages = Math.max(1, Math.ceil(total / PER_PAGE)); if (currentPage > totalPages) currentPage = 1; var paged = matched.slice((currentPage - 1) * PER_PAGE, currentPage * PER_PAGE); document.getElementById('cf-count').textContent = total + ' product' + (total !== 1 ? 's' : '') + ' matched'; var grid = document.getElementById('cf-grid'); if (paged.length === 0) { grid.innerHTML = '
              No products match your selection. Try adjusting your filters.
              '; } else { var html = ''; paged.forEach(function(p) { var imgHtml = p.imageUrl ? '' + (p.imageAlt || '') + '' : '
              📦
              '; html += '
              ' + imgHtml + '
              ' + '

              ' + p.title + '

              ' + '

              ' + formatPrice(p.price, p.currency) + '

              ' + 'View Product' + '
              '; }); grid.innerHTML = html; } var pag = document.getElementById('cf-pagination'); if (totalPages <= 1) { pag.innerHTML = ''; return; } var pagHtml = ''; for (var i = 1; i <= totalPages; i++) { pagHtml += ''; } pag.innerHTML = pagHtml; pag.querySelectorAll('button').forEach(function(btn) { btn.addEventListener('click', function() { currentPage = parseInt(btn.dataset.page); renderResults(); document.getElementById('chain-finder').scrollIntoView({ behavior: 'smooth', block: 'start' }); }); }); } function updateAll() { Object.keys(selections).forEach(function(dim) { if (selections[dim] && getOptions(dim).indexOf(selections[dim]) === -1) { selections[dim] = ''; var inp = document.querySelector('input[data-dim="' + dim + '"]'); if (inp) { inp.value = ''; inp.classList.remove('has-value'); } } }); Object.keys(selections).forEach(renderDropdown); currentPage = 1; renderResults(); } function setupCombobox(dim) { var input = document.querySelector('input[data-dim="' + dim + '"]'); var ul = document.querySelector('.cf-dropdown[data-dim="' + dim + '"]'); if (!input || !ul) return; input.addEventListener('focus', function() { renderDropdown(dim); ul.classList.add('open'); }); input.addEventListener('blur', function() { setTimeout(function() { ul.classList.remove('open'); }, 180); }); input.addEventListener('input', function() { renderDropdown(dim); ul.classList.add('open'); if (input.value === '') { selections[dim] = ''; input.classList.remove('has-value'); updateAll(); } }); } document.getElementById('cf-reset').addEventListener('click', function() { Object.keys(selections).forEach(function(d) { selections[d] = ''; var inp = document.querySelector('input[data-dim="' + d + '"]'); if (inp) { inp.value = ''; inp.classList.remove('has-value'); } }); currentPage = 1; updateAll(); }); fetchAllProducts().then(function(products) { allProducts = products; document.getElementById('cf-loading').style.display = 'none'; Object.keys(selections).forEach(setupCombobox); updateAll(); }).catch(function(err) { document.getElementById('cf-loading').textContent = 'Failed to load products. Please refresh the page.'; console.error('Chain Finder error:', err); }); })();