1
votes

What I am trying: Show the Variation Description of the Child of a Variable Product on single product page in the product tab description area.

In WooCommerce and variable products the parent has the description which is stored in wp_posts->post_content and every child has an additional _variation_description field. On the frontent the description of the parent is always visible and the _variation_description of the Child is showing as a variation is selected. It gets updated with js and is displayed before the add to cart button together with the price of the variation.

The description is called in description.php with the code

the_content();

which outputs the parent products post_content db field. The variation description is called in variation.php with the code

<script type="text/template" id="tmpl-variation-template">
    <div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
</script>

As I understand this works with wp.template and I also checked the info on Javascript Reference wp.template The js is in add-to-cart-variation.js and the template is built with

template     = wp.template( 'variation-template' );

Then the data can be updated which I do not really understand in detail. What I understand is that all the js calls are in the form,

form.$singleVariation.html( $template_html );

so then I realized why I couldn't just copy the code from variation.php and paste it to description.php because there it would be outside the form tag.

On the other hand the data for SKU is not called from within the form, it is called through .product_meta so if I put a div with class="product_meta" I can call the sku and have it updated with js from anywhere. For example I can put this code into description.php

 <div class="product_meta">
       <?php if ( wc_product_sku_enabled() && ( $product->get_sku() || $product->is_type( 'variable' ) ) ) : ?>
          <?php if ( $sku = $product->get_sku() ) : ?>
             <span class="sku_wrapper"><?php esc_html_e( 'SKU:', 'woocommerce' ); ?> 
             <span class="sku" itemprop="sku"><?php echo $sku; ?></span></span>
          <?php endif; ?>
       <?php endif; ?>
 </div>

and it works fine.

So here I am stuck. I just want to have the variation description displayed dynamically in the description.php and I thought if I understand how the wp.template works in add-to-cart-variation.js I could figure it out. But I can't. I do not exactly understand how the content is being updated in the variation form and what the difference is to the data in SKU.

Maybe there is a totally simple and easy solution for what I want, and maybe my approach is too complicated. I would be very glad for any Ideas or hints or just pointing in the right direction.

2
I updated my question and left out all the custom fields, so now it is a bit clearer. I also tried to clarify my aim and what I have been trying so far.Karim

2 Answers

2
votes

This can be done with some jQuery code, where we will copy the variation description to the variable product description tab. But first you need to make some very small changes on some templates.

Here is the official docs related to: Template structure & Overriding templates via a theme

The templates changes and the necessary code:

  1. On single-product/tabs/description.php template file, you will replace the line:

    <?php the_content(); ?>
    

    by the following line (We just add a surrounding html <div> tag with a selector class):

    <div class="product-post-content"><?php the_content(); ?></div>
    
  2. On single-product/add-to-cart/variation.php template file, you will replace the line:

    <div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
    

    by the following line (we just hide the variation description):

    <div class="woocommerce-variation-description" style="display:none;">{{{ data.variation.variation_description }}}</div>
    
  3. Now the jQuery (commented) code (on single product pages for variable products only):

    add_action( 'wp_footer', 'move_variation_description' );
    function move_variation_description(){
        global $product;
        // Only on single product pages for variable products
        if ( ! ( is_product() && $product->is_type('variable') ) ) return;
        // jQuery code
        ?>
        <script type="text/javascript">
            jQuery(function($){
                a = '.woocommerce-variation-description', b = a+' p', c = 'input.variation_id',
                d = '#tab-description .product-post-content', de = $(d).html();
    
                // On load, adding a mandatory very small delay
                setTimeout(function(){
                    // variation ID selected by default
                    if( '' != $(c).val() && $(a).text() != '' )
                        $(d).html($(a).html());
                }, 300);
    
                // On live event (attribute select fields change)
                $('table.variations select').on( 'blur', function(){
                    // variation ID is selected
                    if( '' != $(c).val() && $(a).text() != '' ){
                        $(d).html($(a).html()); // We copy the variation description
                    }
                    // No variation ID selected
                    else {
                        $(d).html($(a).html()); // We set back the variable product description
                    }
                    console.log($('input.variation_id').val()); // TEST: Selected variation ID … To be removed
                });
            });
        </script>
        <?php
    }
    

    This code goes on function.php file of your active child theme (or active theme).

Tested and works.

Other related threads:

-1
votes

Hi i tried this solution but i get:

    Uncaught TypeError: e.indexOf is not a function
    at S.fn.init.S.fn.load (jquery-3.5.1.min.js?ver=3.5.1:2)
    at script.js?ver=1.0:1