Skip to content
Advertisement

How to change variation color based on variation stock status in woo commerce?

working on the website built with WordPress + Woocommerce and I’m trying to change the attribute background color on the product page if it is on backorder.

for example, size 4 should have a different background color, because it’s out of stock and available on backorder: see image here

WPC Variation Swatches for WooCommerce by WPClever is used for attributes.

I’m implementing following code in functions.php:

function is_on_backorder() {
    if ( 'onbackorder' === $this->get_stock_status() ) {
        ?>

        <script>
        ( function( $ ) {
            'use strict';
                $( '.wpcvs-term span' ).css("background-color","red");
             ;
        } ( jQuery ) );
    </script>
<?php }
}

This is how HTML looks like:

<div class="wpcvs-terms wpcvs-type-button wpcvs-style-rounded" data-attribute="pa_size">
    <span class="wpcvs-term wpcvs-enabled wpcvs-selected" aria-label="US 4" title="US 4" data-term="us-4">
        <span>US 4</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 4.5" title="US 4.5" data-term="us-4-5">
        <span>US 4.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 5" title="US 5" data-term="us-5">
        <span>US 5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 5.5" title="US 5.5" data-term="us-5-5">
        <span>US 5.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 6" title="US 6" data-term="us-6">
        <span>US 6</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 6.5" title="US 6.5" data-term="us-6-5">
        <span>US 6.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 7" title="US 7" data-term="us-7">
        <span>US 7</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 7.5" title="US 7.5" data-term="us-7-5">
        <span>US 7.5</span>
    </span>
    <span class="wpcvs-term wpcvs-enabled" aria-label="US 8" title="US 8" data-term="us-8">
        <span>US 8</span>
    </span>
</div>

what’s wrong with this code? should I add an action? how?

Advertisement

Answer

First, you have to override the HTML of that variation switches. in order to do that you can use woocommerce_dropdown_variation_attribute_options_html filter hook.

But you have to remove the default filter hook of the WPC Variation Swatches plugin.

Below is the function is helps you to remove the default filter defined in-class method. Thanks to remove_action or remove_filter with external classes?

function remove_class_action ( $action,$class,$method ) {
    global $wp_filter ;
    if (isset($wp_filter[$action])) {
        $len = strlen($method) ;
        foreach ($wp_filter[$action] as $pri => $actions) {
            foreach ($actions as $name => $def) {
                if (substr($name,-$len) == $method) {
                    if (is_array($def['function'])) {
                        if (get_class($def['function'][0]) == $class) {
                            if (is_object($wp_filter[$action]) && isset($wp_filter[$action]->callbacks)) {
                                unset($wp_filter[$action]->callbacks[$pri][$name]) ;
                            } else {
                                unset($wp_filter[$action][$pri][$name]) ;
                            }
                        }
                    }
                }
            }
        }
    }
}

Below is the function where you override HTML.

On this function you need to check each variation status. you can use get_available_variations to get product variations.

Store status in an array and check against term and based on that you can add class.

