8manos / wc-variations-radio-buttons

Let your customers choose product variations using radio buttons instead of dropdowns.
https://wordpress.org/plugins/wc-variations-radio-buttons/
GNU General Public License v2.0
62 stars 34 forks source link

Suggestion to use filter instead of altering template file #32

Open apermo opened 6 years ago

apermo commented 6 years ago

Hi,

I just stumpled upon your plugin while I was creating the same functionality myself.

My idea differed in one way from your way, maybe you guys can integrate my idea into your plugin, making it easier to use.

Instead of altering the /single-product/add-to-cart/variable.php I hooked into the filter for the Dropdown.

` add_filter( 'woocommerce_dropdown_variation_attribute_options_html', [ $this, 'wc_dropdown_filter' ], 10, 2 );

public function wc_dropdown_filter( $html, $args ) {
    $old_html = $html;

    $args = wp_parse_args( apply_filters( 'new_fancy_filtername_woocommerce_dropdown_variation_attribute_options_args', $args ), array(
        'options'          => false,
        'attribute'        => false,
        'product'          => false,
        'selected'         => false,
        'name'             => '',
        'id'               => '',
        'class'            => '',
        'show_option_none' => __( 'Choose an option', 'woocommerce' ),
    ) );

    $options               = $args['options'];
    $product               = $args['product'];
    $attribute             = $args['attribute'];
    $name                  = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
    $id                    = $args['id'] ? $args['id'] : sanitize_title( $attribute );
    $class                 = $args['class'];
    $show_option_none      = $args['show_option_none'] ? true : false;
    $show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' ); // We'll do our best to hide the placeholder, but we'll need to show something when resetting options.

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

    $html = '<fieldset id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" data-show_option_none="' . ( $show_option_none ? 'yes' : 'no' ) . '">';

    if ( ! empty( $options ) ) {
        if ( $product && taxonomy_exists( $attribute ) ) {
            // Get terms if this is a taxonomy - ordered. We need the names too.
            $terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );

            foreach ( $terms as $term ) {
                if ( in_array( $term->slug, $options ) ) {

                    $html .= '<label class="radioLabel ' . $class . '"><input type="radio" name="' . esc_attr( $name ) . '" value="' . esc_attr( $term->slug ) . '"' . checked( sanitize_title( $args['selected'] ), $term->slug, false ) . ' data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '"><span>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) ) . '</span></label>';
                }
            }
        } 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'] ? checked( $args['selected'], sanitize_title( $option ), false ) : checked( $args['selected'], $option, false );
                $html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';

                $html .= '<label class="radioLabel ' . $class . '"><input type="radio" name="' . esc_attr( $name ) . '" value="' . esc_attr( $option ) . '"' . $selected . ' data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '"><span>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</span></label>';
            }
        }
    }

    $html .= '</fieldset>';

    echo apply_filters( 'new_fancy_filter_name', $html, $args, $old_html ); // WPCS: XSS ok.
}

`

The wc_dropdown_filter() is basically a copy of the original WooCommerce Code creating the dropdown, just altered to output radio instead of select, the only missing thing was the javascript code to make it work.

Maybe if you integrate that, you can get rid of the need to copy the template file.

Mantish commented 6 years ago

great idea, thanks you!

apermo commented 6 years ago

You're welcome, drop me a line when it's added to the code :)