【问题标题】:Dynamic select field options based on selected brand in WooCommerce基于 WooCommerce 中所选品牌的动态选择字段选项
【发布时间】:2020-05-21 16:29:45
【问题描述】:

在 woocommerce 中,我有 2 个选择字段:

  • 第一个是“汽车品牌”,
  • 第二个是Car Brands 中的“汽车模型”。

我想做的是为选定的“汽车品牌”动态获取“汽车模型”

“汽车品牌”来自 WooCommerce 产品属性分类法。对于每个“汽车品牌”,相关的“汽车型号”是该产品属性分类的术语。

这是“汽车品牌”的代码(第一个选择字段):

$attributes =  wc_get_attribute_taxonomies();

if($attributes) {
    echo '<select id="car-brands"><option value="noselection">Car Brand</option>';
    foreach ( $attributes as $attribute ) {
        echo '<option value="' . $attribute->attribute_name . '">' . $attribute->attribute_label . '</option>';
    }
    echo '</select>';
}

还有一个生成的html示例代码:

<select id="car-brands">
    <option value="noselection">Car Brand</option>
    <option value="toyota">TOYOTA</option>
    <option value="lexus">LEXUS</option>
</select>

然后是“汽车型号”的代码(第二个选择字段):

$selected_attribute_name = 'toyota';
$taxonomy = 'pa_' . $selected_attribute_name;
$term_names = get_terms( array( 'taxonomy' => $taxonomy, 'fields' => 'names' ) );

echo '<select id="car-models"><option value="noselection">Car Model</option>';
echo '<option>' . implode( '</option><option>', $term_names ) . '</option>';
echo '</select>';

还有一个生成的html示例代码:

<select id="car-models">
    <option value="noselection">Car Model</option>
    <option value="toyota">AVENSIS</option>
    <option value="lexus">CAMRY</option>
</select>

如您所见,我正在获取“丰田”品牌的特定车型,因为我已将“丰田”硬编码为“汽车品牌”:

$selected_attribute_name = 'toyota';

所以我希望将$selected_attribute_name 作为动态变量,因此当用户选择汽车品牌“LEXUS”或“TOYOTA”时,第二个选择字段会动态加载相关术语(选项) em>。

我找到了很多相关的线程,但我无法理解如何使它适用于我的案例。

如何根据选定的汽车品牌让动态“汽车模型”选择字段选项?


编辑

我所有的 php 都在一个动作钩子函数中,如下所示:

function _themename_woocommerce_custom_filter() {
    $attributes =  wc_get_attribute_taxonomies();

    if($attributes) {
        echo '<select id="car-brands"><option value="noselection">Car Brand</option>';
        foreach ( $attributes as $attribute ) {
            echo '<option value="' . $attribute->attribute_name . '">' . $attribute->attribute_label . '</option>';
        }
        echo '</select>';
    }

    $selected_attribute_name = '';
    $taxonomy = 'pa_' . $selected_attribute_name;
    $term_names = get_terms( array( 'taxonomy' => $taxonomy, 'fields' => 'names' ) );

    echo '<select id="car-models"><option value="noselection">Car Model</option>';
    echo '<option>' . implode( '</option><option>', $term_names ) . '</option>';
    echo '</select>';
}
add_action( 'woocommerce_before_shop_loop', '_themename_woocommerce_custom_filter', 3 );

