Woocommerce change product variation via JS
Asked Answered
F

2

6

Here's a working example of where we are: http://fpusa.drunk.kiwi/product/ship-your-idea-2/

I am trying to create 'swatches' for a user to click, which would than change the value of the hidden select box woocommerce uses to grab the variation data.

Is there a specific way to tell woocommerce to read the value of the select box?

Everything works as expected but the javascript event which changes the variation id and gets everything ready to add to cart never happens.

Note: I hide the wc_dropdown with d-none because I thought it would minimize a custom solution.

Variable.php - Calls fpusa_product_attribute_button();

<?php foreach ( $attributes as $attribute_name => $options ) : ?>

  <tr class="">
    <td class="label"><label for="<?php echo esc_attr( sanitize_title( $attribute_name ) ); ?>"><?php echo wc_attribute_label( $attribute_name ); // WPCS: XSS ok. ?></label></td>
        <td class="value">
            <?php
              fpusa_product_attribute_button( $options, $attribute_name, $product );

              wc_dropdown_variation_attribute_options( array(
                'options'   => $options,
                'attribute' => $attribute_name,
                'product'   => $product,
                'class'         => 'd-none',
              ));

            echo end( $attribute_keys ) === $attribute_name ? wp_kses_post( apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . esc_html__( 'Clear', 'woocommerce' ) . '</a>' ) ) : '';

            ?>
        </td>
    </tr>

<?php endforeach; ?>

fpusa_product_attribute_button()

function fpusa_product_attribute_button( $options, $attribute_name, $product ){
    if( ! empty( $options ) ) : ?>
        <div id="var_btn" class="d-flex">
            <?php foreach( $options as $option ): ?>
                <button type="button" class="d-flex btn justify-content-center align-items-center border mx-1" data-key="<?php echo $attribute_name ?>" data-value="<? echo $option ?>">
                    <?php echo $option; ?>
                </button>
            <?php endforeach; ?>
        </div> <?php
    endif;
}

Functions.js

$('#var_btn button').click(function(){
   let attribute = $(this).attr('data-key');
   let option = $(this).attr('data-value');
   console.log( attribute, option );
   $('#' + attribute).val( option );
});
Fruiterer answered 22/2, 2019 at 14:39 Comment(0)
F
4

All I had to do is simply trigger the change event on the <select> was passing the selected option to.

$('#var_btn button').click(function(){
    let attribute = $(this).attr('data-key');
    let option = $(this).attr('data-value');
    console.log( attribute, option );
    $('#' + attribute).val( option ).change();
  });
Fruiterer answered 26/2, 2019 at 15:10 Comment(0)
F
0

Modify function to use name not slug in button text:

function fpusa_product_attribute_button( $options, $attribute_name, $product ){
if( ! empty( $options ) ) :
    
    if ( $product && taxonomy_exists( $attribute_name ) ) {
        // Get terms if this is a taxonomy - ordered. We need the names too.
        $terms = wc_get_product_terms(
            $product->get_id(),
            $attribute_name,
            array(
                'fields' => 'all',
            )
        );
        foreach ( $terms as $term ) {
            if ( in_array( $term->slug, $options, true ) ) {
                $html .= '<button data-value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name, $term, $attribute, $product ) ) . '</button>';
            }
        }
    } else {
        foreach ( $options as $option ) {
            // This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
            $selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
            $html    .= '<button data-value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option, null, $attribute, $product ) ) . '</button>';
        }
    }

    ?>
    <div id="var_btn" class="d-flex">
        <?php echo $html; ?>
    </div> <?php
endif;

}

Ferrosilicon answered 16/8 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.