What's your biggest current challenge? Have your say in Community Polls along the right column.

Javascript localStorage not the same for desktop as phone

Javascript localStorage not the same for desktop as phone

TrendBlend
Trailblazer
245 0 29

Hello, I got this script for displaying random numbers. Debug URL: Controllable LED Curtain – TrendBlend

 

<script>
    // Configurations for different products
    const productConfigs = {
        "VibeSync LED": {
            productNum: 0,
            minSold: 3,
            maxSold: 9,
            minViews: 4,
            maxViews: 16,
        },
        "Aansluitbare Glazenspoeler": {
            productNum: 1,
            minSold: 0,
            maxSold: 2,
            minViews: 1,
            maxViews: 3,
        },
        "Bierkoelstokken - Roestvrijstaal": {
            productNum: 2,
            minSold: 1,
            maxSold: 5,
            minViews: 3,
            maxViews: 10,
        }
    };

    // Helper function to calculate sold count with some randomization
    function soldCalculator(current, minSold, maxSold) {
        let randomNumber = Math.floor(Math.random() * 2) + 1;
        if (current >= minSold && current <= maxSold) {
            return randomNumber === 1 ? current + 1 : current - 1;
        }
        return current <= minSold ? current + 1 : current - 1;
    }

    // Helper function to calculate view count with varied random increments
    function viewsCalculator(current, minViews, maxViews) {
        let randomNumber = Math.floor(Math.random() * 100) + 1;
        let change = 0;
        if (randomNumber <= 5) change = 3;
        else if (randomNumber <= 15) change = 2;
        else if (randomNumber <= 45) change = 1;
        else if (randomNumber > 55 && randomNumber <= 60) change = -3;
        else if (randomNumber > 60 && randomNumber <= 70) change = -2;
        else if (randomNumber > 70) change = -1;

        const newCount = current + change;
        return newCount < 0 ? current : newCount;  // Prevent negative view count
    }

    // Initialize counters for a product based on config
    function initializeProductCounters(config) {
        const { productNum, minSold, maxSold, minViews, maxViews, form, mobileForm } = config;

        // Check if counters already exist in localStorage
        let soldCount = parseInt(localStorage.getItem(`soldCount${productNum}`));
        let viewCount = parseInt(localStorage.getItem(`viewCount${productNum}`));

        // If no counters exist, generate random values and store them in localStorage
        if (isNaN(soldCount)) {
            soldCount = Math.floor(Math.random() * (maxSold - minSold + 1)) + minSold;
            localStorage.setItem(`soldCount${productNum}`, soldCount);
        }

        if (isNaN(viewCount)) {
            viewCount = Math.floor(Math.random() * (maxViews - minViews + 1)) + minViews;
            localStorage.setItem(`viewCount${productNum}`, viewCount);
        }

        // Create and append elements for displaying sold and view counts
        const soldCountElement = document.createElement('div');
        soldCountElement.className = 'sold-count shopify-payment-button';
        soldCountElement.style.marginTop = "10px";
        soldCountElement.innerText = `️️ ${soldCount} verkocht in de laatste 24 uur.`;

        const viewCountElement = document.createElement('div');
        viewCountElement.className = 'view-count shopify-payment-button';
        viewCountElement.style.marginBottom = "20px";
        viewCountElement.innerText = `️️ ${viewCount} mensen kijken nu naar dit product.`;

        // Append the elements to the form and mobileForm
        form.appendChild(soldCountElement);
        mobileForm.appendChild(viewCountElement);

        // Function to synchronize updates
        function updateCounts() {
            // Update sold and view counts
            soldCount = soldCalculator(soldCount, minSold, maxSold);
            viewCount = viewsCalculator(viewCount, minViews, maxViews);

            // Update the numbers in localStorage
            localStorage.setItem(`soldCount${productNum}`, soldCount);
            localStorage.setItem(`viewCount${productNum}`, viewCount);

            // Update the displayed counts on both desktop and mobile
            soldCountElement.innerText = `️️ ${soldCount} verkocht in de laatste 24 uur.`;
            viewCountElement.innerText = `️️ ${viewCount} mensen kijken nu naar dit product.`;
        }

        // Listen for changes in localStorage to sync across devices
        window.addEventListener('storage', function(event) {
            if (event.key === `soldCount${productNum}` || event.key === `viewCount${productNum}`) {
                // Fetch the updated values from localStorage
                soldCount = parseInt(localStorage.getItem(`soldCount${productNum}`));
                viewCount = parseInt(localStorage.getItem(`viewCount${productNum}`));

                // Update the displayed numbers on both devices
                soldCountElement.innerText = `️️ ${soldCount} verkocht in de laatste 24 uur.`;
                viewCountElement.innerText = `️️ ${viewCount} mensen kijken nu naar dit product.`;
            }
        });

        // Set interval to update the numbers periodically (every 3 seconds for this example)
        setInterval(updateCounts, 3000);
    }

    document.addEventListener('DOMContentLoaded', function () {
        const form = document.querySelector('product-info .no-js-hidden');
        const mobileForm = document.querySelector('product-info .price_mobile_col');
        const productTitle = '{{ product.title }}';

        if (productConfigs[productTitle]) {
            const config = { ...productConfigs[productTitle], form, mobileForm };
            initializeProductCounters(config);
        }

        // Copy counter elements to desktop view
        const soldCountDiv = document.querySelector('.sold-count');
        const viewCountDiv = document.querySelector('.view-count');
        const soldCountHTML = soldCountDiv ? soldCountDiv.outerHTML : '';
        const viewCountHTML = viewCountDiv ? viewCountDiv.outerHTML : '';
        const combinedHTML = soldCountHTML + viewCountHTML;

        const priceDesktopColDiv = document.querySelector('.price_desktop_col');
        const containerDiv = document.createElement('div');
        containerDiv.innerHTML = combinedHTML;

        if (priceDesktopColDiv) {
            priceDesktopColDiv.insertAdjacentElement('afterend', containerDiv);
        }
    });
