You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jQuery调整WooCommerce购物车产品属性显示顺序

Reorder WooCommerce Cart Variation Attributes Without Cross-Item Element Mix-Up

Hey there, let's work through this WooCommerce cart attribute ordering problem you're dealing with. I see you're using multiple plugins to handle custom cabinet door specs, but the attribute order in the cart is messed up—especially when the Boring option is selected. Let's break down how to fix this properly.

The Problem in Detail

Your store uses WooCommerce for custom cabinet doors, with plugins calculating various specs. Right now, when a customer selects the Boring option, the related attributes (Boring, Unit, Specs - Distance 1/2) show up before width/height/area, which isn't ideal. When Boring isn't selected, the order is okay, but we need consistency when it is selected.

Current Cart Display

  • With Boring selected:
    Wood Type: Thickness of Door: Boring ($7.50): Unit: Specs - Distance 1: Specs - Distance 2: Width (in): Height (in): Total Area (sq. ft.)
    Corresponding HTML:
    <dl class="variation">
     <dt class="variation-WoodType">Wood Type:</dt>
     <dd class="variation-WoodType"><p>Mahogany</p></dd>
     <dt class="variation-ThicknessofDoor">Thickness of Door:</dt>
     <dd class="variation-ThicknessofDoor"><p>3/4"</p></dd>
     <dt class="variation-Boringspanclasswoocommerce-Price-amountamountspanclasswoocommerce-Price-currencySymbol36span750span">Boring (<span class="woocommerce-Price-amount amount"><span class="woocommerce-Price-currencySymbol">&#036;</span>7.50</span>):</dt>
     <dd class="variation-Boringspanclasswoocommerce-Price-amountamountspanclasswoocommerce-Price-currencySymbol36span750span"><p>Yes</p></dd>
     <dt class="variation-Unit">Unit:</dt>
     <dd class="variation-Unit"><p>Inches</p></dd>
     <dt class="variation-Specs-Distance1">Specs - Distance 1:</dt>
     <dd class="variation-Specs-Distance1"><p>1</p></dd>
     <dt class="variation-Specs-Distance2">Specs - Distance 2:</dt>
     <dd class="variation-Specs-Distance2"><p>2</p></dd>
     <dt class="variation-Widthin">Width (in):</dt>
     <dd class="variation-Widthin"><p>13</p></dd>
     <dt class="variation-Heightin">Height (in):</dt>
     <dd class="variation-Heightin"><p>18</p></dd>
     <dt class="variation-TotalAreasqft">Total Area (sq. ft.):</dt>
     <dd class="variation-TotalAreasqft"><p>1.63</p></dd>
    </dl>
    
  • Without Boring selected:
    Wood Type: Thickness of Door: Width (in): Height (in): Total Area (sq. ft.)
    Corresponding HTML:
    <dl class="variation">
     <dt class="variation-WoodType">Wood Type:</dt>
     <dd class="variation-WoodType"><p>Poplar</p></dd>
     <dt class="variation-ThicknessofDoor">Thickness of Door:</dt>
     <dd class="variation-ThicknessofDoor"><p>3/4"</p></dd>
     <dt class="variation-Widthin">Width (in):</dt>
     <dd class="variation-Widthin"><p>22</p></dd>
     <dt class="variation-Heightin">Height (in):</dt>
     <dd class="variation-Heightin"><p>22</p></dd>
     <dt class="variation-TotalAreasqft">Total Area (sq. ft.):</dt>
     <dd class="variation-TotalAreasqft"><p>3.36</p></dd>
    </dl>
    

What You Want

You want all Boring-related attributes to come after the width, height, and total area, like this:
Wood Type: Thickness of Door: Width (in): Height (in): Total Area (sq. ft.): Boring ($7.50): Unit: Specs - Distance 1: Specs - Distance 2:

What You Tried (and Why It Broke)

Your initial jQuery code targeted all .variation elements globally, which is why elements from other cart items got moved into the first one. When you tried each(), you probably didn't properly scope the elements to the current cart item, leading to duplicate elements.

The Fix: Scoped jQuery for Per-Item Processing

The key is to process each cart item's variation list individually. Here's the corrected jQuery code that won't mix up elements between items:

(function ($) {
    // Run on page load AND after WooCommerce updates the cart via AJAX
    $(document).on('updated_cart_totals', reorderCartAttributes);
    $(reorderCartAttributes);

    function reorderCartAttributes() {
        // Loop through every variation list in the cart
        $('.variation').each(function() {
            var $currentVariation = $(this);
            
            // Grab the Total Area attribute (dt + dd) — this is our anchor point
            var $totalArea = $currentVariation.find('.variation-TotalAreasqft')
                                              .add($currentVariation.find('.variation-TotalAreasqft').next('dd'));
            
            // Collect all Boring-related attribute pairs (dt + dd)
            var $boringAttributes = $currentVariation.find('.variation-Boringspanclasswoocommerce-Price-amountamountspanclasswoocommerce-Price-currencySymbol36span750span')
                                                    .add($currentVariation.find('.variation-Boringspanclasswoocommerce-Price-amountamountspanclasswoocommerce-Price-currencySymbol36span750span').next('dd'))
                                                    .add($currentVariation.find('.variation-Unit'))
                                                    .add($currentVariation.find('.variation-Unit').next('dd'))
                                                    .add($currentVariation.find('.variation-Specs-Distance1'))
                                                    .add($currentVariation.find('.variation-Specs-Distance1').next('dd'))
                                                    .add($currentVariation.find('.variation-Specs-Distance2'))
                                                    .add($currentVariation.find('.variation-Specs-Distance2').next('dd'));
            
            // Only move the attributes if they exist in this variation
            if ($boringAttributes.length) {
                $totalArea.after($boringAttributes);
            }
        });
    }
})(jQuery);

Why This Works

  1. Scoped to each cart item: The each() loop ensures we only work with elements inside the current .variation dl, so no cross-item mixing.
  2. Handles AJAX updates: The updated_cart_totals event makes sure the code runs again if the cart is updated (like changing quantities), which is crucial for WooCommerce.
  3. Keeps dt/dd pairs together: We always select both the label (dt) and its value (dd) to avoid splitting attribute pairs.
  4. Conditional execution: It only runs the reordering if Boring attributes exist, so it doesn't affect carts where Boring isn't selected.

Even Better: Server-Side PHP Solution

If you want a more reliable fix (no client-side JS dependencies), use WooCommerce's built-in filter to reorder attributes on the server. Add this to your theme's functions.php or a custom plugin:

add_filter('woocommerce_get_item_data', 'custom_reorder_cart_attributes', 10, 2);
function custom_reorder_cart_attributes($item_data, $cart_item) {
    // Define your desired attribute order (match the labels exactly)
    $desired_order = [
        'Wood Type',
        'Thickness of Door',
        'Width (in)',
        'Height (in)',
        'Total Area (sq. ft.)',
        'Boring',
        'Unit',
        'Specs - Distance 1',
        'Specs - Distance 2'
    ];

    $sorted_attributes = [];

    // First add attributes in your desired order
    foreach ($desired_order as $label) {
        foreach ($item_data as $key => $attribute) {
            if (strpos($attribute['name'], $label) !== false) {
                $sorted_attributes[] = $attribute;
                unset($item_data[$key]);
                break;
            }
        }
    }

    // Add any leftover attributes (in case you add new ones later)
    $sorted_attributes = array_merge($sorted_attributes, $item_data);

    return $sorted_attributes;
}

This method works regardless of AJAX updates and avoids any potential JS conflicts. It directly tells WooCommerce the order you want attributes to appear in the cart.

内容的提问来源于stack exchange,提问作者Luke Miller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:58:19