【问题标题】:Woocommerce 2 Variable Product Dropdown List, force first one to always show all optionsWoocommerce 2 可变产品下拉列表,强制第一个始终显示所有选项
【发布时间】:2018-07-07 01:12:28
【问题描述】:

我的可变 WooCommerce 产品中有 2 个下拉选择字段。

第一个是产品类型(在我的情况下,有框或无框艺术品) 第二个是艺术品的尺寸。

感谢this code

add_filter( 'woocommerce_dropdown_variation_attribute_options_args', 'dropdown_variation_attribute_options', 10, 1 );
function dropdown_variation_attribute_options( $args ){

    // For attribute "Type"
    if( 'Type' == $args['attribute'] )
        $args['show_option_none'] = __( 'Select Framed or Unframed Artwork', 'woocommerce' );

    // For attribute "Sizes"
    if( 'Size' == $args['attribute'] )
        $args['show_option_none'] = __( 'Select Size of Artwork', 'woocommerce' );

    return $args;
}

当没有为每个下拉选择字段单独选择任何内容时,我可以显示默认文本。

我现在遇到的问题是我需要强制第一个下拉列表始终显示所有选项,并在进行选择时重置第二个。

例子:

我在第一个下拉列表中提供变体 A、B、C、D。 第二个下拉列表会有 1,2,3,4 的变化。

假设我选择 A,第二个下拉选择字段现在将选项限制为 1 和 3,因为 A 不适用于 2 和 4。

假设我现在在第二个下拉选择字段中选择 3,这会将第一个下拉选择字段的选择限制为 A 和 B,因为 C 和 D 在 3 中不可用。

但我还需要在第一个中看到 C 和 D,这样人们在选择产品时总是可以从头开始。

任何帮助将不胜感激。

【问题讨论】:

    标签: javascript php wordpress woocommerce dropdown


    【解决方案1】:

    请检查以下代码。希望这会对你有所帮助。

    jQuery(document).ready(function($){
        if (jQuery('form.variations_form').length) {
            let $form              = jQuery('form.variations_form');
            let $first_attr_select = $form.find( '.variations select' ).eq(0);
            let first_attr_val     = $first_attr_select.val() || '';
    
            $first_attr_select.on('change', function(e){
                if (!e.isTrigger) {
                    // store the real value only
                    first_attr_val = this.value;
                }
            });
    
            $form.on('woocommerce_update_variation_values', function(){
                let first_attr_name       = $first_attr_select.data( 'attribute_name' ) || $first_attr_select.attr( 'name' ),
                    show_option_none        = $first_attr_select.data( 'show_option_none' ),
                    option_gt_filter        = ':gt(0)',
                    attached_options_count  = 0,
                    new_attr_select         = $( '<select/>' ),
                    first_attr_val_valid = true;
    
                let variations          = $form.data('product_variations');
    
                new_attr_select.html( $first_attr_select.data( 'attribute_html' ) );
    
                // Loop through variations.
                for ( let variation of variations ) {
                    if ( typeof( variation ) !== 'undefined' && first_attr_name in variation.attributes ) {
                        let attr_val         = variation.attributes[ first_attr_name ],
                            variation_active = variation.variation_is_active ? 'enabled' : '';
    
                        if ( attr_val ) {
                            // Decode entities.
                            attr_val = $( '<div/>' ).html( attr_val ).text();
    
                            // Attach to matching options by value. This is done to compare
                            // TEXT values rather than any HTML entities.
                            var $option_elements = new_attr_select.find( 'option' );
                            for (var i = 0, len = $option_elements.length; i < len; i++) {
                                var $option_element = $( $option_elements[i] ),
                                    option_value = $option_element.val();
    
                                if ( attr_val === option_value ) {
                                    $option_element.addClass( 'attached ' + variation_active );
                                    break;
                                }
                            }
                        } else {
                            // Attach all apart from placeholder.
                            new_attr_select.find( 'option:gt(0)' ).addClass( 'attached ' + variation_active );
                        }
                    }
                }
    
                // Count available options.
                attached_options_count = new_attr_select.find( 'option.attached' ).length;
    
                // Check if current selection is in attached options.
                if ( first_attr_val ) {
                    first_attr_val_valid = false;
    
                    if ( 0 !== attached_options_count ) {
                        new_attr_select.find( 'option.attached.enabled' ).each( function() {
                            var option_value = $( this ).val();
    
                            if ( first_attr_val === option_value ) {
                                first_attr_val_valid = true;
                                return false; // break.
                            }
                        });
                    }
                }
    
                // Detach the placeholder if:
                // - Valid options exist.
                // - The current selection is non-empty.
                // - The current selection is valid.
                // - Placeholders are not set to be permanently visible.
                if ( attached_options_count > 0 && first_attr_val && first_attr_val_valid && ( 'no' === show_option_none ) ) {
                    new_attr_select.find( 'option:first' ).remove();
                    option_gt_filter = '';
                }
    
                // Detach unattached.
                new_attr_select.find( 'option' + option_gt_filter + ':not(.attached)' ).remove();
    
                // Finally, copy to DOM and set value.
                $first_attr_select.html( new_attr_select.html() );
                $first_attr_select.find( 'option' + option_gt_filter + ':not(.enabled)' ).prop( 'disabled', true );
    
                // Choose selected value.
                if ( first_attr_val ) {
                    // If the previously selected value is no longer available, fall back to the placeholder (it's going to be there).
                    if ( first_attr_val_valid ) {
                        $first_attr_select.val( first_attr_val );
                    } else {
                        $first_attr_select.val( '' ).change();
                    }
                } else {
                    $first_attr_select.val( '' ); // No change event to prevent infinite loop.
                }
    
            });
        }
    });
    

    【讨论】:

    • 哇,这似乎有效!所以你现在的方法是第一个属性获取所有值,独立于第二个下拉列表中的选定值?
    • 是的,当然 :-) 实际上我付出了很多努力。
    • @LuukVanDongen 如果我的回答有帮助,请给予慷慨的赏金。 :-)
    猜你喜欢
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 2019-09-27
    • 2017-01-14
    • 1970-01-01
    • 2018-06-06
    相关资源
    最近更新 更多