</script>

 

I added it to my main-product.liquid but I am facing a problem. The localStorage appear different from mobile than desktop. And I'm also having another problem, the numbers update on phone. But the numbers only update on desktop after refreshing, so not when the number is actually updated (after 3000ms)

Replies 5 (5)

iffikhan30
Shopify Partner
291 37 53

Hello @TrendBlend ,

 

Javascript is client side language, its run when page load.

Custom theme and app [remix] expert.

Email: irfan.sarwar.khan30@gmail.com
Chat on WhatsApp
TrendBlend
Trailblazer
245 0 29

Okay, thanks for your reaction, so it is not really possible to store the data in like a map and update the map every x seconds/minutes to always show the same number to different users/devices? And if it is not, do you maybe know why the numbers are not changing on desktop, but are changing on phone for this code?
Kind regards,
Stef

iffikhan30
Shopify Partner
291 37 53

You are not a good explainer please explain me in detail actually what you want to do? secondly if you have any referance link kindly share.

Custom theme and app [remix] expert.

Email: irfan.sarwar.khan30@gmail.com
Chat on WhatsApp
TrendBlend
Trailblazer
245 0 29

Hello @iffikhan30 ,

I want to show a random number for units sold in the last 24 hours and how many people are looking at the product right now. This number has to stay between the minimum and maximum which is settled with this code:

minSold: 3, maxSold: 9, minViews: 4, maxViews: 16, for example. So for this code something like this would show:

5 sold in the last 24 hours.

12 people are looking at this product right now.

currently I am using localstorage which shows other numbers to different people at the same time. But also has the issue that when the same person looks on mobile the code outputs different numbers than when he looks on desktop. This would mean that he sees 3 units sold on mobile and 8 units sold on desktop AT THE SAME TIME. This is a problem, because the number should always show the same at a time. So for desktop and mobile the number should both show 3 units sold in the last 24 hours, but this number should be able to change (which is what the interval does). This does not only need to work for different devices but also for different users. So when one user is seeing 3 units sold, it should not be possible that another user sees 5 units sold at the same time. So the random numbers have to update at the same time for everyone, and not xx seconds (or minutes) after the code is being executed per person. Viewcount uses the same principes as soldcount. I hope this explains well, and you can help me with this.

Kind regards,

Stef

 

iffikhan30
Shopify Partner
291 37 53

Hello @TrendBlend ,

 

understand your concerns, First think you don;t need to add localstorage because this sold items, max and min, Just add the javascript code simple so all screens show same even mobile and desktop, I pretty sure this count not come to the admin panel. use code,

 

<script>
document.addEventListener('DOMContentLoaded', function () {
    var minViews = 2;
    var maxViews = 20;
    var minSold = 10;
    var maxSold = 100;

    var viewText = 'people are viewing this product right now.';
    var soldText = 'sold in the last 22 hours';
    
    var viewCountElement = document.createElement('div');
    viewCountElement.className = 'view-count shopify-payment-button';
    viewCountElement.innerText = Math.floor(Math.random() * (maxViews - minViews) + minViews) + ' ' + viewText;

    var soldCountElement =  document.createElement('div');
    soldCountElement.className = 'sold-count shopify-payment-button';
    soldCountElement.innerText = Math.floor(Math.random() * (maxSold - minSold) + minSold) + ' ' + soldText;

    var form = document.querySelector('product-info');
    form.appendChild(viewCountElement);
    form.appendChild(soldCountElement);
});
</script>
Custom theme and app [remix] expert.

Email: irfan.sarwar.khan30@gmail.com
Chat on WhatsApp