wordpress 常用函数 checked(),selected(),disabled()

本文详细介绍了如何在自定义widget中使用selected()函数实现下拉菜单默认选中的功能,通过比较保存的值和当前值,使指定选项默认处于选中状态。

checked()、selected()、disabled(),这三个函数是主题设计和插件设计中添加后台设置比较常用到的函数。
例如自定义一个widget,这个widget有一个字段为文章排列方式。文章排列方式有:按时间、评论数、随机等。我们在制作这个widget时会做一个selected下拉菜单。当我们选择一个选项,如:按时间。那么下次我们打开这个widget时,就会希望下拉菜单默认是选中按时间这个选项。这就是 checked(),selected(),disabled() 的应用场景。以下以selected()为例子:

selected()

用在表单中的下拉菜单,用于比较两个给定的值(比如:保存的值和当前的值),如果值相同,给当前的选项添加 selected 属性。

用法

<?php selected( $selected, $current, $echo); ?>  

参数

$selected
(mixed) (required) 用于比较的值,已经在数据库中保存的。
Default: None

$current
(mixed) (optional) 另外的值(如果不为 true),当前选项的值。
Default: true

$echo
(boolean) (optional) 返回结果是输出还是返回字符串。
Default: true

代码

<!-- 使用 if() 来测试值 -->   
<select name="options[foo]">   
<option value="1" <?php if ( $options['foo'] == 1 ) echo 'selected="selected"'; ?>>1</option>   
<option value="2" <?php if ( $options['foo'] == 2 ) echo 'selected="selected"'; ?>>2</option>   
<option value="3" <?php if ( $options['foo'] == 3 ) echo 'selected="selected"'; ?>>3</option>   
</select> 
 

<!-- 使用 selected() -->   
<select name="options[foo]">   
<option value="1" <?php selected( $options['foo'], 1 ); ?>>1</option>   
<option value="2" <?php selected( $options['foo'], 2 ); ?>>2</option>   
<option value="3" <?php selected( $options['foo'], 3 ); ?>>3</option>   
</select>  

转载于:https://www.cnblogs.com/flowerszhong/p/5286333.html

