Matt Stafford
Matt Stafford

Reputation: 35

Woocommerce product loop - display variation select dropdown and add to cart button in archive

Trying to add a "add to cart" button within a product loop on an archive page for a variable product. Currently my loop links to the full product page to select the variation. I would like to add a drop down select for the variation options (single attribute) with an add to cart button for the chosen attribute

Currently my code below will link directly to the product page to select the variation:

<?php while ( have_posts() ): the_post(); ?>
<?php $product = wc_get_product( get_the_ID() ); /* get the WC_Product Object */ 
?>

<div class="post-item" data-id="<?php the_id(); ?>">
    <a href="<?php the_permalink(); ?>" >
        <div class="post-image"> 
            <?php echo get_the_post_thumbnail(); ?>
        </div>
        <div class="post-content">
            <h3><?php the_title(); ?></h3>
            <div class="address">
                <span class="icon-post"><img src="https://inmemoryoflife.com/wp-content/uploads/2020/07/pin-1.svg" alt=""></span><?php echo get_field('crematorium_address'); ?>
            </div>
            <div class="price">
                <span class="icon-post"><img src="https://inmemoryoflife.com/wp-content/uploads/2020/06/pound-sterling.svg" alt=""></span><?php echo $product->get_price_html(); ?>
            </div>
            <div class="button-post">
                <span>View Details</span>
            </div>
        </div>
    </a>
</div>
<?php endwhile; ?>

Upvotes: 2

Views: 65

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254373

For variable products with a unique attribute for variations, you can easily add a select field for that unique attribute. Then you will be able to select the corresponding variation and add it to cart using WooCommerce Ajax add to cart functionality.

Here is the revised code:

<?php 
while ( have_posts() ): the_post();
    $product = wc_get_product( get_the_ID() ); // get the WC_Product Object 
    $is_variable = $product->is_type('variable'); // Check if product is variable
    $variation_attributes = $is_variable ? $product->get_variation_attributes() : array(); // Get attributes for variations
    $attributes_count = (int) count( $variation_attributes ); // Attributes count
?>

<div class="post-item" data-id="<?php the_id(); ?>">
    <a href="<?php the_permalink(); ?>" >
        <div class="post-image"> 
            <?php echo get_the_post_thumbnail(); ?>
        </div>
        <div class="post-content">
            <h3><?php the_title(); ?></h3>
            <div class="address">
                <span class="icon-post"><img src="https://inmemoryoflife.com/wp-content/uploads/2020/07/pin-1.svg" alt=""></span><?php echo get_field('crematorium_address'); ?>
            </div>
            <div class="price">
                <span class="icon-post"><img src="https://inmemoryoflife.com/wp-content/uploads/2020/06/pound-sterling.svg" alt=""></span><?php echo $product->get_price_html(); ?>
            </div>
            <?php if ( $attributes_count !== 1 ) : ?>
            <div class="button-post">
                <span>View Details</span>
            </div>
            <?php endif; ?>
        </div>
    </a>
    <?php 
    // For variable products with only one attribute set for variations
    if ( $attributes_count === 1 ) {
        $attribute_name = current( array_keys( $variation_attributes ) );
        
        // Display the select field
        echo '<div>
        <select class="product-attribute">';
            
        printf( '<option value="">%s %s</option>', esc_html__('Select a', 'woocommerce'), wc_attribute_label( $attribute_name ) );

        foreach ( $product->get_available_variations( 'object ') as $variation ) {
            if ( $variation->is_in_stock() ) {
                printf( '<option value="%s">%s</option>', $variation->get_id(), $variation->get_attribute( $attribute_name ) );
            }
        }
        echo '</select><br>';

        // Display the add to cart button
        printf('<a href="" data-quantity="1" class="%s" data-product_id="" rel="nofollow" data-success_message="%s">%s</a>',
            'button add_to_cart_button ajax_add_to_cart', esc_html__('The product has been added to your cart'), esc_html__('Add to cart')
        );
        echo '</div>';
    }
    ?>
</div>
<?php endwhile; ?>

Now, some JavaScript (jQuery) code is required to add the selected variation related parameters to the add to cart button.

The JavaScript code:

add_action('wp_footer', 'variable_product_add_to_cart_script', 1);
function variable_product_add_to_cart_script() {
    if ( is_woocommerce() && ! is_wc_endpoint_url() && ! is_checkout() ) :
    ?>
    <script>
    jQuery( function($) {
        $('select.product-attribute').on('change', function(){
            const productID = $(this).find(":selected").val(),
                  addToCart = $(this).parent().find('a.add_to_cart_button'),
                  hrefTag   = productID == '' ? '' : '?add-to-cart='+productID;

            addToCart.prop('href', hrefTag).attr('data-product_id', productID);
        });
    });
    </script>
    <?php
    endif;
}

Code goes in functions.php file of your child theme (or in a plugin).

Tested and works with Ajax add to cart functionality enabled.

Upvotes: 1

Related Questions