【问题讨论】:

    标签: php jquery ajax wordpress woocommerce


    【解决方案1】:

    下面使用Ajax从选中的“汽车品牌”中获取对应的词条(产品属性分类)动态生成“车型”选择字段选项(选中的词条产品属性分类)

    // Display 2 select fields (car brands and car models)
    add_action( 'woocommerce_before_shop_loop', 'before_shop_loop_action_callback', 3 );
    function before_shop_loop_action_callback() {
        if( $attributes =  wc_get_attribute_taxonomies() ) {
    
            ## 1st dropdown
    
            echo '<select id="car-brands" style="min-width:100px;"><option value="">' . __("Car Brand"). '</option>';
    
            // Loop through attribute taxonomies
            foreach ( $attributes as $attribute ) {
                echo '<option value="' . $attribute->attribute_name . '">' . $attribute->attribute_label . '</option>';
            }
            echo '</select>';
    
            ## 2nd dropdown
    
            echo '<select id="car-models" style="min-width:100px;"><option value=""> … </option></select>';
        }
    }
    
    // jQuery / Ajax (client side)
    add_action( 'wp_footer', 'car_brand_selectors_script' );
    function car_brand_selectors_script() {
        ?>
        <script type="text/javascript">
        jQuery(function( $ ) {
            if (typeof woocommerce_params === 'undefined')
                return false;
    
            var b = 'select#car-brands', // 1st field
                m = 'select#car-models', // 2nd field
                r = $(m).html(); // Original 2nd field select options
    
            function ajaxSendCarBrand( carBrand ) {
                $.ajax({
                    url: woocommerce_params.ajax_url,
                    type : 'POST',
                    data : {
                        'action' : 'get_brand_terms',
                        'car_brand' : carBrand
                    },
                    success: function( response ) {
                        var options = $.parseJSON(response),
                            opt     = '';
    
                        if ( $.isEmptyObject(options) ) {
                            $(m).html(r);
                        } else {
                            $.each( options, function( key, value ){
                                opt += '<option value="'+key+'">'+value+'</option>';
                            });
                            $(m).html(opt);
                        }
                    }
                });
            }
    
            // On change live event
            $( document.body ).on( 'change', b, function() {
                ajaxSendCarBrand($(this).val());
            });
        });
        </script>
        <?php
    }
    
    // WP AJAX HANDLER (Server side)
    add_action('wp_ajax_get_brand_terms', 'get_car_brand_models');
    add_action('wp_ajax_nopriv_get_brand_terms','get_car_brand_models');
    function get_car_brand_models() {
        if( isset($_POST['car_brand']) ) {
            $brand    = wc_clean( $_POST['car_brand'] );
            $taxonomy = wc_attribute_taxonomy_name($brand);
            $options  = [];
    
            if( taxonomy_exists( $taxonomy ) ) {
                $terms   = get_terms( array( 'taxonomy' => $taxonomy ) );
    
                foreach( $terms as $term ){
                    $options[$term->slug] = $term->name;
                }
            }
            echo json_encode( $options );
        }
        wp_die();
    }
    

    代码在您的活动子主题(或活动主题)的functions.php 文件中。经过测试并且可以工作。

    【讨论】:

      【解决方案2】:

      这里看一个有效的 ajax 示例。

      Javascript 部分:

      jQuery('#car-brands').change(function() {
          let carBrandName = jQuery(this).val();
          YourFunctionNameHere(carBrandName);
      });
      
      //function to execute
      function YourFunctionNameHere(carBrandName) {
          //formdata variable consists of
          //action: this is ajax action name for WordPress which we define in PHP with a callback function with same name. See in PHP code part.
          //brandName: this is your custom post attributes name
          let formdata = "action=get_car_models&brandName="+carBrandName;
          jQuery.ajax({
              type: "POST",
              url: ajaxurl, // since WordPress version 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
              data: formdata,
              cache: false,
              success: function(response, textStatus, jqXHR) {
                  jQuery("#car-models").html(response);
              },
              error: function(jqXHR, textStatus, errorThrown) {
                  //do stuff here in case of error
              }
          });
      }
      

      PHP部分:

       //here wp_ajax is the required prefix for your custom actions
       //first parameter is action name with wp_ajax prefix
       //second parameter is callback function to execute with same name as your action
       //for example if your action name is wp_ajax_get_car_models then your callback will be get_car_models
      add_action( 'wp_ajax_get_car_models', 'get_car_models' );
      
      function get_car_models() {
          global $wpdb; // this is how you get access to the database
      //require_once any files here in which the below code is available or just write your code here.
          $selected_attribute_name = $_POST['brandName'];
          $taxonomy = 'pa_' . $selected_attribute_name;
          $term_names = get_terms( array( 'taxonomy' => $taxonomy, 'fields' => 'names' ) );
          $html = '';
          $html .= '<select id="car-models"><option value="noselection">Car Model</option>';
          $html .= '<option>' . implode( '</option><option>', $term_names ) . '</option>';
          $html .= '</select>';
          echo $html;
          wp_die(); // this is required to terminate immediately and return a proper response
      
      }
      

      【讨论】:

      • 谢谢,但我无法让它工作,我在我的问题中添加了更多信息,对不起,你能看看吗?我所有的 php 都在一个函数中,它挂在另一个动作中,我怎么能调用 wp_ajax?再次抱歉,我认为这不是重要信息。
      • 在我创建的 wp_ajax 动作钩子中。尝试调用该函数并将 $_POST['brandName'] 作为参数传递。 _themename_woocommerce_custom_filter($_POST['brandName']):
      猜你喜欢
      • 1970-01-01
      • 2018-10-11
      • 2022-01-05
      • 2011-11-06
      • 2013-06-13
      • 1970-01-01
      • 2019-07-31
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多