Announcement

Collapse
No announcement yet.

Shadows ReadyTheme, Add To Cart On CTGY Trigger Ajax Add To Cart

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Shadows ReadyTheme, Add To Cart On CTGY Trigger Ajax Add To Cart

    As the title reads, anyone have a quick hit process for enabling the ajax add to cart button on the CTGY page within the Shadows theme? I have it set so it's triggering, but it's erroring out. Can't figure out the right medley of settings with all the moving parts. So if anyone abroad or at Miva has a quick hit how to, that would be pretty awesome for me so I don't have to hurt my brain figuring it out.
    Ted Hust
    AarcMediaGroup.com

    Celebrating 13 Years of Outstanding Service & Support
    Miva Merchant Design

    #2
    As far as I'm aware there isn't an easy out of the box solution. I've implemented this functionality on a couple of sites made with Shadows... It requires editing a few templates and a separate script for the CTGY page. I also like to update the cart via AJAX on page load, and upon clicking the cart button – so it incorporates that as well. None of the Readythemes update the cart after a user uses the back button, which is a major problem with Chromium browsers.

    Honestly, you might try posting this on the Shadows forum first. Hopefully, Matt can chime in with a solution / add this functionality to the core theme. Otherwise, shoot me a message and I'll try to walk you through it via email.

    You can see an example of this working here:
    https://www.christmastraditions.com/...ra-schoch.html

    -Ryan

    Comment


      #3
      I'm tagging in on this - I've been trying to get something like this working for quite some time now, but for different ReadyThemes (Trying to get it working in Colossus here ). Ryan, I might be reaching out too.
      Leslie Kirk
      Miva Certified Developer
      Miva Merchant Specialist since 1997
      Previously of Webs Your Way
      (aka Leslie Nord leslienord)

      Email me: [email protected]
      www.lesliekirk.com

      Follow me: Twitter | Facebook | FourSquare | Pinterest | Flickr

      Comment


        #4
        The default ajax-add-to-cart function is designed to be used on a page with a single product add form. I do have extension for other ways to use it in the works [ https://github.com/mivaecommerce/Extensions/projects/1 ]. Here is a possible framework you can use to start building your own function for the category page. It is completely untested and may blow-up.
        Code:
        (function (window, document, undefined) {
            'use strict';
        
            let purchaseForms = document.querySelectorAll('[data-hook="purchase"]');
            let responseMessage = document.querySelector('[data-hook="purchase-message"]');
            let miniBasketCount = document.querySelectorAll('[data-hook~="mini-basket-count"]');
            let miniBasketAmount = document.querySelectorAll('[data-hook~="mini-basket-amount"]');
        
            Array.from(purchaseForms).forEach(function (purchaseForm) {
                purchaseForm.addEventListener('submit', function (evt) {
                    let purchaseButton = purchaseForm.querySelector('[data-hook="add-to-cart"]');
                    let purchaseButtonText = (purchaseButton.nodeName.toLowerCase() === 'input') ? purchaseButton.value : purchaseButton.textContent;
                    let purchaseFormActionInput = purchaseForm.querySelector('input[name="Action"]');
        
                    if (purchaseFormActionInput.value !== 'ADPR') {
                        return;
                    }
        
                    evt.preventDefault();
                    evt.stopImmediatePropagation();
        
                    purchaseForm.action = purchaseButton.getAttribute('data-action');
                    purchaseFormActionInput.value = 'ADPR';
        
                    let data = new FormData(purchaseForm);
                    let request = new XMLHttpRequest(); // Set up our HTTP request
        
                    purchaseForm.setAttribute('data-status', 'idle');
        
                    if (purchaseForm.getAttribute('data-status') !== 'submitting') {
                        purchaseForm.setAttribute('data-status', 'submitting');
                        purchaseButton.setAttribute('disabled', 'disabled');
        
                        if (purchaseButton.nodeName.toLowerCase() === 'input') {
                            purchaseButton.value = 'Processing...';
                        }
                        else{
                            purchaseButton.textContent = 'Processing...';
                        }
        
                        responseMessage.innerHTML = '';
        
                        // Setup our listener to process completed requests
                        request.onreadystatechange = function () {
                            // Only run if the request is complete
                            if (request.readyState !== 4) {
                                return;
                            }
        
                            // Process our return data
                            if (request.status === 200) {
                                // What do when the request is successful
                                let response = request.response;
        
                                if (response.body.id === 'js-BASK') {
                                    let basketData = response.querySelector('[data-hook="mini-basket"]');
                                    let basketCount = basketData.getAttribute('data-item-count');
                                    let basketSubtotal = basketData.getAttribute('data-subtotal');
        
                                    if (miniBasketCount) {
                                        for (let mbcID = 0; mbcID < miniBasketCount.length; mbcID++) {
                                            miniBasketCount[mbcID].textContent = basketCount; // Update mini-basket quantity (display only)
                                        }
                                    }
        
                                    if (miniBasketAmount) {
                                        for (let mbaID = 0; mbaID < miniBasketAmount.length; mbaID++) {
                                            miniBasketAmount[mbaID].textContent = basketSubtotal; // Update mini-basket subtotal (display only)
                                        }
                                    }
        
                                    if (typeof miniBasket !== 'undefined') {
                                        document.querySelector('[data-hook="mini-basket"]').innerHTML = response.querySelector('[data-hook="mini-basket"]').innerHTML;
        
                                        setTimeout(function () {
                                            document.querySelector('[data-hook="open-mini-basket"]').click();
                                        }, 100);
                                    }
                                    else {
                                        responseMessage.innerHTML = '<div class="x-messages x-messages--success"><span class="u-icon-check"></span> Added to cart.</div>';
                                    }
        
                                    // Re-Initialize Attribute Machine (if it is active)
                                    if (typeof attrMachCall !== 'undefined') {
                                        attrMachCall.Initialize();
                                    }
                                }
                                else if(response.body.id === 'js-PATR') {
                                    let findRequired = purchaseForm.querySelectorAll('.is-required');
                                    let missingAttributes = [];
        
                                    for (let id = 0; id < findRequired.length; id++) {
                                        missingAttributes.push(' ' + findRequired[id].title);
                                    }
        
                                    responseMessage.innerHTML = '<div class="x-messages x-messages--warning">All <em class="u-color-red">Required</em> options have not been selected.<br />Please review the following options: <span class="u-color-red">' + missingAttributes + '</span>.</div>';
                                }
                                else if(response.body.id === 'js-PLMT') {
                                    responseMessage.innerHTML = '<div class="x-messages x-messages--warning">We do not have enough of the combination you have selected.<br />Please adjust your quantity.</div>';
                                }
                                else if(response.body.id === 'js-POUT') {
                                    responseMessage.innerHTML = '<div class="x-messages x-messages--warning">The combination you have selected is out of stock.<br />Please review your options or check back later.</div>';
                                }
                                else {
                                    responseMessage.innerHTML = '<div class="x-messages x-messages--warning">Please review your selection.</div>';
                                }
        
                                // Reset button text and form status
                                purchaseButton.removeAttribute('disabled');
        
                                if (purchaseButton.nodeName.toLowerCase() === 'input') {
                                    purchaseButton.value = purchaseButtonText;
                                }
                                else{
                                    purchaseButton.textContent = purchaseButtonText;
                                }
        
                                purchaseForm.setAttribute('data-status', 'idle');
                            }
                            else {
                                // What do when the request fails
                                console.log('The request failed!');
                                purchaseForm.setAttribute('data-status', 'idle');
                            }
                        };
        
                        /**
                         * Create and send a request
                         * The first argument is the post type (GET, POST, PUT, DELETE, etc.)
                         * The second argument is the endpoint URL
                         */
                        request.open(purchaseForm.method, purchaseForm.action, true);
                        request.responseType = 'document';
                        request.send(data);
                    }
                }, false);
            });
        
        })(window, document);
        Matt Zimmermann
        Front-End Development Director / Miva, Inc.

        Comment


          #5
          Thanks for the link Matt! Good resource to have.

          Comment


            #6
            So color me clueless here. (I was going to go back to one of my other posts on this but since this page has a coding example I'll muddy up this thread).

            With regard to Shadows 1.0 and the theme.js file

            Code:
            jsCTGY: function() {
            },
            jsPROD: function() {
            /**
            * Load and initialize the Quantify extension
            */
            $.loadScript(theme_path + 'extensions/quantify/quantify.js');
            
            /**
            * Load and initialize the AJAX Add to Cart extension
            */
            $.loadScript(theme_path + 'extensions/product-layout/ajax-add-to-cart.js');
            
            /**
            * Load and initialize the Roundabout extension
            */
            $.loadScript(theme_path + 'extensions/carousel/roundabout.js', function () {
            $.hook('product-carousel').roundabout({
            group: true,
            groupTiny: 1,
            groupSmall: 1
            });
            });
            },
            Could the jsCTGY function be tweaked to trigger the ajax-add-to-cart.js as it does for the jsPROD? It looks like the code cited is almost the same as the ajax-add-to-cart.js (I do see differences but don't have enough javascript foo to understand).
            Leslie Kirk
            Miva Certified Developer
            Miva Merchant Specialist since 1997
            Previously of Webs Your Way
            (aka Leslie Nord leslienord)

            Email me: [email protected]
            www.lesliekirk.com

            Follow me: Twitter | Facebook | FourSquare | Pinterest | Flickr

            Comment


              #7
              Hi Leslie,

              Unfortunately, the default Ajax Add To Cart function only looks for a single instance of a form and you wouldn't want to load and initialize the script for every form on the page.
              Matt Zimmermann
              Front-End Development Director / Miva, Inc.

              Comment


                #8
                Originally posted by Matt Zimmermann View Post
                Hi Leslie,

                Unfortunately, the default Ajax Add To Cart function only looks for a single instance of a form and you wouldn't want to load and initialize the script for every form on the page.
                Thanks for the explanation (that makes sense to me). I know you've added this to the "wish list" - many thanks because I seem to be getting more people who want that Add to Cart back on the screens it was left out of. But not only do they want it back, but they also want the functionality that the Add to Cart button has on the PROD page.
                Leslie Kirk
                Miva Certified Developer
                Miva Merchant Specialist since 1997
                Previously of Webs Your Way
                (aka Leslie Nord leslienord)

                Email me: [email protected]
                www.lesliekirk.com

                Follow me: Twitter | Facebook | FourSquare | Pinterest | Flickr

                Comment

                Working...
                X