This is the full code in my cart.php <?php /** * Custom Cart Page for WooCommerce with Selective Checkout * Place this file in your child theme directory: /wp-content/themes/woodmart-child/cart.php */ if (!defined('ABSPATH')) { exit; // Exit if accessed directly } do_action('woocommerce_before_cart'); ?> <div class="cart-page-section container" style="max-width: 1200px; margin: 0 auto;"> <form class="woocommerce-cart-form" action="<?php echo esc_url(wc_get_cart_url()); ?>" method="post"> <?php do_action('woocommerce_before_cart_table'); ?> <table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents"> <thead> <tr> <th class="product-select"> <input type="checkbox" id="select-all-items" /> <label for="select-all-items" style="display: inline-block; margin-left: 5px; cursor: pointer;">全选</label> </th> <th class="product-info"><?php esc_html_e('Product', 'woocommerce'); ?></th> <th class="product-params"><?php esc_html_e('Parameters', 'woocommerce'); ?></th> <th class="product-price"><?php esc_html_e('Price', 'woocommerce'); ?></th> <th class="product-quantity"><?php esc_html_e('Quantity', 'woocommerce'); ?></th> <th class="product-subtotal"><?php esc_html_e('Subtotal', 'woocommerce'); ?></th> <!-- 已移除 Action 列 --> </tr> </thead> <tbody> <?php do_action('woocommerce_before_cart_contents'); ?> <?php foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) : $_product = apply_filters('woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key); $product_id = apply_filters('woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key); if ($_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters('woocommerce_cart_item_visible', true, $cart_item, $cart_item_key)) : $product_permalink = apply_filters('woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink($cart_item) : '', $cart_item, $cart_item_key); ?> <tr class="woocommerce-cart-form__cart-item <?php echo esc_attr(apply_filters('woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key)); ?>"> <!-- Checkbox Column --> <td class="product-select" data-title="<?php esc_attr_e('Select', 'woocommerce'); ?>"> <input type="checkbox" class="item-checkbox" name="selected_items[]" value="<?php echo esc_attr($cart_item_key); ?>" data-price="<?php echo esc_attr($cart_item['line_total']); ?>" /> </td> <!-- Product Info Column --> <td class="product-info" data-title="<?php esc_attr_e('Product', 'woocommerce'); ?>"> <div class="product-image"> <?php $thumbnail = apply_filters('woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key); if (!$product_permalink) : echo $thumbnail; // PHPCS: XSS ok. else : printf('<a href="%s">%s</a>', esc_url($product_permalink), $thumbnail); // PHPCS: XSS ok. endif; ?> </div> <div class="product-name"> <?php if (!$product_permalink) : echo wp_kses_post(apply_filters('woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key) . ' '); else : echo wp_kses_post(apply_filters('woocommerce_cart_item_name', sprintf('<a href="%s">%s</a>', esc_url($product_permalink), $_product->get_name()), $cart_item, $cart_item_key)); endif; do_action('woocommerce_after_cart_item_name', $cart_item, $cart_item_key); // Meta data. echo wc_get_formatted_cart_item_data($cart_item); // PHPCS: XSS ok. ?> </div> </td> <!-- Product Parameters Column --> <td class="product-params" data-title="<?php esc_attr_e('Parameters', 'woocommerce'); ?>"> <?php if ($cart_item['variation_id']) { $variation_attributes = $_product->get_variation_attributes(); if (!empty($variation_attributes)) { foreach ($variation_attributes as $attribute => $value) { echo '<span class="param">' . esc_html(wc_attribute_label($attribute)) . ': ' . esc_html($value) . '</span><br>'; } } } else { $attributes = $_product->get_attributes(); if (!empty($attributes)) { foreach ($attributes as $attribute) { $values = wc_get_product_terms($product_id, $attribute['name'], array('fields' => 'names')); echo '<span class="param">' . esc_html(wc_attribute_label($attribute['name'])) . ': ' . esc_html(implode(', ', $values)) . '</span><br>'; } } } ?> </td> <!-- Price Column --> <td class="product-price" data-title="<?php esc_attr_e('Price', 'woocommerce'); ?>"> <?php echo apply_filters('woocommerce_cart_item_price', WC()->cart->get_product_price($_product), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?> </td> <!-- Quantity Column --> <td class="product-quantity" data-title="<?php esc_attr_e('Quantity', 'woocommerce'); ?>"> <?php if ($_product->is_sold_individually()) : $product_quantity = sprintf('1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key); else : $product_quantity = woocommerce_quantity_input( array( 'input_name' => "cart[{$cart_item_key}][qty]", 'input_value' => $cart_item['quantity'], 'max_value' => $_product->get_max_purchase_quantity(), 'min_value' => '0', 'product_name' => $_product->get_name(), ), $_product, false ); endif; echo apply_filters('woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item); // PHPCS: XSS ok. ?> </td> <!-- Subtotal Column --> <td class="product-subtotal" data-title="<?php esc_attr_e('Subtotal', 'woocommerce'); ?>"> <?php echo apply_filters('woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal($_product, $cart_item['quantity']), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?> </td> <!-- 已移除 Remove Item Column --> </tr> <?php endif; ?> <?php endforeach; ?> <?php do_action('woocommerce_after_cart_contents'); ?> </tbody> </table> <div class="actions"> <button type="submit" class="button" name="update_cart" value="<?php esc_attr_e('Update cart', 'woocommerce'); ?>"><?php esc_html_e('Update cart', 'woocommerce'); ?></button> <?php do_action('woocommerce_cart_actions'); ?> <?php wp_nonce_field('woocommerce-cart', 'woocommerce-cart-nonce'); ?> </div> <?php do_action('woocommerce_after_cart_table'); ?> </form> </div> <!-- Sticky Footer --> <div class="cart-footer-actions sticky-footer" style="position: sticky; bottom: 0; background: white; padding: 15px; border-top: 1px solid #ddd; max-width: 1200px; margin: 0 auto;"> <div style="display: flex; justify-content: space-between; align-items: center;"> <div> <input type="checkbox" id="footer-select-all"> <label for="footer-select-all" style="display: inline-block; margin-left: 5px; cursor: pointer;">全选</label> <button type="button" class="button" id="remove-selected-items">刪除選中的商品</button> <button type="button" class="button" id="clear-cart">清理購物車</button> </div> <div class="selected-summary" style="text-align: right;"> <p> 已选商品: <span id="selected-count">0</span> 件,共计: <span id="selected-total">RM0.00</span> </p> <a href="<?php echo esc_url(wc_get_checkout_url()); ?>" class="checkout-button button alt wc-forward" id="partial-checkout"> 结算 </a> </div> </div> </div> <?php do_action('woocommerce_after_cart'); ?> <style> /* Custom Styles for Cart Page */ .cart-page-section { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); margin-bottom: 30px; } .cart-page-section table.cart { width: 100%; border-collapse: collapse; margin-bottom: 20px; } .cart-page-section table.cart th, .cart-page-section table.cart td { padding: 15px; text-align: left; border-bottom: 1px solid #eee; } .cart-page-section table.cart th { background-color: #f8f8f8; font-weight: bold; } /* 调整列宽 */ .cart-page-section table.cart td.product-select { width: 10%; text-align: center; vertical-align: middle; } .cart-page-section table.cart td.product-info { width: 20%; vertical-align: top; } .cart-page-section table.cart .product-info .product-image { float: left; margin-right: 15px; width: 100px; height: 100px; } .cart-page-section table.cart .product-info .product-image img { max-width: 100%; height: auto; display: block; } .cart-page-section table.cart .product-info .product-name { overflow: hidden; } .cart-page-section table.cart td.product-params { width: 20%; vertical-align: top; } .cart-page-section table.cart .product-params .param { display: block; margin-bottom: 5px; font-size: 14px; color: #666; } /* 调整剩余列宽度 */ .cart-page-section table.cart td.product-price, .cart-page-section table.cart td.product-quantity, .cart-page-section table.cart td.product-subtotal { width: 16.67%; /* 三列平均分配剩余宽度 */ vertical-align: middle; } .cart-page-section .actions { text-align: right; margin-top: 20px; } .cart-page-section .actions .button { padding: 12px 24px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; transition: background-color 0.3s; } .cart-page-section .actions .button:hover { background-color: #45a049; } .cart-footer-actions { position: sticky; bottom: 0; background: #fff; padding: 15px; border-top: 1px solid #ddd; box-shadow: 0 -2px 10px rgba(0,0,0,0.1); z-index: 100; } .cart-footer-actions .button { padding: 10px 20px; margin-left: 10px; background-color: #f44336; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; transition: background-color 0.3s; } .cart-footer-actions .button:hover { background-color: #d32f2f; } #partial-checkout { padding: 12px 24px; background-color: #2196F3; color: white; text-decoration: none; border-radius: 4px; display: inline-block; margin-top: 10px; transition: background-color 0.3s; } #partial-checkout:hover { background-color: #0b7dda; } .selected-summary { font-size: 16px; font-weight: bold; } .selected-summary p { margin: 0 0 10px 0; } /* Responsive styles */ @media (max-width: 768px) { .cart-page-section table.cart thead { display: none; } .cart-page-section table.cart td { display: block; width: 100% !important; text-align: right; padding: 10px; position: relative; padding-left: 50%; } .cart-page-section table.cart td::before { content: attr(data-title); position: absolute; left: 15px; font-weight: bold; text-align: left; } .cart-page-section table.cart .product-info .product-image { float: none; margin: 0 auto 10px; } .cart-footer-actions { position: relative; } .cart-footer-actions > div { flex-direction: column; align-items: flex-start; } .cart-footer-actions .selected-summary { margin-top: 20px; text-align: left; width: 100%; } } </style> <script> jQuery(document).ready(function($) { // Define our AJAX parameters var wc_cart_params = { ajax_url: '<?php echo admin_url('admin-ajax.php'); ?>', cart_nonce: '<?php echo wp_create_nonce('woocommerce-cart'); ?>' }; // Update selected items summary function updateSelectedSummary() { let total = 0; let count = 0; $('.item-checkbox:checked').each(function() { total += parseFloat($(this).data('price')); count++; }); $('#selected-count').text(count); $('#selected-total').text('RM' + total.toFixed(2)); } // Select all functionality $('#select-all-items, #footer-select-all').change(function() { const isChecked = $(this).prop('checked'); $('.item-checkbox').prop('checked', isChecked); updateSelectedSummary(); }); // Individual checkbox change $('.item-checkbox').change(updateSelectedSummary); // Remove selected items $('#remove-selected-items').click(function() { const selectedKeys = $('.item-checkbox:checked').map(function() { return this.value; }).get(); if (selectedKeys.length === 0) { alert('请选择要删除的商品'); return; } if (!confirm('确定要删除选中的商品吗?')) { return; } $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'remove_selected_cart_items', selected_items: selectedKeys, security: wc_cart_params.cart_nonce }, success: function(response) { if (response.success) { location.reload(); } }, error: function() { alert('删除失败,请重试'); } }); }); // Clear entire cart $('#clear-cart').click(function() { if (!confirm('确定要清空购物车吗?')) { return; } $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'clear_entire_cart', security: wc_cart_params.cart_nonce }, success: function(response) { if (response.success) { location.reload(); } }, error: function() { alert('清空购物车失败,请重试'); } }); }); // Partial checkout $('#partial-checkout').click(function(e) { e.preventDefault(); const selectedKeys = $('.item-checkbox:checked').map(function() { return this.value; }).get(); if (selectedKeys.length === 0) { alert('请至少选择一件商品结算'); return false; } // Show loading indicator $(this).html('处理中...').prop('disabled', true); // Store selected items in session $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'store_selected_items', selected_items: selectedKeys, security: wc_cart_params.cart_nonce }, success: function(response) { if (response.success) { window.location.href = '<?php echo esc_url(wc_get_checkout_url()); ?>'; } else { alert('结算失败,请重试'); $('#partial-checkout').html('结算').prop('disabled', false); } }, error: function() { alert('发生错误,请重试'); $('#partial-checkout').html('结算').prop('disabled', false); } }); }); // Initialize summary updateSelectedSummary(); }); </script> This is the full code in my functions.php // 完全删除旧的"部分结账"相关代码 // 替换为以下完整优化版本 // ===== 部分结账功能核心代码 ===== // // 存储选中商品到会话 add_action('wp_ajax_store_selected_items', 'store_selected_items'); add_action('wp_ajax_nopriv_store_selected_items', 'store_selected_items'); function store_selected_items() { check_ajax_referer('woocommerce-cart', 'security'); if (isset($_POST['selected_items'])) { $sanitized_items = array_map('sanitize_text_field', $_POST['selected_items']); WC()->session->set('selected_checkout_items', $sanitized_items); wp_send_json_success(); } wp_send_json_error(); } // 折扣计算前应用购物车过滤 (解决折扣问题) add_action('woocommerce_before_calculate_totals', 'apply_partial_cart_before_discounts', 5); function apply_partial_cart_before_discounts() { if (!is_checkout() || is_wc_endpoint_url('order-received') || !WC()->session) { return; } $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { $cart = WC()->cart; $cart_contents = $cart->cart_contents; $filtered_contents = array(); foreach ($cart_contents as $key => $item) { if (in_array($key, $selected_items)) { $filtered_contents[$key] = $item; } } $cart->cart_contents = $filtered_contents; } } // 结账页面显示过滤 add_filter('woocommerce_get_cart_contents', 'filter_cart_contents_for_checkout', 20, 1); function filter_cart_contents_for_checkout($cart_contents) { if (is_checkout() && !is_wc_endpoint_url('order-received') && WC()->session) { $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { $filtered_contents = array(); foreach ($cart_contents as $key => $item) { if (in_array($key, $selected_items)) { $filtered_contents[$key] = $item; } } return $filtered_contents; } } return $cart_contents; } // 结账后恢复购物车 add_action('woocommerce_checkout_update_order_meta', 'restore_full_cart_after_checkout', 10, 2); function restore_full_cart_after_checkout($order_id, $data) { if (!WC()->session) return; // 备份完整购物车 $full_cart = WC()->cart->get_cart(); WC()->session->set('full_cart_backup', $full_cart); } // 订单感谢页处理 add_action('woocommerce_thankyou', 'remove_selected_items_after_checkout', 10, 1); function remove_selected_items_after_checkout($order_id) { if (!WC()->session) return; $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { // 恢复完整购物车 $full_cart = WC()->session->get('full_cart_backup'); if ($full_cart) { WC()->cart->cart_contents = $full_cart; WC()->session->__unset('full_cart_backup'); } WC()->session->__unset('selected_checkout_items'); WC()->cart->calculate_totals(); } } // AJAX移除选中商品 add_action('wp_ajax_remove_selected_cart_items', 'remove_selected_cart_items'); add_action('wp_ajax_nopriv_remove_selected_cart_items', 'remove_selected_cart_items'); function remove_selected_cart_items() { check_ajax_referer('woocommerce-cart', 'security'); if (isset($_POST['selected_items'])) { foreach ($_POST['selected_items'] as $cart_item_key) { $sanitized_key = sanitize_text_field($cart_item_key); if (WC()->cart->get_cart_item($sanitized_key)) { WC()->cart->remove_cart_item($sanitized_key); } } wp_send_json_success(); } wp_send_json_error(); } // 覆盖购物车清空方法 add_action('woocommerce_init', 'override_woocommerce_cart'); function override_woocommerce_cart() { if (!class_exists('WC_Cart') || !WC()->session) return; class WC_Cart_Custom extends WC_Cart { public function empty_cart($force_session = false) { if (WC()->session && WC()->session->get('selected_checkout_items')) { return; // 阻止清空 } parent::empty_cart($force_session); } } $GLOBALS['woocommerce']->cart = new WC_Cart_Custom(); } // ===== 辅助功能 ===== // // 移除购物车总计部分 add_action('template_redirect', 'remove_cart_totals_section'); function remove_cart_totals_section() { if (is_cart()) { remove_action('woocommerce_cart_collaterals', 'woocommerce_cart_totals', 10); } } // 加载必要脚本 add_action('wp_enqueue_scripts', 'partial_checkout_scripts'); function partial_checkout_scripts() { if (is_cart()) { wp_enqueue_script('wc-cart'); wp_localize_script('wc-cart', 'wc_cart_params', array( 'ajax_url' => admin_url('admin-ajax.php'), 'cart_nonce' => wp_create_nonce('woocommerce-cart') )); } } // 放弃结账时恢复原始购物车 add_action('template_redirect', 'restore_original_cart_if_abandoned'); function restore_original_cart_if_abandoned() { if (is_cart() && WC()->session && WC()->session->get('selected_checkout_items')) { WC()->session->__unset('selected_checkout_items'); } } the dynamic discount is not applied, Without changing the 成功了的 function, please check which part goes wrong and give me the full code to be replaced with the current one.
08-01
is this the full code for javascript partt in my cart.php? becase the javascript part is not functioning <script> jQuery(function($) { // ============================================= // 核心功能函数 // ============================================= // 实用工具:全选辅助函数 function getHeaderSA() { return $('#select-all-items, #select-all-items-header').length ? $('#select-all-items, #select-all-items-header') : $('table.shop_table thead th.product-select input[type="checkbox"]').first(); } function getFooterSA() { return $('#footer-select-all, #select-all-items-footer').length ? $('#footer-select-all, #select-all-items-footer') : $('.cart-footer-actions input[type="checkbox"]').first(); } function $items() { return $('.woocommerce-cart-form .item-checkbox'); } // AJAX 助手函数 function getAjaxUrl() { return (window.wc_cart_params && window.wc_cart_params.ajax_url) || '<?php echo esc_url(admin_url("admin-ajax.php")); ?>'; } function getCartNonce() { const n = $('input[name="woocommerce-cart-nonce"]').val(); return n || '<?php echo wp_create_nonce("woocommerce-cart"); ?>'; } function fmtRM(n) { return 'RM' + (isNaN(n) ? 0 : n).toFixed(2); } // ============================================= // 收藏列表管理(兼容 Woodmart 主题) // ============================================= // 获取收藏列表 function getScWishlist() { try { // 优先使用 Woodmart 主题的收藏列表 if (typeof window.woodmart !== 'undefined' && window.woodmart.wishlist) { const woodmartList = window.woodmart.wishlist.getWishlist(); return woodmartList.map(item => ({ productId: item.product_id, variationId: item.variation_id || 0 })); } // 使用本地存储作为备用 const wishlistJson = localStorage.getItem('sc_wishlist'); return wishlistJson ? JSON.parse(wishlistJson) : []; } catch (error) { console.error('获取收藏列表出错:', error); return []; } } // 保存收藏列表 function saveScWishlist(wishlist) { try { // 优先同步到 Woodmart 主题 if (typeof window.woodmart !== 'undefined' && window.woodmart.wishlist) { // 清空现有收藏 window.woodmart.wishlist.clearCache(); // 重新添加所有项目 wishlist.forEach(item => { window.woodmart.wishlist.add(item.productId, item.variationId); }); } // 保存到本地存储 localStorage.setItem('sc_wishlist', JSON.stringify(wishlist)); return true; } catch (error) { console.error('保存收藏列表出错:', error); return false; } } // 检查商品是否在收藏列表中 function isInScWishlist(productId, variationId = 0) { try { const wishlist = getScWishlist(); return wishlist.some(item => parseInt(item.productId) === parseInt(productId) && parseInt(item.variationId || 0) === parseInt(variationId || 0) ); } catch (error) { console.error('检查收藏状态出错:', error); return false; } } // 添加到收藏列表 function addToScWishlist(productId, variationId = 0) { try { const wishlist = getScWishlist(); // 检查是否已存在 const exists = wishlist.some(item => parseInt(item.productId) === parseInt(productId) && parseInt(item.variationId || 0) === parseInt(variationId || 0) ); if (!exists) { wishlist.push({ productId: parseInt(productId), variationId: variationId ? parseInt(variationId) : 0 }); return saveScWishlist(wishlist); } return false; // 已存在 } catch (error) { console.error('添加收藏出错:', error); return false; } } // 从收藏列表移除 function removeFromScWishlist(productId, variationId = 0) { try { const wishlist = getScWishlist(); const initialLength = wishlist.length; const filtered = wishlist.filter(item => !(parseInt(item.productId) === parseInt(productId) && parseInt(item.variationId || 0) === parseInt(variationId || 0)) ); if (filtered.length !== initialLength) { return saveScWishlist(filtered); } return false; // 未找到 } catch (error) { console.error('移除收藏出错:', error); return false; } } // ============================================= // 收藏按钮状态管理 // ============================================= // 更新所有收藏按钮状态 function updateWishlistButtons() { $('.wishlist-btn').each(function() { const $btn = $(this); const productId = $btn.data('product-id'); const variationId = $btn.data('variation-id') || 0; const inWishlist = isInScWishlist(productId, variationId); $btn.toggleClass('added', inWishlist); $btn.attr('title', inWishlist ? '浏览收藏列表' : '加入收藏'); $btn.data('in-wishlist', inWishlist.toString()); // 控制台日志用于调试 console.log(`产品 ${productId} (变体 ${variationId}) 收藏状态: ${inWishlist}`); }); } // 收藏状态同步机制 function setupWishlistSync() { // 监听本地存储变化(跨标签页同步) $(window).on('storage', function(e) { if (e.originalEvent.key === 'sc_wishlist') { console.log('检测到收藏列表变化,更新按钮状态...'); updateWishlistButtons(); } }); // 自定义事件监听(同一页面内同步) $(document).on('wishlistUpdated', function() { console.log('收到自定义收藏更新事件'); updateWishlistButtons(); }); // 每5秒检查一次状态(防止意外不同步) setInterval(updateWishlistButtons, 5000); } // 处理收藏按钮点击 function handleWishlistButtonClick(e) { e.preventDefault(); const $btn = $(this); const productId = $btn.data('product-id'); const variationId = $btn.data('variation-id') || 0; const inWishlist = $btn.data('in-wishlist') === 'true'; console.log('收藏按钮点击', { productId, variationId, inWishlist }); if (inWishlist) { // 已在收藏列表中 - 跳转到收藏页面 console.log('跳转到收藏列表页面'); window.location.href = "<?php echo home_url('/wishlist'); ?>"; } else { // 添加到收藏列表 if (addToScWishlist(productId, variationId)) { console.log('成功添加到收藏列表'); showWishlistMessage('商品已添加到收藏列表', 'success'); // 更新按钮状态 updateWishlistButtons(); // 触发同步事件 $(document).trigger('wishlistUpdated'); window.dispatchEvent(new Event('storage')); } else { console.log('添加失败或已在收藏列表中'); showWishlistMessage('商品已在收藏列表中', 'info'); } } } // 显示收藏操作消息 function showWishlistMessage(message, type = 'success') { $('.wishlist-message').remove(); const bgColor = type === 'success' ? '#4CAF50' : type === 'error' ? '#f44336' : '#2196F3'; const $message = $(` <div class="wishlist-message ${type}" style="background: ${bgColor}"> ${message} </div> `); $('body').append($message); setTimeout(() => { $message.fadeOut(300, function() { $(this).remove(); }); }, 3000); } // ============================================= // 购物车核心功能 // ============================================= // 更新选中商品摘要 function updateSelectedSummary() { let count = 0, total = 0; $('.item-checkbox:checked').each(function() { const quantity = parseFloat($(this).data('quantity')) || 1; const price = parseFloat($(this).data('price')) || 0; count += quantity; total += price; }); $('#selected-count').text(count); $('#selected-total').text(fmtRM(total)); } // 全选逻辑 function refreshSelectAllFromItems() { const $all = $items(); const total = $all.length; const checked = $all.filter(':checked').length; const allChecked = total > 0 && checked === total; getHeaderSA().prop('checked', allChecked); getFooterSA().prop('checked', allChecked); } // 修复删除按钮显示 function fixRemoveButtonDisplay() { $('<style>.product-remove .remove::before { content: "" !important; }</style>').appendTo('head'); $('.product-remove .remove').each(function() { const $btn = $(this); if ($btn.html().trim() === '') { $btn.html('X'); } }); } // 获取商品库存信息 function getProductStockInfo(productId, variationId = 0) { return new Promise((resolve) => { $.post(getAjaxUrl(), { action: 'get_product_stock_info', security: getCartNonce(), product_id: productId, variation_id: variationId }, function(response) { response && response.success ? resolve(response.data) : resolve({}); }).fail(() => resolve({})); }); } // 初始化库存数据 async function initializeStockData() { const promises = []; $('.item-checkbox').each(function() { const $checkbox = $(this); const $row = $checkbox.closest('tr'); const $input = $row.find('.qty'); const productId = $checkbox.data('product-id'); const variationId = $checkbox.data('variation-id') || 0; if (productId) { const promise = getProductStockInfo(productId, variationId).then(stockInfo => { const maxStock = stockInfo.stock_quantity || stockInfo.max_purchase_quantity || 0; if (maxStock > 0) { $input.attr({ 'max': maxStock, 'data-stock': maxStock }); const currentQty = parseInt($input.val()) || 1; if (currentQty > maxStock) { $input.val(maxStock); $checkbox.data('quantity', maxStock).attr('data-quantity', maxStock); setTimeout(() => saveQuantityAjax($input, true), 500); } } }); promises.push(promise); } }); await Promise.all(promises); } // 处理库存超限 function handleOverstock($input, immediateSave = false) { const maxStock = parseInt($input.attr('data-stock')) || parseInt($input.attr('max')) || 0; const currentQty = parseInt($input.val()) || 0; if (maxStock > 0 && currentQty > maxStock) { alert(`此商品库存仅剩 ${maxStock}`); $input.val(maxStock); if (immediateSave) saveQuantityAjax($input, false); return true; } return false; } // 保存数量变更 function saveQuantityAjax($input, showNotice = true) { if (!$input.length) return; const $row = $input.closest('tr'); const cart_item_key = $row.find('.item-checkbox').val(); let newQty = parseFloat($input.val()) || 1; if (handleOverstock($input, false)) { newQty = parseFloat($input.val()) || 1; } $input.prop('disabled', true); $row.find('.plus, .minus').prop('disabled', true); $.post(getAjaxUrl(), { action: 'update_cart_item_qty', security: getCartNonce(), cart_item_key, qty: newQty }, function(response) { if (response?.success) { const d = response.data || {}; const $checkbox = $row.find('.item-checkbox'); if (d.subtotal_html) $row.find('.product-subtotal').html(d.subtotal_html); if (d.discounted_price) $checkbox.data('price', d.discounted_price).attr('data-price', d.discounted_price); if (d.unit_price) $checkbox.data('unit-price', d.unit_price).attr('data-unit-price', d.unit_price); if (d.adjusted_qty) $input.val(d.adjusted_qty).attr('data-quantity', d.adjusted_qty); if (d.max_stock) $input.attr('max', d.max_stock).attr('data-stock', d.max_stock); if (showNotice && d.notice) alert(d.notice); if (d.unit_price !== undefined) $row.find('td.product-price').html(fmtRM(d.unit_price)); updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); } }).always(function() { $input.prop('disabled', false); $row.find('.plus, .minus').prop('disabled', false); }); } // ============================================= // 事件绑定 // ============================================= function bindEvents() { // 商品选择变更 $(document).on('change', '.woocommerce-cart-form .item-checkbox', function() { updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); }); // 顶部全选 $(document).on('change', '#select-all-items, #select-all-items-header, table.shop_table thead th.product-select input[type="checkbox"]', function() { const checked = $(this).prop('checked'); $items().prop('checked', checked).trigger('change'); }); // 底部全选 $(document).on('change', '#footer-select-all, #select-all-items-footer, .cart-footer-actions input[type="checkbox"]', function() { const checked = $(this).prop('checked'); const $header = getHeaderSA(); $header.length ? $header.prop('checked', checked).trigger('change') : $items().prop('checked', checked).trigger('change'); }); // 数量输入事件 $('.woocommerce-cart-form').on({ 'input change': function() { handleOverstock($(this), false); }, 'blur': function() { !handleOverstock($(this), false) && saveQuantityAjax($(this), true); }, 'keydown': function(e) { if (e.key === 'Enter') { e.preventDefault(); !handleOverstock($(this), false) && saveQuantityAjax($(this), true); } } }, '.qty'); // 数量按钮 $('body').on('click', '.plus, .minus', function(e) { e.stopImmediatePropagation(); const $input = $(this).closest('.quantity').find('input.qty'); const currentQty = parseInt($input.val()) || 0; const newQty = Math.max(1, currentQty + ($(this).hasClass('plus') ? 1 : -1)); $input.val(newQty); if (!handleOverstock($input, false)) { clearTimeout($input.data('buttonSaveTimer')); $input.data('buttonSaveTimer', setTimeout(() => saveQuantityAjax($input, true), 300)); } }); // 删除选中商品 $('#remove-selected-items').on('click', function() { const keys = $('.item-checkbox:checked').map(function(){ return $(this).val(); }).get(); if (!keys.length) return alert('请先选择要删除的商品'); $.post(getAjaxUrl(), { action: 'remove_selected_cart_items', security: getCartNonce(), cart_item_keys: keys }, function(response) { if (response?.success) { keys.forEach(k => $(`.item-checkbox[value="${k}"]`).closest('tr').remove()); updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); } }); }); // 清空购物车 $('#clear-cart').on('click', function() { if (!confirm('确定要清空整个购物车吗?')) return; $.post(getAjaxUrl(), { action: 'empty_cart', security: getCartNonce() }, function(response) { if (response?.success) { $('.woocommerce-cart-form__cart-item').remove(); updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); } }); }); // 应用优惠券 $('#apply-coupon').on('click', function() { const code = $('#coupon_code').val().trim(); if (!code) return alert('请输入优惠券代码'); $.post(getAjaxUrl(), { action: 'apply_coupon', security: getCartNonce(), coupon_code: code }, function(response) { if (response?.success) { alert('优惠券应用成功!'); setTimeout(() => location.reload(), 300); // 刷新页面更新优惠信息 } else { alert((response.data && response.data.message) || '优惠券应用失败'); } }).fail(() => alert('网络错误,请重试')); }); // 部分结算 $('#partial-checkout').on('click', function(e) { e.preventDefault(); const keys = $('.item-checkbox:checked').map(function(){ return $(this).val(); }).get(); if (keys.length === 0) { alert('请至少选择一件商品结算'); return false; } // 保存选中的商品到 sessionStorage sessionStorage.setItem('selected_cart_items', JSON.stringify(keys)); // 延迟跳转确保 sessionStorage 已设置 setTimeout(() => { window.location.href = $('#partial-checkout').attr('href'); }, 100); }); // 绑定收藏按钮事件 $(document).on('click', '.wishlist-btn', handleWishlistButtonClick); // ============================================= // 初始化函数 // ============================================= // 购物车初始化 async function initializeCart() { // 1. 修复删除按钮显示问题 fixRemoveButtonDisplay(); // 2. 初始化库存数据 await initializeStockData(); // 3. 更新选中商品摘要 updateSelectedSummary(); // 4. 刷新全选状态 refreshSelectAllFromItems(); // 5. 初始化收藏按钮状态 updateWishlistButtons(); // 6. 设置收藏状态同步 setupWishlistSync(); // 7. 绑定所有事件 bindEvents(); console.log('购物车初始化完成'); } // 页面加载时初始化 $(document).ready(function() { initializeCart(); // WooCommerce 片段更新后重新初始化 $(document.body).on('updated_wc_div', function() { setTimeout(initializeCart, 300); }); }); }); </script>
09-27
you only generated halfway until <script> jQuery(function($) { // ============================================= // 核心功能函数 (完整修复版) // ============================================= // 实用工具:全选辅助函数 function getHeaderSA() { return $('#select-all-items').length ? $('#select-all-items') : $('table.shop_table thead th.product-select input[type="checkbox"]').first(); } function getFooterSA() { return $('#footer-select-all').length ? $('#footer-select-all') : $('.cart-footer-actions input[type="checkbox"]').first(); } function $items() { return $('.woocommerce-cart-form .item-checkbox'); } // AJAX 助手函数 function getAjaxUrl() { return (window.wc_cart_params && window.wc_cart_params.ajax_url) || '<?php echo esc_url(admin_url("admin-ajax.php")); ?>'; } function getCartNonce() { const n = $('input[name="woocommerce-cart-nonce"]').val(); return n || '<?php echo wp_create_nonce("woocommerce-cart"); ?>'; } function fmtRM(n) { return 'RM' + (isNaN(n) ? 0 : n).toFixed(2); } // ============================================= // 收藏列表管理(Woodmart主题兼容) // ============================================= // 获取收藏列表 function getScWishlist() { try { // 优先使用Woodmart主题的内部收藏列表 if (typeof window.woodmart !== 'undefined' && window.woodmart.wishlist) { const woodmartList = window.woodmart.wishlist.getWishlist(); if (Array.isArray(woodmartList)) { return woodmartList.map(item => ({ product_id: item.product_id, variation_id: item.variation_id || 0 })); } } // 使用自定义备份收藏列表 const wishlistJson = localStorage.getItem('sc_wishlist'); return wishlistJson ? JSON.parse(wishlistJson) : []; } catch (error) { console.error('获取收藏列表出错:', error); return []; } } // 检查商品是否在收藏列表中 function isInScWishlist(productId, variationId = 0) { try { const wishlist = getScWishlist(); return wishlist.some(item => parseInt(item.product_id) === parseInt(productId) && parseInt(item.variation_id || 0) === parseInt(variationId || 0) ); } catch (error) { console.error('检查收藏状态出错:', error); return false; } } // 添加到收藏列表 function addToScWishlist(productId, variationId = 0) { try { const wishlist = getScWishlist(); const exists = wishlist.some(item => parseInt(item.product_id) === parseInt(productId) && parseInt(item.variation_id || 0) === parseInt(variationId || 0) ); if (!exists) { // 优先使用Woodmart主题的方法 if (typeof window.woodmart !== 'undefined' && window.woodmart.wishlist) { window.woodmart.wishlist.add(productId, variationId); // 确保保存到本地存储 if (typeof window.woodmart.wishlist.save === 'function') { window.woodmart.wishlist.save(); } return true; } // 使用自定义方法 wishlist.push({ product_id: parseInt(productId), variation_id: variationId ? parseInt(variationId) : 0 }); localStorage.setItem('sc_wishlist', JSON.stringify(wishlist)); return true; } return false; // 已存在 } catch (error) { console.error('添加收藏出错:', error); return false; } } // 从收藏列表移除 function removeFromScWishlist(productId, variationId = 0) { try { // 优先使用Woodmart主题的方法 if (typeof window.woodmart !== 'undefined' && window.woodmart.wishlist) { const result = window.woodmart.wishlist.remove(productId, variationId); // 确保保存到本地存储 if (result && typeof window.woodmart.wishlist.save === 'function') { window.woodmart.wishlist.save(); } return result; } // 使用自定义方法 const wishlist = getScWishlist(); const initialLength = wishlist.length; const filtered = wishlist.filter(item => !(parseInt(item.product_id) === parseInt(productId) && parseInt(item.variation_id || 0) === parseInt(variationId || 0)) ); if (filtered.length !== initialLength) { localStorage.setItem('sc_wishlist', JSON.stringify(filtered)); return true; } return false; // 未找到 } catch (error) { console.error('移除收藏出错:', error); return false; } } // ============================================= // 收藏按钮状态管理 // ============================================= // 更新所有收藏按钮状态 function updateWishlistButtons() { $('.wishlist-btn').each(function() { const $btn = $(this); const productId = $btn.data('product-id'); const variationId = $btn.data('variation-id') || 0; const inWishlist = isInScWishlist(productId, variationId); $btn.toggleClass('added', inWishlist); $btn.attr('title', inWishlist ? '浏览收藏列表' : '加入收藏'); }); } // 收藏状态同步机制 function setupWishlistSync() { // 监听本地存储变化(跨标签页同步) $(window).on('storage', function(e) { if (e.originalEvent.key === 'sc_wishlist' || e.originalEvent.key === 'woodmart_wishlist') { updateWishlistButtons(); } }); // 自定义事件监听 $(document).on('wishlistUpdated', function() { setTimeout(updateWishlistButtons, 500); }); } // 处理收藏按钮点击 function handleWishlistButtonClick(e) { e.preventDefault(); const $btn = $(this); const productId = $btn.data('product-id'); const variationId = $btn.data('variation-id') || 0; const inWishlist = isInScWishlist(productId, variationId); if (inWishlist) { if (removeFromScWishlist(productId, variationId)) { showWishlistMessage('商品已从收藏列表移除', 'success'); $btn.removeClass('added'); $btn.attr('title', '加入收藏'); } } else { if (addToScWishlist(productId, variationId)) { showWishlistMessage('商品已添加到收藏列表', 'success'); $btn.addClass('added'); $btn.attr('title', '浏览收藏列表'); } } // 触发同步事件 $(document).trigger('wishlistUpdated'); window.dispatchEvent(new Event('storage')); } // 显示收藏操作消息 function showWishlistMessage(message, type = 'success') { $('.wishlist-message').remove(); const bgColor = type === 'success' ? '#4CAF50' : type === 'error' ? '#f44336' : '#2196F3'; const $message = $(` <div class="wishlist-message ${type}"> ${message} </div> `); $('body').append($message); setTimeout(() => { $message.fadeOut(300, function() { $(this).remove(); }); }, 3000); } // ============================================= // 购物车核心功能 // ============================================= // 更新选中商品摘要 function updateSelectedSummary() { let count = 0, total = 0; $('.item-checkbox:checked').each(function() { const quantity = parseFloat($(this).data('quantity')) || 1; const price = parseFloat($(this).data('price')) || 0; count += quantity; total += price; }); $('#selected-count').text(count); $('#selected-total').text(fmtRM(total)); } // 全选逻辑 function refreshSelectAllFromItems() { const $all = $items(); const total = $all.length; const checked = $all.filter(':checked').length; const allChecked = total > 0 && checked === total; getHeaderSA().prop('checked', allChecked); getFooterSA().prop('checked', allChecked); } // 获取商品库存信息 function getProductStockInfo(productId, variationId = 0) { return new Promise((resolve) => { $.post(getAjaxUrl(), { action: 'get_product_stock_info', security: getCartNonce(), product_id: productId, variation_id: variationId }, function(response) { response && response.success ? resolve(response.data) : resolve({}); }).fail(() => resolve({})); }); } // 初始化库存数据 async function initializeStockData() { const promises = []; $('.item-checkbox').each(function() { const $checkbox = $(this); const $row = $checkbox.closest('tr'); const $input = $row.find('.qty'); const productId = $checkbox.data('product-id'); const variationId = $checkbox.data('variation-id') || 0; if (productId) { const promise = getProductStockInfo(productId, variationId).then(stockInfo => { const maxStock = stockInfo.stock_quantity || stockInfo.max_purchase_quantity || 0; if (maxStock > 0) { $input.attr({ 'max': maxStock, 'data-stock': maxStock }); const currentQty = parseInt($input.val()) || 1; if (currentQty > maxStock) { $input.val(maxStock); $checkbox.data('quantity', maxStock).attr('data-quantity', maxStock); setTimeout(() => saveQuantityAjax($input, true), 500); } } }); promises.push(promise); } }); await Promise.all(promises); } // 处理库存超限 function handleOverstock($input, immediateSave = false) { const maxStock = parseInt($input.attr('data-stock')) || parseInt($input.attr('max')) || 0; const currentQty = parseInt($input.val()) || 0; if (maxStock > 0 && currentQty > maxStock) { alert(`此商品库存仅剩 ${maxStock}`); $input.val(maxStock); if (immediateSave) saveQuantityAjax($input, false); return true; } return false; } // 保存数量变更 function saveQuantityAjax($input, showNotice = true) { if (!$input.length) return; const $row = $input.closest('tr'); const cart_item_key = $row.find('.item-checkbox').val(); let newQty = parseFloat($input.val()) || 1; if (handleOverstock($input, false)) { newQty = parseFloat($input.val()) || 1; } $input.prop('disabled', true); $row.find('.plus, .minus').prop('disabled', true); $.post(getAjaxUrl(), { action: 'update_cart_item_qty', security: getCartNonce(), cart_item_key, qty: newQty }, function(response) { if (response?.success) { const d = response.data || {}; const $checkbox = $row.find('.item-checkbox'); if (d.subtotal_html) $row.find('.product-subtotal').html(d.subtotal_html); if (d.discounted_price) $checkbox.data('price', d.discounted_price).attr('data-price', d.discounted_price); if (d.unit_price) $checkbox.data('unit-price', d.unit_price).attr('data-unit-price', d.unit_price); if (d.adjusted_qty) $input.val(d.adjusted_qty).attr('data-quantity', d.adjusted_qty); if (d.max_stock) $input.attr('max', d.max_stock).attr('data-stock', d.max_stock); if (showNotice && d.notice) alert(d.notice); if (d.unit_price !== undefined) $row.find('td.product-price').html(fmtRM(d.unit_price)); updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); } }).always(function() { $input.prop('disabled', false); $row.find('.plus, .minus').prop('disabled', false); }); } // ============================================= // 事件绑定 // ============================================= function bindEvents() { // 商品选择变更 $(document).on('change', '.woocommerce-cart-form .item-checkbox', function() { updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); }); // 顶部全选 $(document).on('change', '#select-all-items', function() { const checked = $(this).prop('checked'); $items().prop('checked', checked).trigger('change'); }); // 底部全选 $(document).on('change', '#footer-select-all', function() { const checked = $(this).prop('checked'); const $header = getHeaderSA(); $header.length ? $header.prop('checked', checked).trigger('change') : $items().prop('checked', checked).trigger('change'); }); // 数量输入事件 $('.woocommerce-cart-form').on({ 'input change': function() { handleOverstock($(this), false); }, 'blur': function() { !handleOverstock($(this), false) && saveQuantityAjax($(this), true); }, 'keydown': function(e) { if (e.key === 'Enter') { e.preventDefault(); !handleOverstock($(this), false) && saveQuantityAjax($(this), true); } } }, '.qty'); // 数量按钮点击事件 $('body').on('click', '.plus, .minus', function(e) { e.stopImmediatePropagation(); const $input = $(this).closest('.quantity').find('input.qty'); const currentQty = parseInt($input.val()) || 0; const newQty = Math.max(1, currentQty + ($(this).hasClass('plus') ? 1 : -1)); $input.val(newQty); if (!handleOverstock($input, false)) { clearTimeout($input.data('buttonSaveTimer')); $input.data('buttonSaveTimer', setTimeout(() => saveQuantityAjax($input, true), 300)); } }); // 删除选中商品 $('#remove-selected-items').on('click', function() { const keys = $('.item-checkbox:checked').map(function(){ return $(this).val(); }).get(); if (!keys.length) return alert('请先选择要删除的商品'); // 显示确认对话框 if (!confirm(`确定要删除选中的 ${keys.length} 件商品吗?`)) return; $.post(getAjaxUrl(), { action: 'remove_selected_cart_items', security: getCartNonce(), cart_item_keys: keys }, function(response) { if (response?.success) { keys.forEach(k => $(`.item-checkbox[value="${k}"]`).closest('tr').fadeOut(300, function() { $(this).remove(); })); updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); showWishlistMessage('选中的商品已删除', 'success'); } }).fail(() => showWishlistMessage('删除失败,请重试', 'error')); }); // 清空购物车 $('#clear-cart').on('click', function() { if (!confirm('确定要清空整个购物车吗?')) return; $.post(getAjaxUrl(), { action: 'empty_cart', security: getCartNonce() }, function(response) { if (response?.success) { $('.woocommerce-cart-form__cart-item').fadeOut(300, function() { $(this).remove(); updateSelectedSummary(); setTimeout(refreshSelectAllFromItems, 0); }); showWishlistMessage('购物车已清空', 'success'); } }).fail(() => showWishlistMessage('清空失败,请重试', 'error')); }); // 应用优惠券 $('#apply-coupon').on('click', function() { const code = $('#coupon_code').val().trim(); if (!code) return alert('请输入优惠券代码'); $.post(getAjaxUrl(), { action: 'apply_coupon', security: getCartNonce(), coupon_code: code }, function(response) { if (response?.success) { showWishlistMessage('优惠券应用成功!', 'success'); Please continue from // 应用优惠券 $('#apply-coupon').on('click', function() { const code = $('#coupon_code').val().trim(); if (!code) return alert('请输入优惠券代码'); $.post(getAjaxUrl(), { action: 'apply_coupon', security: getCartNonce(), coupon_code: code }, function(response) { if (response?.success) { showWishlistMessage('优惠券应用成功!', 'success');
最新发布
09-27
I would like to 2x check, this would be the code in my cart.php <?php defined('ABSPATH') || exit; do_action('woocommerce_before_cart'); ?> <style> .cart-container { max-width: 1024px; margin: 0 auto; padding: 20px; } .cart-footer { position: sticky; bottom: 0; background: white; padding: 15px; border-top: 1px solid #ddd; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 -2px 10px rgba(0,0,0,0.1); } .cart-footer-left { display: flex; align-items: center; gap: 15px; } .cart-footer-right { display: flex; align-items: center; gap: 15px; } .selected-info { font-weight: bold; } .checkout-btn { background-color: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; } .cart-actions { margin: 20px 0; display: flex; gap: 10px; } .action-btn { padding: 8px 15px; background: #f1f1f1; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; } .action-btn:hover { background: #e9e9e9; } </style> <div class="cart-container"> <form class="woocommerce-cart-form" action="<?php echo esc_url(wc_get_cart_url()); ?>" method="post"> <?php do_action('woocommerce_before_cart_table'); ?> <table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents" cellspacing="0"> <thead> <tr> <th class="product-select"><input type="checkbox" id="select-all"></th> <th class="product-name"><?php esc_html_e('Product', 'woocommerce'); ?></th> <th class="product-attributes"><?php esc_html_e('Attributes', 'woocommerce'); ?></th> <th class="product-price"><?php esc_html_e('Price', 'woocommerce'); ?></th> <th class="product-quantity"><?php esc_html_e('Quantity', 'woocommerce'); ?></th> <th class="product-subtotal"><?php esc_html_e('Subtotal', 'woocommerce'); ?></th> <th class="product-remove"><?php esc_html_e('Action', 'woocommerce'); ?></th> </tr> </thead> <tbody> <?php do_action('woocommerce_before_cart_contents'); ?> <?php foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) { $_product = apply_filters('woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key); $product_id = apply_filters('woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key); if ($_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters('woocommerce_cart_item_visible', true, $cart_item, $cart_item_key)) { $product_permalink = apply_filters('woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink($cart_item) : '', $cart_item, $cart_item_key); ?> <tr class="woocommerce-cart-form__cart-item <?php echo esc_attr(apply_filters('woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key)); ?>"> <!-- 选择框 --> <td class="product-select"> <input type="checkbox" name="selected_items[]" value="<?php echo $cart_item_key; ?>" class="item-checkbox"> </td> <!-- 商品图片和名称 --> <td class="product-name" data-title="<?php esc_attr_e('Product', 'woocommerce'); ?>"> <?php $thumbnail = apply_filters('woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key); if (!$product_permalink) { echo $thumbnail; // PHPCS: XSS ok. } else { printf('<a href="%s">%s</a>', esc_url($product_permalink), $thumbnail); // PHPCS: XSS ok. } ?> <div class="product-info"> <?php if (!$product_permalink) { echo wp_kses_post(apply_filters('woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key) . ' '); } else { echo wp_kses_post(apply_filters('woocommerce_cart_item_name', sprintf('<a href="%s">%s</a>', esc_url($product_permalink), $_product->get_name()), $cart_item, $cart_item_key)); } do_action('woocommerce_after_cart_item_name', $cart_item, $cart_item_key); // Meta data. echo wc_get_formatted_cart_item_data($cart_item); // PHPCS: XSS ok. // Backorder notification. if ($_product->backorders_require_notification() && $_product->is_on_backorder($cart_item['quantity'])) { echo wp_kses_post(apply_filters('woocommerce_cart_item_backorder_notification', '<p class="backorder_notification">' . esc_html__('Available on backorder', 'woocommerce') . '</p>', $product_id)); } ?> </div> </td> <!-- 商品参数 --> <td class="product-attributes" data-title="<?php esc_attr_e('Attributes', 'woocommerce'); ?>"> <?php // 显示自定义属性 $attributes = $_product->get_attributes(); if ($attributes) { foreach ($attributes as $attribute) { if ($attribute->get_visible()) { echo '<div>'.wc_attribute_label($attribute->get_name()).': '; $values = array(); if ($attribute->is_taxonomy()) { $attribute_taxonomy = $attribute->get_taxonomy_object(); $attribute_values = wc_get_product_terms($product_id, $attribute->get_name(), array('fields' => 'all')); foreach ($attribute_values as $attribute_value) { $value_name = esc_html($attribute_value->name); $values[] = $value_name; } } else { $values = $attribute->get_options(); foreach ($values as &$value) { $value = esc_html($value); } } echo apply_filters('woocommerce_attribute', wptexturize(implode(', ', $values)), $attribute, $values); echo '</div>'; } } } ?> </td> <!-- 单价 --> <td class="product-price" data-title="<?php esc_attr_e('Price', 'woocommerce'); ?>"> <?php echo apply_filters('woocommerce_cart_item_price', WC()->cart->get_product_price($_product), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?> </td> <!-- 数量 --> <td class="product-quantity" data-title="<?php esc_attr_e('Quantity', 'woocommerce'); ?>"> <?php if ($_product->is_sold_individually()) { $product_quantity = sprintf('1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key); } else { $product_quantity = woocommerce_quantity_input( array( 'input_name' => "cart[{$cart_item_key}][qty]", 'input_value' => $cart_item['quantity'], 'max_value' => $_product->get_max_purchase_quantity(), 'min_value' => '0', 'product_name' => $_product->get_name(), ), $_product, false ); } echo apply_filters('woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item); // PHPCS: XSS ok. ?> </td> <!-- 小计 --> <td class="product-subtotal" data-title="<?php esc_attr_e('Subtotal', 'woocommerce'); ?>"> <?php echo apply_filters('woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal($_product, $cart_item['quantity']), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?> </td> <!-- 移除按钮 --> <td class="product-remove"> <?php echo apply_filters( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 'woocommerce_cart_item_remove_link', sprintf( '<a href="%s" class="remove" aria-label="%s" data-product_id="%s" data-product_sku="%s">×</a>', esc_url(wc_get_cart_remove_url($cart_item_key)), esc_html__('Remove this item', 'woocommerce'), esc_attr($product_id), esc_attr($_product->get_sku()) ), $cart_item_key ); ?> </td> </tr> <?php } } ?> <?php do_action('woocommerce_cart_contents'); ?> <tr> <td colspan="7" class="actions"> <div class="cart-actions"> <button type="button" class="action-btn" id="remove-selected"><?php esc_html_e('Delete Selected', 'woocommerce'); ?></button> <button type="button" class="action-btn" id="clear-cart"><?php esc_html_e('Clear Cart', 'woocommerce'); ?></button> </div> <?php if (wc_coupons_enabled()) { ?> <div class="coupon"> <label for="coupon_code"><?php esc_html_e('Coupon:', 'woocommerce'); ?></label> <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e('Coupon code', 'woocommerce'); ?>" /> <button type="submit" class="button" name="apply_coupon" value="<?php esc_attr_e('Apply coupon', 'woocommerce'); ?>"><?php esc_attr_e('Apply coupon', 'woocommerce'); ?></button> <?php do_action('woocommerce_cart_coupon'); ?> </div> <?php } ?> <button type="submit" class="button" name="update_cart" value="<?php esc_attr_e('Update cart', 'woocommerce'); ?>"><?php esc_html_e('Update cart', 'woocommerce'); ?></button> <?php do_action('woocommerce_cart_actions'); ?> <?php wp_nonce_field('woocommerce-cart', 'woocommerce-cart-nonce'); ?> </td> </tr> <?php do_action('woocommerce_after_cart_contents'); ?> </tbody> </table> <?php do_action('woocommerce_after_cart_table'); ?> </form> <!-- 底部固定栏 --> <div class="cart-footer"> <div class="cart-footer-left"> <input type="checkbox" id="footer-select-all"> <label for="footer-select-all"><?php esc_html_e('Select all', 'woocommerce'); ?></label> </div> <div class="cart-footer-right"> <div class="selected-info"> <?php esc_html_e('Selected items:', 'woocommerce'); ?> <span id="selected-count">0</span> <?php esc_html_e('Total:', 'woocommerce'); ?> <span id="selected-total">RM0.00</span> </div> <button type="button" class="checkout-btn" id="partial-checkout"> <?php esc_html_e('Proceed to checkout', 'woocommerce'); ?> </button> </div> </div> <?php do_action('woocommerce_before_cart_collaterals'); ?> <div class="cart-collaterals"> <?php /** * Cart collaterals hook. * * @hooked woocommerce_cross_sell_display * @hooked woocommerce_cart_totals - 10 */ do_action('woocommerce_cart_collaterals'); ?> </div> </div> <?php do_action('woocommerce_after_cart'); ?> <script> jQuery(document).ready(function($) { // 全选功能 $('#select-all, #footer-select-all').change(function() { $('.item-checkbox').prop('checked', this.checked); updateSelectedInfo(); }); // 更新选中商品信息 function updateSelectedInfo() { let selectedCount = $('.item-checkbox:checked').length; let total = 0; $('.item-checkbox:checked').each(function() { let itemKey = $(this).val(); let subtotal = $('tr.cart_item').has(this).find('.product-subtotal .amount').html(); if (subtotal) { total += parseFloat(subtotal.replace(/[^\d.-]/g, '')); } }); $('#selected-count').text(selectedCount); $('#selected-total').text('RM' + total.toFixed(2)); } // 初始更新 updateSelectedInfo(); // 监听单个商品选择 $('.item-checkbox').change(updateSelectedInfo); // 删除选中商品 $('#remove-selected').click(function() { let selectedItems = []; $('.item-checkbox:checked').each(function() { selectedItems.push($(this).val()); }); if (selectedItems.length === 0) { alert('<?php esc_html_e("Please select items to remove", "woocommerce"); ?>'); return; } if (confirm('<?php esc_html_e("Are you sure you want to remove the selected items?", "woocommerce"); ?>')) { $.each(selectedItems, function(index, itemKey) { $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'woocommerce_remove_cart_item', cart_item_key: itemKey, security: wc_cart_params.remove_item_nonce }, success: function(response) { $(document.body).trigger('wc_fragment_refresh'); } }); }); } }); // 清空购物车 $('#clear-cart').click(function() { if (confirm('<?php esc_html_e("Are you sure you want to clear your cart?", "woocommerce"); ?>')) { $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'woocommerce_clear_cart', security: wc_cart_params.nonce }, success: function(response) { $(document.body).trigger('wc_fragment_refresh'); } }); } }); // 替换原来的部分结算点击处理 $('#partial-checkout').click(function() { let selectedItems = $('.item-checkbox:checked').map(function() { return $(this).val(); }).get(); if (selectedItems.length === 0) { alert('<?php esc_html_e("Please select at least one item to checkout", "woocommerce"); ?>'); return; } // 添加加载指示器 $(this).prop('disabled', true).html('<?php esc_html_e("Processing...", "woocommerce"); ?>'); // 使用AJAX保存原始购物车状态 $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'wc_save_original_cart', security: wc_cart_params.nonce }, success: function() { // 创建临时表单提交 $('<form>', { 'method': 'post', 'action': '<?php echo esc_url(wc_get_checkout_url()); ?>' }).append($('<input>', { 'type': 'hidden', 'name': 'selected_cart_items', 'value': JSON.stringify(selectedItems) })).appendTo('body').submit(); }, error: function() { alert('<?php esc_html_e("An error occurred. Please try again.", "woocommerce"); ?>'); $('#partial-checkout').prop('disabled', false).html('<?php esc_html_e("Proceed to checkout", "woocommerce"); ?>'); } }); }); </script> This would be the code in my functions.php // 添加清空购物车功能 add_action('wp_ajax_woocommerce_clear_cart', 'woocommerce_clear_cart'); add_action('wp_ajax_nopriv_woocommerce_clear_cart', 'woocommerce_clear_cart'); function woocommerce_clear_cart() { if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'woocommerce-cart')) { wp_send_json_error('Invalid nonce'); } WC()->cart->empty_cart(); wp_send_json_success(); } // 处理部分结算 - 改进版本 add_action('template_redirect', 'handle_partial_checkout'); function handle_partial_checkout() { // 仅在进入结算页面时处理 if (is_checkout() && !is_wc_endpoint_url('order-received') && isset($_POST['selected_cart_items'])) { $selected_items = json_decode(stripslashes($_POST['selected_cart_items']), true); if (!empty($selected_items) && is_array($selected_items)) { // 保存原始购物车到用户元数据(更持久) if (is_user_logged_in()) { $user_id = get_current_user_id(); update_user_meta($user_id, 'wc_original_cart', WC()->cart->get_cart_for_session()); } else { WC()->session->set('wc_original_cart', WC()->cart->get_cart_for_session()); } // 设置临时购物车标记 WC()->session->set('wc_partial_checkout', true); // 创建新购物车只包含选中商品 $new_cart = []; foreach ($selected_items as $item_key) { if (isset(WC()->cart->cart_contents[$item_key])) { $new_cart[$item_key] = WC()->cart->cart_contents[$item_key]; } } // 更新购物车 WC()->cart->cart_contents = $new_cart; WC()->cart->persistent_cart_update(); WC()->cart->calculate_totals(); } } } // 订单完成后恢复原始购物车 add_action('woocommerce_checkout_order_processed', 'restore_original_cart_after_order', 10, 3); function restore_original_cart_after_order($order_id, $posted_data, $order) { if (WC()->session->get('wc_partial_checkout')) { restore_original_cart($order_id); } } // 用户放弃结算时恢复购物车 add_action('template_redirect', 'maybe_restore_cart_on_cart_page'); function maybe_restore_cart_on_cart_page() { if (is_cart() && WC()->session->get('wc_partial_checkout')) { restore_original_cart(); } } // 通用恢复函数 function restore_original_cart($order_id = null) { $original_cart = null; // 尝试从用户元数据获取 if (is_user_logged_in()) { $user_id = get_current_user_id(); $original_cart = get_user_meta($user_id, 'wc_original_cart', true); delete_user_meta($user_id, 'wc_original_cart'); } // 尝试从会话获取 else { $original_cart = WC()->session->get('wc_original_cart'); WC()->session->set('wc_original_cart', null); } if ($original_cart) { WC()->cart->cart_contents = $original_cart; WC()->session->set('wc_partial_checkout', false); WC()->cart->persistent_cart_update(); WC()->cart->calculate_totals(); } } // 保存原始购物车状态 add_action('wp_ajax_wc_save_original_cart', 'wc_save_original_cart'); add_action('wp_ajax_nopriv_wc_save_original_cart', 'wc_save_original_cart'); function wc_save_original_cart() { if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'woocommerce-cart')) { wp_send_json_error('Invalid nonce'); } // 保存原始购物车 if (is_user_logged_in()) { $user_id = get_current_user_id(); update_user_meta($user_id, 'wc_original_cart', WC()->cart->get_cart_for_session()); } else { WC()->session->set('wc_original_cart', WC()->cart->get_cart_for_session()); } wp_send_json_success(); } correct?
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值