gpt4 book ai didi

ajax - Woocommerce如何使用自定义html单选按钮而不是下拉菜单将可变产品的添加到购物车按钮ajaxify - 没有插件

转载 作者:行者123 更新时间:2023-12-03 20:39:53 25 4
gpt4 key购买 nike

我试图把这个拼图的所有部分放在一起。在过去的 3 天里,我一直在阅读有关此主题的所有问题和答案。所以我遵循的总体蓝图如下:

  • 在单品页面,首先检查产品类型是“简单”还是“可变”。
  • 如果产品是“可变的”,那么我使用 woocommerce_variable_add_to_cart(); 函数来输出正确的 html。
  • 然后尝试使用默认 html(即“下拉菜单”)和 woocommerce Hook 生成新的和自定义的 html(即“单选按钮”)。
  • 然后尝试使用 javascript 为新的和自定义的 html(即“单选按钮”)提供功能。
  • 然后使用 css 隐藏默认下拉菜单。
  • 然后尝试向 wordpress 发送 ajax 请求。
  • 然后尝试在后端处理该 ajax 请求并将产品添加到购物车。

  • 这是我每个部分的代码:
  • 在单品页面检查产品类型是否“可变”:

  • global $post;

    $product = wc_get_product($post->ID);

    $product_type = $product->get_type();

  • 如果产品类型是“变量”,则输出正确的 html:

  • if($product_type == 'variable'):
    woocommerce_variable_add_to_cart();
    endif;
  • 使用 php 和 woocommerce Hook 生成新的和自定义的 html(单选按钮):

  • add_filter('woocommerce_dropdown_variation_attribute_options_html', 'my_theme_variation_radio_buttons', 20, 2);

    function my_theme_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;
    $radios .= '<input type="radio" data-checked="no" id="' . esc_attr($id) . '" name="' . esc_attr($name) . '" value="' . esc_attr($term->slug) . '" ' . checked(sanitize_title($args['selected']), $term->slug, false) . '><label for="' . esc_attr($id) . '">' . esc_html(apply_filters('woocommerce_variation_option_name', $term->name)) . '</label>';
    }
    }
    } else {
    foreach ($options as $option) {
    $id = $name . '-' . $option;
    $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) . '" name="' . esc_attr($name) . '" value="' . esc_attr($option) . '" id="' . sanitize_title($option) . '" ' . $checked . '><label for="' . esc_attr($id) . '">' . esc_html(apply_filters('woocommerce_variation_option_name', $option)) . '</label>';
    }
    }
    }

    $radios .= '</div>';

    return $html . $radios;
    }


    add_filter('woocommerce_variation_is_active', 'my_theme_variation_check', 10, 2);

    function my_theme_variation_check($active, $variation)
    {
    if (!$variation->is_in_stock() && !$variation->backorders_allowed()) {
    return false;
    }
    return $active;
    }
  • 使用 javascript 为“单选按钮”提供功能:

  • jQuery(document).ready($ => {
    $(document).on('change', '.variation-radio input', function () {
    $('.variation-radio input:checked').each(function (index, element) {

    var radioElement = $(element);
    var radioName = radioElement.attr('name');
    var radioValue = radioElement.attr('value');

    $('select[name="' + radioName + '"]').val(radioValue).trigger('change');
    });
    });
    $(document).on('woocommerce_update_variation_values', function () {
    $('.variation-radio input').each(function (index, element) {
    var radioElement = $(element);
    var radioName = radioElement.attr('name');
    var radioValue = radioElement.attr('value');
    radioElement.removeAttr('disabled');
    if ($('select[name="' + radioName + '"] option[value="' + radioValue + '"]').is(':disabled')) {
    radioElement.prop('disabled', true);
    }
    });
    });
    $("a.reset_variations").click(function () {
    $('input:radio[name="attribute_size"]').prop('checked', false); $(this).css('display', 'none');
    });
    })
  • 使用 css 隐藏默认下拉菜单:

  • table.variations select{
    display: none;
    }
  • 向 wordpress 发送 ajax 请求:

  • jQuery(document).ready($ => {
    $("button.single_add_to_cart_button").on('click', function (e) {
    e.preventDefault();
    var myBtn = $(this),
    $form = myBtn.closest('form.variations_form'),
    product_qty = $form.find('input[name=quantity]').val() || 1,
    product_id = $form.find('input[name=product_id]').val(),
    variation_id = $form.find('input[name=variation_id]').val() || 0,
    variation = {},
    keys = [],
    values = [];
    // Looping through the attributes names and save them as the keys array
    $('table tr td.label label').each(function (index, element) {
    let radioElement = $(element);
    keys[index] = radioElement.text();
    });
    // Looping through the attributes values and save them as the values array
    $('.variation-radios input:checked').each(function (index, element) {
    let radioElement = $(element);
    values[index] = radioElement.val();
    });
    // Looping through the variation object and save keys and values in that object
    $.each(keys, function (index, element) {
    variation[element] = values[index]
    })
    console.log(variation);

    var data = {
    action: 'woocommerce_add_variation_to_cart',
    product_id: product_id,
    quantity: product_qty,
    variation_id: variation_id,
    var: variation
    };

    $(document.body).trigger('adding_to_cart', [myBtn, data]);

    $.ajax({
    type: 'post',
    url: wc_add_to_cart_params.ajax_url,
    data: data,
    beforeSend: function (response) {
    myBtn.removeClass('added').addClass('loading');
    },
    complete: function (response) {
    myBtn.addClass('added').removeClass('loading');
    },
    success: function (response) {
    console.log(response);
    if (response.error && response.product_url) {
    window.location = response.product_url;
    return;
    } else {
    $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, myBtn]);
    }
    },
    });

    return false;
    });
    })
  • 后台处理ajax请求,将商品加入购物车:

  • add_action('wp_ajax_nopriv_woocommerce_add_variation_to_cart', 'my_theme_testing_add_to_cart_variable');

    add_action('wp_ajax_woocommerce_add_variation_to_cart', 'my_theme_testing_add_to_cart_variable');

    function my_theme_testing_add_to_cart_variable()
    {
    if (isset($_POST['product_id']) && $_POST['product_id'] > 0) {
    $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));

    $quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);

    $variation_id = isset($_POST['variation_id']) ? absint($_POST['variation_id']) : '';

    $attributes = explode(',', $_POST['var']);

    $variation = array();

    foreach ($attributes as $values) {

    $values = explode(':', $values);

    $variation['attributes_' . $values[0]] = $values[1];

    }

    $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);

    if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variation)) {

    do_action('woocommerce_ajax_added_to_cart', $product_id);

    if (get_option('woocommerce_cart_redirect_after_add') == 'yes') {
    wc_add_to_cart_message($product_id);
    }

    WC_AJAX::get_refreshed_fragments();

    } else {

    $data = array(
    'error' => true,
    'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id)
    );

    wp_send_json($data);
    }

    die();
    }
    }

    问题
    一切正常,直到第 7 步没有错误,但是当我运行整个过程时,单个产品页面会刷新,并且变量产品不会添加到购物车中。并且 wordpress 错误显示“{您的属性字段} 是必填字段”!
    我认为当我尝试将变体对象发送到后端时,该错误可能位于 ajax 调用中的某个位置。
    虽然,我在后端获得的数据非常好,但它没有将其添加到购物车中。

    我尝试调试的东西
    我试图将 ajax 调用中的数据作为数组发送,但也没有用。
    我还尝试同时使用 =: 来分解变异数据,但都没有奏效!
    蹄子!到目前为止,这是漫长的一周:\充满了调试、头痛和挫折。现在,当我尝试运行整个 shebang 时,我无法让它工作,我一直在阅读所有 Qs 和 As on SO 但找不到错误!我想我已经想了几天了,而且还有很多部分。
    所以我想我需要一些额外的眼睛来检测这个错误。
    谢谢,我感谢任何见解!

    此外,向这些我从中学到很多东西的人大声喊叫:


    编辑
    代码工作正常,错误不在代码中,而是在我提供的数据中。我会把代码留在这里以防将来有人需要它。

    最佳答案

    短线
    代码运行良好,我会把它留在这里以防将来有人需要它。错误不在代码中,而是在我提供的数据中。

    详细说明
    该代码工作正常。我的客户出于某些原因对我提供的数据进行了操作,因此每个可变产品都不是真正的可变产品,但同时标签被输入为可变产品(是的,我知道这很困惑,而不是标准练习),这就是为什么每当我尝试将它们添加到购物车时,它都会给出错误,指出 {your-attribute} 是必填字段。
    因此,我们删除了每个产品数据,并将其作为真实的可变产品重新添加回来,然后代码就可以工作,而无需我们更改其中的任何内容。

    外卖
    所以请记住,无论何时开发您的应用程序,这枚硬币总是有两个方面!一方面是您的代码,另一方面是您正在处理的数据。
    因此,始终始终确保您使用的数据是它应有的方式/格式。此外,如果您在代码中找不到任何错误,请记住检查/调试数据的另一侧。
    如果您不先检查数据或在任何调试阶段都没有检查数据,那么以后就很难找到问题所在!
    这个错误造成了项目的长时间延迟(大约 2 周,直到我们追踪到数据中的错误)。所以一定要经常检查硬币的两面:

  • 首先,你正在处理的数据
  • 其次,你写的代码。
  • 关于ajax - Woocommerce如何使用自定义html单选按钮而不是下拉菜单将可变产品的添加到购物车按钮ajaxify - 没有插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67453806/

    25 4 0