Variation image click change attribute dropdown selected value in WooCommerce

62 views Asked by At

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

There are 2 answers

0
Nemanja Sabo On 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

5
LoicTheAztec On

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).