function custom_variation_attribute_options_html( $html, $args ) {
    
    remove_class_action( 'woocommerce_dropdown_variation_attribute_options_html', 'WPCleverWpcvs', 'variation_attribute_options_html' );

    $options    = $args['options'];
    $product    = $args['product'];
    $attribute  = $args['attribute'];
    $hint       = get_option( 'wpcvs_tooltip', 'top' );
    $hint_class = $hint !== 'no' ? 'hint--' . $hint : '';
    $style      = get_option( 'wpcvs_style', 'square' );
    $attr_id    = wc_attribute_taxonomy_id_by_name( $attribute );
    $wpcvs_html = '';

    if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
        $attributes = $product->get_variation_attributes();
        $options    = $attributes[ $attribute ];
    }

    $variation_statuses = array();

    $variations = $product->get_available_variations();
    
    foreach($variations as $variation){
        
        $variation_id         = $variation['variation_id'];
        $variation_obj        = new WC_Product_variation($variation_id);
        $variation_attributes = $variation_obj->get_variation_attributes();
        $stock_status         = get_post_meta( $variation_id, '_stock_status', true );

        $variation_statuses[$variation_attributes['attribute_pa_size']] = $stock_status;
    }

    if ( $attr_id ) {
        $attr      = wc_get_attribute( $attr_id );
        $attr_type = isset( $attr->type ) ? $attr->type : 'select';

        $terms = wc_get_product_terms(
            $product->get_id(),
            $attribute,
            array(
                'fields' => 'all',
            )
        );

        if ( ( $attr_type === 'select' ) && ( get_option( 'wpcvs_button_default', 'no' ) === 'yes' ) ) {
            $attr_type = 'button';
        }

        $class = '';

        if ( ( $attr_type !== '' ) && ( $attr_type !== 'select' ) ) {
            $wpcvs_html .= '<div class="wpcvs-terms wpcvs-type-' . esc_attr( $attr_type ) . ' wpcvs-style-' . $style . '" data-attribute="' . esc_attr( $attribute ) . '">';

            switch ( $attr_type ) {
                case 'button' :
                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_button', true ) ?: $term->name;
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $val;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span>' . esc_html( $val ) . '</span></span>';
                    }

                    break;
                case 'color':
                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_color', true ) ?: '';
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $term->name;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span ' . ( ! empty( $val ) ? 'style="background-color: ' . esc_attr( $val ) . '"' : '' ) . '>' . esc_html( $val ) . '</span></span>';
                    }

                    break;
                case 'image':
                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_image', true ) ? wp_get_attachment_thumb_url( get_term_meta( $term->term_id, 'wpcvs_image', true ) ) : wc_placeholder_img_src();
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $term->name;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span><img src="' . esc_url( $val ) . '" alt="' . esc_attr( $term->name ) . '"/></span></span>';
                    }

                    break;
                case 'radio':
                    $name = uniqid( 'wpcvs_radio_' );

                    foreach ( $terms as $term ) {

                        if( isset( $variation_statuses[$term->slug] ) ){
                            $class = $variation_statuses[$term->slug];
                        }

                        $val        = get_term_meta( $term->term_id, 'wpcvs_radio', true ) ?: $term->name;
                        $tooltip    = get_term_meta( $term->term_id, 'wpcvs_tooltip', true ) ?: $term->name;
                        $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . ' '. $class .' " aria-label="' . esc_attr( $tooltip ) . '" title="' . esc_attr( $tooltip ) . '" data-term="' . esc_attr( $term->slug ) . '"><span><input type="radio" name="' . esc_attr( $name ) . '" value="' . esc_attr( $term->slug ) . '"/> ' . esc_html( $val ) . '</span></span>';
                    }

                    break;
                default:
                    break;
            }

            $wpcvs_html .= '</div>';
        }
    } else {
        // custom attribute
        if ( get_option( 'wpcvs_button_default', 'no' ) === 'yes' ) {
            $wpcvs_html .= '<div class="wpcvs-terms wpcvs-type-button wpcvs-style-' . $style . '" data-attribute="' . sanitize_key( esc_attr( $attribute ) ) . '">';

            foreach ( $options as $option ) {
                $wpcvs_html .= '<span class="wpcvs-term ' . $hint_class . '" aria-label="' . esc_attr( $option ) . '" title="' . esc_attr( $option ) . '" data-term="' . esc_attr( $option ) . '"><span>' . esc_html( $option ) . '</span></span>';
            }

            $wpcvs_html .= '</div>';
        }
    }

    return $wpcvs_html . $html;
}

add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'custom_variation_attribute_options_html', 198, 2 );

function add_custom_css(){
    ?>
    <style type="text/css">
        .wpcvs-term.outofstock  span { background-color: red; color: #ffffff; }
        .wpcvs-term.instock span { background-color: green; color: #ffffff; }
        .wpcvs-term.onbackorder span { background-color: blue; color: #ffffff; }
    </style>
    <?php
}

add_action( 'wp_head', 'add_custom_css', 10, 1 );

Tested and works. code will go in your active theme functions.php

enter image description here

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement