skip to Main Content

I’m trying to make it so that by clicking on an attribute’s photo, I also update the selection in the attribute’s dropdown

In content-single-product.php I added

// get the product variations
    $product_variations = $product->get_available_variations();
    if ( !empty( $product_variations ) ) {
        ?>
    <div class="product-variation-images">
    <?php
    foreach($product_variations as $product_variation) {
        // get the slug of the variation
        $product_attribute_name = $product_variation['attributes'];
        ?>
        <div class="product-variation-image product-variation-<?php echo $product_attribute_name ?>" id="product-variation-<?php echo $product_variation['variation_id']; ?>" data-attribute="<?php echo $product_attribute_name ?>">
        <img src="<?php echo $product_variation['image']['src']; ?>" alt="">

        </div><!-- #product-variation-image -->
    <?php } ?>
    </div>
    <?php } ?>  

Then I added to functions.php

add_action('wp_enqueue_scripts', 'custom_enqueue_scripts');
function custom_enqueue_scripts() {
    if (is_product()) {
        global $product;
        $product = wc_get_product();

        wp_enqueue_script('custom-variation-script', get_template_directory_uri() . '/js/custom-variation-script.js', array('jquery'), '1.0', true);
        wp_localize_script('custom-variation-script', 'wc_single_product_params', array(
            'variations' => $product->get_available_variations()
        ));
    }
}

then in custom-variation-script.js

jQuery(document).ready(function ($) {
    // Klik na sliku atributa
    $('.product-variation-image').on('click', function () {
        var attributeValue = $(this).data('attribute');

        // Pronađi odgovarajuću opciju u dropdownu
        var select = $('select[name^="attribute_' + attributeValue + '"]');
        
        if (select.length) {
            // Postavi vrijednost dropdowna
            select.val(attributeValue);

            // Pokreni događaj za ažuriranje WooCommerce varijacija
            select.trigger('change');
        }
    });
});

But it doesn’t work.. Can someone help me?

I tried several ways but none work’s…


jQuery(document).ready(function ($) {
    // Klik na sliku atributa
    $('.product-variation-image').on('click', function () {
        // Pronađi id varijacije iz data atributa
        var variationId = $(this).attr('id').replace('product-variation-', '');

        // Pronađi odgovarajući dropdown za varijaciju
        var select = $('select.variation_id');

        // Postavi vrijednost dropdowna
        if (select.length) {
            select.val(variationId);

            // Pokreni događaj za ažuriranje WooCommerce varijacija
            select.trigger('change');
        }
    });
});

The attributes for variations in the product are "Color" and "Weight":

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to everyone who tried to help, I managed to solve it like this in the end

    In content-single-product.php

    <?php
    if ($product->is_type('variable')) {
        // get the product variations
        $available_variations = $product->get_available_variations();
        $color_taxonomy = 'pa_color';
        $weight_taxonomy = 'pa_weight';
    
        if (!empty($available_variations)) {
            echo '<div class="product-variation-images">';
    
            foreach ($available_variations as $variation_data) {
                // get the slug of the color variation attribute
                $color_slug = isset($variation_data['attributes']['attribute_' . $color_taxonomy]) ? $variation_data['attributes']['attribute_' . $color_taxonomy] : '';
                $weight_slug = isset($variation_data['attributes']['attribute_' . $weight_taxonomy]) ? $variation_data['attributes']['attribute_' . $weight_taxonomy] : '';
    
                echo '<div class="product-variation-image product-variation-' . $color_slug . '-' . $weight_slug . '" data-color="' . $color_slug . '" data-weight="' . $weight_slug . '">
                    <img src="' . esc_url($variation_data['image']['src']) . '" alt="">
                </div><!-- #product-variation-image -->';
            }
            echo '</div>';
        }
    }
    ?>
    

    Then i added in my child functions.php

    function variable_product_jquery_script()
    {
        global $product;
    
        if ($product->is_type('variable')) {
            $color_taxonomy = 'pa_color';
            $weight_taxonomy = 'pa_weight';
    
            wc_enqueue_js("jQuery(document).ready(function($) {
                $('.product-variation-images').on('click', '.product-variation-image', function () {
                    const colorAttr = $(this).data('color'),
                          weightAttr = $(this).data('weight'),
                          colorSelect = $('select#' + '{$color_taxonomy}'),
                          weightSelect = $('select#' + '{$weight_taxonomy}');
    
                    if (colorSelect.length && weightSelect.length) {
                        // Clear previous weight selection
                        weightSelect.val('').trigger('change');
    
                        // Set new color selection
                        colorSelect.val(colorAttr).trigger('change');
                    }
                });
            });");
        }
    }
    

    Hope this helps someone! @LoicTheAztec Thanks for trying to help me


  2. Updated – There are some mistakes in your code. Try the following replacement instead:

    In template content-single-product.php file:

    if ( $product->is_type('variable') ) {
        // get the product variations
        $available_variations = $product->get_available_variations();
        $taxonomy             = 'pa_color';
        $color_attribute      = $product->get_attribute($taxonomy);
    
        if ( ! empty($available_variations) && ! empty($color_attribute) ) {
            echo '<div class="product-variation-images">';
    
            foreach($available_variations as $variation_data) {
                if( ! isset($variation_data['attributes']['attribute_'.$taxonomy]) ) continue;
    
                // get the slug of the variation attribute
                $term_slug = $variation_data['attributes']['attribute_'.$taxonomy];
    
                echo '<div class="product-variation-image product-variation-'.$term_slug.'" id="product-variation-'.$variation_data['variation_id'].'" data-attribute="'.$term_slug.'">
                    <img src="'.$variation_data['image']['src'].'" alt="">
                </div><!-- #product-variation-image -->';
            }
            echo '</div>';
        }
    }
    

    In your child theme’s functions.php file:

    add_action('woocommerce_single_product_summary', 'variable_product_jquery_script', 5);
    function variable_product_jquery_script() {
        global $product;
    
        if ( $product->is_type('variable') ) {
            $taxonomy = 'pa_color';
    
            wc_enqueue_js("$(document.body).on('click', '.product-variation-image', function () {
                const attrVal = $(this).data('attribute'),
                      select  = $('table.variations select#{$taxonomy}');
                
                if (select.length) {
                    select.val(attrVal).trigger('change');
                }
            });");
        }
    }
    

    Remove the custom-variation-script.js file.

    Tested and works on variable products with 2 attributes set for variations: Only the color attribute generate the variations as the second attribute is set as default (with no selected value).

    Important:

    The code will only work if the variations are generated from the Color attribute.
    It will work if the "Weight" attribute has only one value, or if the "Weight" attribute is set in each variation as "Any" (no selected value).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search