T
T
trenton2021-08-04 07:03:22
JavaScript
trenton, 2021-08-04 07:03:22

Select and radio button are linked incorrectly, how to link correctly?

Already at the end of the workflow, I realized that my bugs were not related to ajax, but to the incorrect operation of selects with radio buttons
. and they conflict with my custom color meta fields and stuff like that - it's too late, too-too much to redo, and the directory options in them are paid, not sure there won't be the same issues.
Here is the site . The browser may swear at the technical domain, but it is there and the host is not free, not viruses. The selects should be hidden, but I opened them for demonstration that it does not always select correctly on a button click.

What did I do. Moved the button with variations from the product card to the catalog.

remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart',10 );
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_single_add_to_cart', 10);


For the buttons, I took the snippet from here , but podshamanil under the markup I needed, AND ADDED THE PRODUCT ID TO THE ID OF THE ATTRIBUTES, so that they were unique in the catalog
function variation_radio_buttons($html, $args) {
  $args = wp_parse_args(apply_filters('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'),
  ));

  if(false === $args['selected'] && $args['attribute'] && $args['product'] instanceof WC_Product) {
    $selected_key     = 'attribute_'.sanitize_title($args['attribute']);
    $args['selected'] = isset($_REQUEST[$selected_key]) ? wc_clean(wp_unslash($_REQUEST[$selected_key])) : $args['product']->get_variation_default_attribute($args['attribute']);
  }

  $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      = (bool)$args['show_option_none'];
  $show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __('Choose an option', 'woocommerce');

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

  $radios = '<div class="variation-radios">';

  if(!empty($options)) {
    if($product && taxonomy_exists($attribute)) {
      $terms = wc_get_product_terms($product->get_id(), $attribute, array(
        'fields' => 'all',
      ));

      foreach($terms as $term) {
        if(in_array($term->slug, $options, true)) {
          $id = $name.'-'.$term->slug;
          global $product;
          $product_id = $product->get_id();
          $radios .= '<div class="attr-container"><div class="radio-span" style="background:' .  get_term_meta( $term->term_id, 'miniluna_pa_color', true ) . '"><input type="radio" id="'.esc_attr($id). $product_id. '" name="'.esc_attr($name).'" value="'.esc_attr($term->slug).'" '.checked(sanitize_title($args['selected']), $term->slug, false).'><label for="'.esc_attr($id). $product_id.'">'.esc_html(apply_filters('woocommerce_variation_option_name', $term->name)).'</label></div></div>';
        }
      } 
    } else {
      foreach($options as $option) {
        $id = $name.'-'.$option;
         global $product;
          $product_id = $product->get_id();
        $checked    = sanitize_title($args['selected']) === $args['selected'] ? checked($args['selected'], sanitize_title($option), false) : checked($args['selected'], $option, false);
        $radios    .= '<input type="radio" id="'.esc_attr($id). $product_id.'" name="'.esc_attr($name).'" value="'.esc_attr($option).'" id="'.sanitize_title($option).'" '.$checked.'><label for="'.esc_attr($id). $product_id.'">'.esc_html(apply_filters('woocommerce_variation_option_name', $option)).'</label>';
      }
    }
  }

  $radios .= '</div>';
    
  return $html.$radios;
}
add_filter('woocommerce_dropdown_variation_attribute_options_html', 'variation_radio_buttons', 20, 2);

function variation_check($active, $variation) {
  if(!$variation->is_in_stock() && !$variation->backorders_allowed()) {
    return false;
  }
  return $active;
}
add_filter('woocommerce_variation_is_active', 'variation_check', 10, 2);


JS part remained unchanged
jQuery(document).on('change', '.variation-radios input', function() {
  jQuery('.variation-radios input:checked').each(function(index, element) {
    var $el = jQuery(element);
    var thisName = $el.attr('name');
    var thisVal  = $el.attr('value');
    jQuery('select[name="'+thisName+'"]').val(thisVal).trigger('change');
  });
});
jQuery(document).on('woocommerce_update_variation_values', function() {
  jQuery('.variation-radios input').each(function(index, element) {
    var $el = jQuery(element);
    var thisName = $el.attr('name');
    var thisVal  = $el.attr('value');
    $el.removeAttr('disabled');
    if(jQuery('select[name="'+thisName+'"] option[value="'+thisVal+'"]').is(':disabled')) {
      $el.prop('disabled', true);
    }
  });
});


In what part of the problem - from the front or from the back? Maybe someone will see? Very helpful, even ready to thank.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question