PageSourceSearch

https://www.3chi.com/wp-content/plugins/3c-woo-loop-select-variati…/js/3c-wc-loop-select-variations.js?ver=1.1

js 3chi.com collected 2026-09-25 23:51:41 UTC 7,911 bytes, 143 lines download raw bytes

1jQuery( function( $ ) {
2
3    // Define function to bind variation select handlers
4    function bindVariationSelectHandlers() {
5        
6        $( '.products, .related-products-wrapper' ).on( 'change', '.svatc-variation-select select[data-attribute_name]', function(e) {
7
8            const el = $( e.target );
9            const variationsWrapper = el.closest( '.svatc-variations' );
10            const availableVariations = JSON.parse( variationsWrapper.attr( 'data-product_variations' ) );
11            const productWrapper = variationsWrapper.closest( 'div.product' );
12            const button = productWrapper.find( 'a.add_to_cart_button' );
13            const prodName = el.closest( 'div.box-text-products' ).find('a.woocommerce-loop-product__link').text();
14
15            // Create empty object to store matching variations
16            let matchingVariation = {};
17
18            // Loop through all available variations
19            for( let i = 0; i < availableVariations.length; i++ ) {
20                // Assign current variation as our matching variation...we'll check later
21                matchingVariation = availableVariations[i];
22
23                // Check the attributes of this variation
24                for( const [ attr_name, attr_value ] of Object.entries( availableVariations[i].attributes ) ) {
25                    // If the attributes don't match, reset our matchingVariation object
26                    if( attr_value !== variationsWrapper.find( '[name="' + attr_name + '"]' ).val() ) {
27                        matchingVariation = {};
28                    }
29                }
30
31                // If we found a matching variation, exit the loop
32                if( Object.keys( matchingVariation ).length !== 0 ) {
33                    break;
34                }
35            }
36
37            // If we have a matching variation
38            if( Object.keys( matchingVariation ).length !== 0 ) {
39                
40                // If the matching variation is in stock
41                if( matchingVariation.is_in_stock === true ) {
42
43                    if( matchingVariation.variation_id ) {
44                        button.removeClass( 'disabled' ).addClass( 'ajax_add_to_cart' ); // Remove disabled class; add ajax class
45                        button.attr( 'data-product_id', matchingVariation.variation_id ); // Add the variation ID
46                        const newHref = '?add-to-cart=' + matchingVariation.variation_id; // Create new href for ajax add to cart
47                        button.attr( 'href', newHref ); // Set the new href value
48                        button.text( 'ADD TO CART' ); // Change button text
49                        button.attr( 'data-prod_name', prodName ); // Add the product name
50                        button.attr( 'data-product_sku', matchingVariation.sku ); // Add the product sku
51                    }
52                    productWrapper.find( 'div.out-of-stock-label' ).remove(); // Remove the out of stock label
53        
54                } else { // If variation is out of stock
55                    button.removeClass( 'ajax_add_to_cart' ).addClass( 'disabled' ); // Remove ajax class; add disabled class
56                    button.text( 'OUT OF STOCK' ); // Change button text
57                    button.removeAttr( 'data-product_id' ); // Remove the variation ID
58                    button.removeAttr( 'href' ); // Remove the href
59                    button.removeAttr( 'data-prod_name' ); // Remove the product name
60                    button.removeAttr( 'data-product_sku' ); // Remove the product sku
61                    button.removeAttr( 'data-prod_price' ); // Remove the product price
62        
63                    // If the out of stock label does not already exist, add it
64                    if( ! productWrapper.find( 'div.out-of-stock-label' ).length ) {
65                        const oos_overlay = "<div class='out-of-stock-label'>OUT OF STOCK</div>";
66                        productWrapper.find( 'div.box-image' ).append( oos_overlay );
67                    }
68                }
69        
70                // Update variation price
71                if( matchingVariation.price_html ) {
72                    productWrapper.find( 'span.price' ).replaceWith( matchingVariation.price_html );
73                }
74
75                // Add price to ATC button
76                const prodPrice = productWrapper.find( 'span.price' ).text().substring(1);
77                button.attr( 'data-prod_price', prodPrice ); // Add the product price to the button
78        
79                // Update variation image
80                if( matchingVariation.image ) {
81                    productWrapper.find( 'img' ).attr( {
82                        src: matchingVariation.image.src,
83                        srcset: matchingVariation.image.srcset,
84                        width: matchingVariation.image.src_w,
85                        height: matchingVariation.image.src_h
86                    } );
87                }
88            } else { // If there is no matching variation
89                button.removeClass( 'ajax_add_to_cart' ).addClass( 'disabled' ); // Remove ajax class; add disabled class
90                button.text( 'ADD TO CART' ); // Change button text
91                button.removeAttr( 'data-product_id' ); // Remove the variation ID
92                button.removeAttr( 'href' ); // Remove the href
93                button.removeAttr( 'data-prod_name' ); // Remove the product name
94                button.removeAttr( 'data-product_sku' ); // Remove the product sku
95                button.removeAttr( 'data-prod_price' ); // Remove the product price
96
97                // Get the original product price HTML and image, and replace them
98                const orig_prod_attrs = JSON.parse( variationsWrapper.attr( 'data-orig_prod_attrs' ) );
99                productWrapper.find( 'img' ).attr( {
100                    src: orig_prod_attrs.img.src,
101                    srcset: orig_prod_attrs.img.srcset
102                } );
103                productWrapper.find( 'span.price' ).empty().append( orig_prod_attrs.price );
104                
105                // Remove out of stock label if other variations are in stock
106                if( orig_prod_attrs.is_in_stock ) {
107                    productWrapper.find( 'div.out-of-stock-label' ).remove(); 
108                }  
109            }
110        } );
111
112        // Remove the href from disabled add to cart buttons generated on page load
113        $( document ).ready( function() {
114            $( this ).find( 'a.disabled.add_to_cart_button' ).removeAttr( 'href' );
115        } );
116
117        // Remove the href from disabled add to cart buttons that are dynamically generated w/ infinite scroll
118        $( document ).on( 'flatsome-infiniteScroll-append', function() {
119            $( this ).find( 'a.disabled.add_to_cart_button' ).removeAttr( 'href' );
120        } );
121
122        // On add to cart, hide view cart link and keep add to cart button visible
123        $( document.body ).on( 'wc_cart_button_updated', function() {
124            const view_cart_link = $( this ).find( 'a.added_to_cart.wc-forward' );
125            const atc_button = $( this ).find( 'a.add_to_cart_button.ajax_add_to_cart' );
126            view_cart_link.css( 'display', 'none' );
127            atc_button.removeClass ( 'added' );
128        } );
129    }
130
131    // Initial binding of variation select handlers
132    bindVariationSelectHandlers();
133
134    // When product is added to cart on cart page, reset the dropdown and re-bind the handlers
135    $( document.body ).on( 'updated_cart_totals', function() {
136        productDropdowns = $( this ).find( 'div.svatc-variation-select > select' );
137        productDropdowns.each( function() {
138            $( this ).prop( 'selectedIndex', 0 ).change();
139        } );
140        bindVariationSelectHandlers();
141    } );
142
143} );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.