Skip to content

Instantly share code, notes, and snippets.

@emilushi
Created May 2, 2019 11:29
Show Gist options
  • Save emilushi/7e1acc2417371a640c543324ff2465a1 to your computer and use it in GitHub Desktop.
Save emilushi/7e1acc2417371a640c543324ff2465a1 to your computer and use it in GitHub Desktop.
Convert WooCommerce variations to custom radio input.
<?php
/**
* Output radio buttons on WooCommerce variations.
*/
add_filter('woocommerce_dropdown_variation_attribute_options_html', static function ($html, $args) {
/** @var array $args */
$args = wp_parse_args(apply_filters('woocommerce_dropdown_variation_attribute_options_args', $args), [
'options' => false,
'attribute' => false,
'product' => false,
'selected' => false,
'name' => '',
'id' => '',
'class' => '',
'show_option_none' => __('Choose an option', 'woocommerce'),
]);
/** @var WC_Product_Variable $product */
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ?: 'attribute_'.sanitize_title($attribute);
$id = $args['id'] ?: sanitize_title($attribute);
$class = $args['class'];
$show_option_none = (bool)$args['show_option_none'];
// We'll do our best to hide the placeholder, but we'll need to show something when resetting options.
$show_option_none_text = $args['show_option_none'] ?: __('Choose an option', 'woocommerce');
// Get selected value.
if ($attribute && $product instanceof WC_Product && $args['selected'] === false) {
$selected_key = 'attribute_'.sanitize_title($attribute);
$args['selected'] = isset($_REQUEST[$selected_key]) ? wc_clean(wp_unslash($_REQUEST[$selected_key]))
: $product->get_variation_default_attribute($attribute); // WPCS: input var ok, CSRF ok, sanitization ok.
}
if (empty($options) && ! empty($product) && ! empty($attribute)) {
$attributes = $product->get_variation_attributes();
$options = $attributes[$attribute];
}
$radios = '<div class="custom-wc-variations">';
if ( ! empty($options)) {
if ($product && taxonomy_exists($attribute)) {
$terms = wc_get_product_terms($product->get_id(), $attribute, ['fields' => 'all']);
foreach ($terms as $term) {
if (in_array($term->slug, $options, true)) {
$radios .= '<input type="radio" name="custom_'.esc_attr($name).'" data-value="'.esc_attr($term->slug).'" id="'
.esc_attr($name).'_'.esc_attr($term->slug).'" data-variation-name="'.esc_attr($name).'" '
.checked(sanitize_title($args['selected']), $term->slug, false).'>';
$radios .= '<label for="'.esc_attr($name).'_'.esc_attr($term->slug).'">';
$radios .= esc_html(apply_filters('woocommerce_variation_option_name', $term->name));
$radios .= '</label>';
}
}
} else {
foreach ($options as $option) {
$checked = sanitize_title($args['selected']) === $args['selected'] ? checked($args['selected'],
sanitize_title($option), false) : checked($args['selected'], $option, false);
$radios .= '<input type="radio" name="custom_'.esc_attr($name).'" data-value="'.esc_attr($option).'" id="'
.esc_attr($name).'_'.esc_attr($option).'" data-variation-name="'.esc_attr($name).'" '.$checked.'>';
$radios .= '<label for="'.esc_attr($name).'_'.esc_attr($option).'">';
$radios .= esc_html(apply_filters('woocommerce_variation_option_name', $option));
$radios .= '</label>';
}
}
}
$radios .= '</div>';
return $html.$radios;
}, 20, 2);
(function ($) {
$(document).ready(function () {
const customVariations = document.getElementsByClassName('custom-wc-variations');
if (customVariations.length > 0) {
Array.from(customVariations).forEach(function (variation) {
const radios = variation.querySelectorAll('input[type=radio]');
radios.forEach(function (radio) {
radio.addEventListener('change', function () {
const variationName = radio.getAttribute('data-variation-name');
const selectBox = document.querySelector('select[name=' + variationName + ']');
selectBox.value = radio.getAttribute('data-value');
$(selectBox).trigger('change');
});
});
});
}
});
})(jQuery);
@emilushi
Copy link
Author

emilushi commented May 2, 2019

Add the filter under function.php file on your theme functions.php file and add the javascript function somewhere on you theme js file. and your good to go.
You may need to do some css styling to hide the current select box and to display you radio input differently.

@javadfathy
Copy link

hi emilushi
tanks for this code

why not change price when change attribute in shop page?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment