Insights & Resources

Blog Posts. Infographics. Case Studies. And so much more. When you’ve spent more than 20 years making lives better, you pick up more than a little industry intuition.

Browse All Resources

/* ========================================= SEARCH ICON ========================================= */ .search-icon { position: absolute; left: 24px; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; pointer-events: none; } /* SVG / IMG */ .search-icon img { width: 24px; height: 24px; object-fit: contain; } /* Font Awesome Icon */ .search-icon i { font-size: 20px; color: #5C5F7A; }
<!----> <!-- Search--> <!----> <!---->
(function(){ const form = document.getElementById('insights-search-form'); const input = document.getElementById('insight-search'); if(!form || !input) return; /* ---------------------------- Restore value from URL ---------------------------- */ const params = new URLSearchParams(window.location.search); input.value = params.get('search') || ''; /* ---------------------------- Submit Search ---------------------------- */ function submitSearch() { const url = new URL(window.location.href); // Reset Elementor pagination in the URL path url.pathname = url.pathname .replace(/\/page\/\d+\/$/, "/") .replace(/\/\d+\/$/, "/"); const value = input.value.trim(); if (value) { url.searchParams.set("search", value); } else { url.searchParams.delete("search"); } // Remove any pagination query params too url.searchParams.delete("paged"); for (const key of [...url.searchParams.keys()]) { if (key.startsWith("e-page-")) { url.searchParams.delete(key); } } window.location.assign(url.toString()); } /* ---------------------------- ENTER / BUTTON ---------------------------- */ form.addEventListener( 'submit', function(e){ e.preventDefault(); submitSearch(); } ); })();
.selected-filters{ margin-top: 40px; display: flex; flex-wrap: wrap; } .selected-filters button { padding: 0px; border: none; color: #307FE2; font-weight: 600; margin: 0px 5px; } .selected-filters button:hover { background-color: transparent; } .selected-filters .filter-chip{ border:1.5px solid #3E83A5; padding: 9px 12px; color: #307FE2; font-size: 18px; margin-right: 10px; display: flex; align-items: baseline; } .selected-filters .filter-chip p{ margin: 0; line-height: 15px; } @media (max-width:1024px){ .selected-filters .filter-chip{ line-height: 0px; font-size: 14px; margin-bottom: 10px; } .selected-filters{ margin-bottom: 20px; } } @media (max-width:767px){ .selected-filters .filter-chip{ padding: 6px 4px; } } (function(){ const container = document.getElementById( 'selected-filters' ); if(!container) return; /* ---------------------------- Read State ---------------------------- */ function getState(){ const params = new URLSearchParams( window.location.search ); const search = params.get('search') || ''; let tax = []; for( const [key,value] of params.entries() ){ if( key.startsWith( 'e-filter-' ) && value ){ value .split(/[\s~]+/) .forEach(v=>{ if(!v) return; tax.push({ slug:v, label: v .replaceAll( '-', ' ' ) .replace( /\b\w/g, c=>c.toUpperCase() ) }); }); } } return { search, tax }; } /* ---------------------------- Render ---------------------------- */ function render(){ const state = getState(); container.innerHTML = ''; /* Search */ if( state.search ){ container.innerHTML += `

Search: ${state.search}

`; } /* Taxonomy */ state.tax.forEach( term=>{ container.innerHTML += `

${term.label}

`; } ); /* Clear All */ if ( state.search || state.tax.length ) { container.innerHTML += `

Clear All

`; } bindEvents(); } /* ---------------------------- Remove ---------------------------- */ function removeFilter( type, value ){ const url = new URL( window.location.href ); /* Search */ if( type === 'search' ){ url.searchParams.delete( 'search' ); } /* Taxonomy */ if( type === 'tax' ){ for( const key of [ ...url.searchParams.keys() ] ){ if( key.startsWith( 'e-filter-' ) ){ let values = url .searchParams .get(key) .split(/[\s~]+/) .filter(Boolean); values = values.filter( v => v !== value ); if( values.length ){ url .searchParams .set( key, values.join(' ') ); }else{ url .searchParams .delete( key ); } } } } /* Clear All */ if ( type === 'clear-all' ) { url.searchParams.delete( 'search' ); for ( const key of [...url.searchParams.keys()] ) { if ( key.startsWith( 'e-filter-' ) ) { url.searchParams.delete( key ); } } url.searchParams.delete( 'paged' ); url.searchParams.delete( 'e-page-0f1679e' ); window.location.assign( url.toString() ); return; } /* Reset pagination */ url.searchParams.delete( 'paged' ); url.searchParams.delete( 'e-page-0f1679e' ); /* Reload */ window.location.assign( url.toString() ); } /* ---------------------------- Events ---------------------------- */ function bindEvents(){ container .querySelectorAll( 'button' ) .forEach( btn=>{ btn.onclick = function(){ removeFilter( this.dataset.type, this.dataset.value ); }; } ); } /* ---------------------------- Initial ---------------------------- */ render(); /* ---------------------------- Detect URL changes ---------------------------- */ (function(){ const push = history.pushState; const replace = history.replaceState; history.pushState = function(){ push.apply( this, arguments ); window.dispatchEvent( new Event( 'urlchange' ) ); }; history.replaceState = function(){ replace.apply( this, arguments ); window.dispatchEvent( new Event( 'urlchange' ) ); }; window.addEventListener( 'popstate', render ); window.addEventListener( 'urlchange', render ); })(); })();
(function () { let initialized = false; let lastState = ""; let isBuilding = false; /* ================================ GET PAGINATION ================================ */ function getPagination() { return document.querySelector( ".elementor-pagination" ); } /* ================================ GET CURRENT PAGE ================================ */ function getCurrentPage(pagination) { const current = pagination.querySelector( "[aria-current='page']" ); if (!current) return 1; return parseInt( current.textContent.replace(/\D/g, ""), 10 ) || 1; } /* ================================ GET TOTAL PAGES Only from visible pagination links — NOT data-max-page because that value is wrong ================================ */ function getTotalPages(pagination) { let maxFound = 1; pagination.querySelectorAll(".page-numbers").forEach(function (el) { if ( el.classList.contains("prev") || el.classList.contains("next") || el.classList.contains("first-page") || el.classList.contains("last-page") || el.classList.contains("dots") || el.classList.contains("current") ) { return; } const num = parseInt(el.textContent.replace(/\D/g, ""), 10); if (!isNaN(num) && num > maxFound) { maxFound = num; } }); return maxFound; } /* ================================ GET E-PAGE KEY ================================ */ function getEPageKey() { /* From current URL */ const params = new URLSearchParams( window.location.search ); for (const key of params.keys()) { if (key.startsWith('e-page-')) { return key; } } /* From pagination links */ const pagination = getPagination(); if (pagination) { const links = pagination.querySelectorAll( "a.page-numbers" ); for (const link of links) { try { const url = new URL(link.href); for ( const key of url.searchParams.keys() ) { if (key.startsWith('e-page-')) { return key; } } } catch (e) { } } } /* From anchor next page */ const anchor = document.querySelector( ".e-load-more-anchor" ); if (anchor) { const nextUrl = anchor.getAttribute('data-next-page') || ''; try { const url = new URL(nextUrl); for ( const key of url.searchParams.keys() ) { if (key.startsWith('e-page-')) { return key; } } } catch (e) { } } return null; } /* ================================ BUILD URL FOR PAGE NUMBER ================================ */ function buildPageURL(pageNumber) { const pagination = getPagination(); if (pagination) { // Page 1 if (pageNumber === 1) { const firstLink = [...pagination.querySelectorAll("a.page-numbers")] .find(a => { const n = parseInt(a.textContent.replace(/\D/g, ""), 10); return n === 1; }); if (firstLink) { return firstLink.href; } } // Last page let lastLink = null; let max = 1; pagination.querySelectorAll("a.page-numbers").forEach(function(a) { const n = parseInt(a.textContent.replace(/\D/g, ""), 10); if (!isNaN(n) && n >= max) { max = n; lastLink = a; } }); if (pageNumber === max && lastLink) { return lastLink.href; } } // Fallback (works even if links aren't available) const url = new URL(window.location.href); let path = url.pathname; path = path.replace(/\/\d+\/?$/, "/"); if (!path.endsWith("/")) { path += "/"; } if (pageNumber > 1) { path += pageNumber + "/"; } url.pathname = path; return url.toString(); } /* ================================ REBUILD BUTTONS Disconnect observer before modifying DOM to prevent infinite loop ================================ */ let observer = null; function rebuildButtons() { /* Prevent re-entry */ if (isBuilding) return; const pagination = getPagination(); if (!pagination) return; const currentPage = getCurrentPage( pagination ); const totalPages = getTotalPages(pagination); const stateKey = currentPage + "|" + totalPages; /* Skip if nothing changed */ if (stateKey === lastState) return; lastState = stateKey; isBuilding = true; /* ============================ DISCONNECT OBSERVER before touching DOM to prevent infinite loop ============================ */ if (observer) { observer.disconnect(); } /* Remove old buttons */ pagination.querySelector( ".first-page" )?.remove(); pagination.querySelector( ".last-page" )?.remove(); /* Skip if only 1 page */ if (totalPages >= 2) { /* FIRST button */ const isFirstDisabled = currentPage = totalPages; let lastBtn; if (isLastDisabled) { lastBtn = document.createElement("span"); lastBtn.className = "page-numbers last-page"; } else { lastBtn = document.createElement("a"); lastBtn.href = buildPageURL(totalPages); lastBtn.className = "page-numbers last-page"; } pagination.prepend(firstBtn); pagination.appendChild(lastBtn); } isBuilding = false; /* ============================ RECONNECT OBSERVER after DOM changes done ============================ */ if (observer) { reconnectObserver(); } } /* ================================ SCROLL TO GRID ================================ */ function scrollToGrid() { const grid = document.querySelector( ".custom-pagination-grid, " + ".insights-loop-grid, " + ".elementor-widget-loop-grid, " + "[data-widget_type='loop-grid.post']" ); if (!grid) return; const header = document.querySelector( "header, " + ".site-header, " + ".elementor-location-header, " + "[data-elementor-type='header']" ); window.scrollTo({ top: grid.getBoundingClientRect().top + window.pageYOffset - (header ? header.offsetHeight : 80) - 20, behavior: "smooth" }); } /* ================================ SETUP MUTATION OBSERVER ================================ */ let observerTarget = null; let debounceTimer = null; function reconnectObserver() { if (!observerTarget) return; observer.observe(observerTarget, { childList: true, subtree: true }); } function setupObserver() { observerTarget = document.querySelector( ".elementor-widget-loop-grid, " + ".custom-pagination-grid, " + "[data-widget_type='loop-grid.post']" ); if (!observerTarget) return; observer = new MutationObserver( function (mutations) { /* Skip if we are building */ if (isBuilding) return; /* Check if mutations are from our own button changes */ let relevantChange = false; for (const mutation of mutations) { for (const node of mutation.addedNodes) { if ( node.nodeType !== 1 ) continue; /* Skip our own buttons */ if ( node.classList && ( node.classList.contains( 'first-page' ) || node.classList.contains( 'last-page' ) ) ) continue; /* This is a real change from Elementor AJAX */ relevantChange = true; break; } if (relevantChange) break; for ( const node of mutation.removedNodes ) { if (node.nodeType !== 1) continue; /* Skip removals of our buttons */ if ( node.classList && ( node.classList.contains( 'first-page' ) || node.classList.contains( 'last-page' ) ) ) continue; relevantChange = true; break; } if (relevantChange) break; } if (!relevantChange) return; /* Debounce the rebuild */ clearTimeout(debounceTimer); debounceTimer = setTimeout( function () { lastState = ""; rebuildButtons(); }, 400 ); } ); reconnectObserver(); } /* ================================ INITIALIZE ================================ */ function init() { if (initialized) return; initialized = true; /* Initial build */ rebuildButtons(); /* Setup observer */ setupObserver(); /* ============================ CLICK HANDLER ============================ */ document.addEventListener( "click", function (e) { const link = e.target.closest( ".elementor-pagination a" ); if (!link) return; lastState = ""; setTimeout(function () { rebuildButtons(); scrollToGrid(); }, 800); } ); /* ============================ ONE-TIME POLL Short window only on load Stop after 5 seconds ============================ */ let pollCount = 0; const poll = setInterval(function () { pollCount++; if (pollCount >= 6) { clearInterval(poll); return; } if (!isBuilding) { rebuildButtons(); } }, 1000); } window.addEventListener("load", init); })();

A Global CX Leader That Deliver

Growth gets easier with the right partner behind you. Let's map out what real partnership can do for you.

Form Photo

Learn More About A Global CX Leader

Find out how our unified commerce approach can help you reduce complexity, increase loyalty, and scale smarter, both online and in-store.

Insights and Newsroom Landing Page

"*" indicates required fields

This field is for validation purposes and should be left unchanged.

By clicking below, you consent to us contacting you directly, and to the collection, storage, and use of your personal information as more fully described in our privacy policy.

Let’s Get Started.

Curious how far the right BPO partner can take your business?