首页 > 解决方案 > Woocommerce 删除按钮删除错误的产品

问题描述

我正在编写一个 woocommerce 网站。在我的商店页面中,我设法从购物车页面插入了“从购物车中删除按钮”代码,但是当我单击该按钮时,它是被删除的购物车的第一个产品(按字母顺序),我怎么知道我的代码以删除我单击的产品

我的网站图片在这里: my-shop-page

我已将此代码放在 content-product.php 中:

    <form class="woocommerce-cart-form" action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post">

        <table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents" cellspacing="0">


                    <?php
                      foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
                            $product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'] );
                          $_product   = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $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 );

                        }
                        break;
                    }
                            ?>
                            <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-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">&times;</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>




                                <td class="product-thumbnail">
                                <?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.
                                }
                                ?>
                                </td>

                                <td class="product-name" data-title="<?php esc_attr_e( 'Product', 'woocommerce' ); ?>">
                                <?php
                                if ( ! $product_permalink ) {
                                    echo wp_kses_post( apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key ) . '&nbsp;' );
                                } 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 ) );
                                }
                                ?>
                                </td>




                </tr>
        </table>
    </form>

我有这个 JS,但我认为问题出在 PHP

        /* global wc_cart_params */
        jQuery( function( $ ) {

            // wc_cart_params is required to continue, ensure the object exists
            if ( typeof wc_cart_params === 'undefined' ) {
                return false;
            }

            // Utility functions for the file.

            /**
             * Gets a url for a given AJAX endpoint.
             *
             * @param {String} endpoint The AJAX Endpoint
             * @return {String} The URL to use for the request
             */
            var get_url = function( endpoint ) {
                return wc_cart_params.wc_ajax_url.toString().replace(
                    '%%endpoint%%',
                    endpoint
                );
            };

            /**
             * Check if a node is blocked for processing.
             *
             * @param {JQuery Object} $node
             * @return {bool} True if the DOM Element is UI Blocked, false if not.
             */
            var is_blocked = function( $node ) {
                return $node.is( '.processing' ) || $node.parents( '.processing' ).length;
            };

            /**
             * Block a node visually for processing.
             *
             * @param {JQuery Object} $node
             */
            var block = function( $node ) {
                if ( ! is_blocked( $node ) ) {
                    $node.addClass( 'processing' ).block( {
                        message: null,
                        overlayCSS: {
                            background: '#fff',
                            opacity: 0.6
                        }
                    } );
                }
            };

            /**
             * Unblock a node after processing is complete.
             *
             * @param {JQuery Object} $node
             */
            var unblock = function( $node ) {
                $node.removeClass( 'processing' ).unblock();
            };

            /**
             * Update the .woocommerce div with a string of html.
             *
             * @param {String} html_str The HTML string with which to replace the div.
             * @param {bool} preserve_notices Should notices be kept? False by default.
             */
            var update_wc_div = function( html_str, preserve_notices ) {
                var $html       = $.parseHTML( html_str );
                var $new_form   = $( '.woocommerce-cart-form', $html );
                var $new_totals = $( '.cart_totals', $html );
                var $notices    = $( '.woocommerce-error, .woocommerce-message, .woocommerce-info', $html );

                // No form, cannot do this.
                if ( $( '.woocommerce-cart-form' ).length === 0 ) {
                    window.location.reload();
                    return;
                }

                // Remove errors
                if ( ! preserve_notices ) {
                    $( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove();
                }

                if ( $new_form.length === 0 ) {
                    // If the checkout is also displayed on this page, trigger reload instead.
                    if ( $( '.woocommerce-checkout' ).length ) {
                        window.location.reload();
                        return;
                    }

                    // No items to display now! Replace all cart content.
                    var $cart_html = $( '.cart-empty', $html ).closest( '.woocommerce' );
                    $( '.woocommerce-cart-form__contents' ).closest( '.woocommerce' ).replaceWith( $cart_html );

                    // Display errors
                    if ( $notices.length > 0 ) {
                        show_notice( $notices );
                    }

                    // Notify plugins that the cart was emptied.
                    $( document.body ).trigger( 'wc_cart_emptied' );
                } else {
                    // If the checkout is also displayed on this page, trigger update event.
                    if ( $( '.woocommerce-checkout' ).length ) {
                        $( document.body ).trigger( 'update_checkout' );
                    }

                    $( '.woocommerce-cart-form' ).replaceWith( $new_form );
                    $( '.woocommerce-cart-form' ).find( ':input[name="update_cart"]' ).prop( 'disabled', true );

                    if ( $notices.length > 0 ) {
                        show_notice( $notices );
                    }

                    update_cart_totals_div( $new_totals );
                }

                $( document.body ).trigger( 'updated_wc_div' );
            };

            /**
             * Update the .cart_totals div with a string of html.
             *
             * @param {String} html_str The HTML string with which to replace the div.
             */
            var update_cart_totals_div = function( html_str ) {
                $( '.cart_totals' ).replaceWith( html_str );
                $( document.body ).trigger( 'updated_cart_totals' );
            };

            /**
             * Shows new notices on the page.
             *
             * @param {Object} The Notice HTML Element in string or object form.
             */
            var show_notice = function( html_element, $target ) {
                if ( ! $target ) {
                    $target = $( '.woocommerce-notices-wrapper:first' ) || $( '.cart-empty' ).closest( '.woocommerce' ) || $( '.woocommerce-cart-form' );
                }
                $target.prepend( html_element );
            };


            /**
             * Object to handle AJAX calls for cart shipping changes.
             */
            var cart_shipping = {

                /**
                 * Initialize event handlers and UI state.
                 */
                init: function( cart ) {
                    this.cart                       = cart;
                    this.toggle_shipping            = this.toggle_shipping.bind( this );
                    this.shipping_method_selected   = this.shipping_method_selected.bind( this );
                    this.shipping_calculator_submit = this.shipping_calculator_submit.bind( this );

                    $( document ).on(
                        'click',
                        '.shipping-calculator-button',
                        this.toggle_shipping
                    );
                    $( document ).on(
                        'change',
                        'select.shipping_method, :input[name^=shipping_method]',
                        this.shipping_method_selected
                    );
                    $( document ).on(
                        'submit',
                        'form.woocommerce-shipping-calculator',
                        this.shipping_calculator_submit
                    );

                    $( '.shipping-calculator-form' ).hide();
                },

                /**
                 * Toggle Shipping Calculator panel
                 */
                toggle_shipping: function() {
                    $( '.shipping-calculator-form' ).slideToggle( 'slow' );
                    $( document.body ).trigger( 'country_to_state_changed' ); // Trigger select2 to load.
                    return false;
                },

                /**
                 * Handles when a shipping method is selected.
                 */
                shipping_method_selected: function() {
                    var shipping_methods = {};

                    $( 'select.shipping_method, :input[name^=shipping_method][type=radio]:checked, :input[name^=shipping_method][type=hidden]' ).each( function() {
                        shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val();
                    } );

                    block( $( 'div.cart_totals' ) );

                    var data = {
                        security: wc_cart_params.update_shipping_method_nonce,
                        shipping_method: shipping_methods
                    };

                    $.ajax( {
                        type:     'post',
                        url:      get_url( 'update_shipping_method' ),
                        data:     data,
                        dataType: 'html',
                        success:  function( response ) {
                            update_cart_totals_div( response );
                        },
                        complete: function() {
                            unblock( $( 'div.cart_totals' ) );
                            $( document.body ).trigger( 'updated_shipping_method' );
                        }
                    } );
                },

                /**
                 * Handles a shipping calculator form submit.
                 *
                 * @param {Object} evt The JQuery event.
                 */
                shipping_calculator_submit: function( evt ) {
                    evt.preventDefault();

                    var $form = $( evt.currentTarget );

                    block( $( 'div.cart_totals' ) );
                    block( $form );

                    // Provide the submit button value because wc-form-handler expects it.
                    $( '<input />' ).attr( 'type', 'hidden' )
                                    .attr( 'name', 'calc_shipping' )
                                    .attr( 'value', 'x' )
                                    .appendTo( $form );

                    // Make call to actual form post URL.
                    $.ajax( {
                        type:     $form.attr( 'method' ),
                        url:      $form.attr( 'action' ),
                        data:     $form.serialize(),
                        dataType: 'html',
                        success:  function( response ) {
                            update_wc_div( response );
                        },
                        complete: function() {
                            unblock( $form );
                            unblock( $( 'div.cart_totals' ) );
                        }
                    } );
                }
            };

            /**
             * Object to handle cart UI.
             */
            var cart = {
                /**
                 * Initialize cart UI events.
                 */
                init: function() {
                    this.update_cart_totals    = this.update_cart_totals.bind( this );
                    this.input_keypress        = this.input_keypress.bind( this );
                    this.cart_submit           = this.cart_submit.bind( this );
                    this.submit_click          = this.submit_click.bind( this );
                    this.apply_coupon          = this.apply_coupon.bind( this );
                    this.remove_coupon_clicked = this.remove_coupon_clicked.bind( this );
                    this.quantity_update       = this.quantity_update.bind( this );
                    this.item_remove_clicked   = this.item_remove_clicked.bind( this );
                    this.item_restore_clicked  = this.item_restore_clicked.bind( this );
                    this.update_cart           = this.update_cart.bind( this );

                    $( document ).on(
                        'wc_update_cart added_to_cart',
                        function() { cart.update_cart.apply( cart, [].slice.call( arguments, 1 ) ); } );
                    $( document ).on(
                        'click',
                        '.woocommerce-cart-form :input[type=submit]',
                        this.submit_click );
                    $( document ).on(
                        'keypress',
                        '.woocommerce-cart-form :input[type=number]',
                        this.input_keypress );
                    $( document ).on(
                        'submit',
                        '.woocommerce-cart-form',
                        this.cart_submit );
                    $( document ).on(
                        'click',
                        'a.woocommerce-remove-coupon',
                        this.remove_coupon_clicked );
                    $( document ).on(
                        'click',
                        '.woocommerce-cart-form .product-remove > a',
                        this.item_remove_clicked );
                    $( document ).on(
                        'click',
                        '.woocommerce-cart .restore-item',
                        this.item_restore_clicked );
                    $( document ).on(
                        'change input',
                        '.woocommerce-cart-form .cart_item :input',
                        this.input_changed );

                    $( '.woocommerce-cart-form :input[name="update_cart"]' ).prop( 'disabled', true );
                },

                /**
                 * After an input is changed, enable the update cart button.
                 */
                input_changed: function() {
                    $( '.woocommerce-cart-form :input[name="update_cart"]' ).prop( 'disabled', false );
                },

                /**
                 * Update entire cart via ajax.
                 */
                update_cart: function( preserve_notices ) {
                    var $form = $( '.woocommerce-cart-form' );

                    block( $form );
                    block( $( 'div.cart_totals' ) );

                    // Make call to actual form post URL.
                    $.ajax( {
                        type:     $form.attr( 'method' ),
                        url:      $form.attr( 'action' ),
                        data:     $form.serialize(),
                        dataType: 'html',
                        success:  function( response ) {
                            update_wc_div( response, preserve_notices );
                        },
                        complete: function() {
                            unblock( $form );
                            unblock( $( 'div.cart_totals' ) );
                            $.scroll_to_notices( $( '[role="alert"]' ) );
                        }
                    } );
                },

                /**
                 * Update the cart after something has changed.
                 */
                update_cart_totals: function() {
                    block( $( 'div.cart_totals' ) );

                    $.ajax( {
                        url:      get_url( 'get_cart_totals' ),
                        dataType: 'html',
                        success:  function( response ) {
                            update_cart_totals_div( response );
                        },
                        complete: function() {
                            unblock( $( 'div.cart_totals' ) );
                        }
                    } );
                },

                /**
                 * Handle the <ENTER> key for quantity fields.
                 *
                 * @param {Object} evt The JQuery event
                 *
                 * For IE, if you hit enter on a quantity field, it makes the
                 * document.activeElement the first submit button it finds.
                 * For us, that is the Apply Coupon button. This is required
                 * to catch the event before that happens.
                 */
                input_keypress: function( evt ) {

                    // Catch the enter key and don't let it submit the form.
                    if ( 13 === evt.keyCode ) {
                        var $form = $( evt.currentTarget ).parents( 'form' );

                        try {
                            // If there are no validation errors, handle the submit.
                            if ( $form[0].checkValidity() ) {
                                evt.preventDefault();
                                this.cart_submit( evt );
                            }
                        } catch( err ) {
                            evt.preventDefault();
                            this.cart_submit( evt );
                        }
                    }
                },

                /**
                 * Handle cart form submit and route to correct logic.
                 *
                 * @param {Object} evt The JQuery event
                 */
                cart_submit: function( evt ) {
                    var $submit  = $( document.activeElement ),
                        $clicked = $( ':input[type=submit][clicked=true]' ),
                        $form    = $( evt.currentTarget );

                    // For submit events, currentTarget is form.
                    // For keypress events, currentTarget is input.
                    if ( ! $form.is( 'form' ) ) {
                        $form = $( evt.currentTarget ).parents( 'form' );
                    }

                    if ( 0 === $form.find( '.woocommerce-cart-form__contents' ).length ) {
                        return;
                    }

                    if ( is_blocked( $form ) ) {
                        return false;
                    }

                    if ( $clicked.is( ':input[name="update_cart"]' ) || $submit.is( 'input.qty' ) ) {
                        evt.preventDefault();
                        this.quantity_update( $form );

                    } else if ( $clicked.is( ':input[name="apply_coupon"]' ) || $submit.is( '#coupon_code' ) ) {
                        evt.preventDefault();
                        this.apply_coupon( $form );
                    }
                },

                /**
                 * Special handling to identify which submit button was clicked.
                 *
                 * @param {Object} evt The JQuery event
                 */
                submit_click: function( evt ) {
                    $( ':input[type=submit]', $( evt.target ).parents( 'form' ) ).removeAttr( 'clicked' );
                    $( evt.target ).attr( 'clicked', 'true' );
                },

                /**
                 * Apply Coupon code
                 *
                 * @param {JQuery Object} $form The cart form.
                 */
                apply_coupon: function( $form ) {
                    block( $form );

                    var cart = this;
                    var $text_field = $( '#coupon_code' );
                    var coupon_code = $text_field.val();

                    var data = {
                        security: wc_cart_params.apply_coupon_nonce,
                        coupon_code: coupon_code
                    };

                    $.ajax( {
                        type:     'POST',
                        url:      get_url( 'apply_coupon' ),
                        data:     data,
                        dataType: 'html',
                        success: function( response ) {
                            $( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove();
                            show_notice( response );
                            $( document.body ).trigger( 'applied_coupon', [ coupon_code ] );
                        },
                        complete: function() {
                            unblock( $form );
                            $text_field.val( '' );
                            cart.update_cart( true );
                        }
                    } );
                },

                /**
                 * Handle when a remove coupon link is clicked.
                 *
                 * @param {Object} evt The JQuery event
                 */
                remove_coupon_clicked: function( evt ) {
                    evt.preventDefault();

                    var cart     = this;
                    var $wrapper = $( evt.currentTarget ).closest( '.cart_totals' );
                    var coupon   = $( evt.currentTarget ).attr( 'data-coupon' );

                    block( $wrapper );

                    var data = {
                        security: wc_cart_params.remove_coupon_nonce,
                        coupon: coupon
                    };

                    $.ajax( {
                        type:    'POST',
                        url:      get_url( 'remove_coupon' ),
                        data:     data,
                        dataType: 'html',
                        success: function( response ) {
                            $( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove();
                            show_notice( response );
                            $( document.body ).trigger( 'removed_coupon', [ coupon ] );
                            unblock( $wrapper );
                        },
                        complete: function() {
                            cart.update_cart( true );
                        }
                    } );
                },

                /**
                 * Handle a cart Quantity Update
                 *
                 * @param {JQuery Object} $form The cart form.
                 */
                quantity_update: function( $form ) {
                    block( $form );
                    block( $( 'div.cart_totals' ) );

                    // Provide the submit button value because wc-form-handler expects it.
                    $( '<input />' ).attr( 'type', 'hidden' )
                                    .attr( 'name', 'update_cart' )
                                    .attr( 'value', 'Update Cart' )
                                    .appendTo( $form );

                    // Make call to actual form post URL.
                    $.ajax( {
                        type:     $form.attr( 'method' ),
                        url:      $form.attr( 'action' ),
                        data:     $form.serialize(),
                        dataType: 'html',
                        success:  function( response ) {
                            update_wc_div( response );
                        },
                        complete: function() {
                            unblock( $form );
                            unblock( $( 'div.cart_totals' ) );
                            $.scroll_to_notices( $( '[role="alert"]' ) );
                        }
                    } );
                },

                /**
                 * Handle when a remove item link is clicked.
                 *
                 * @param {Object} evt The JQuery event
                 */
                item_remove_clicked: function( evt ) {
                    evt.preventDefault();

                    var $a = $( evt.currentTarget );
                    var $form = $a.parents( 'form' );

                    block( $form );
                    block( $( 'div.cart_totals' ) );

                    $.ajax( {
                        type:     'GET',
                        url:      $a.attr( 'href' ),
                        dataType: 'html',
                        success:  function( response ) {
                            update_wc_div( response );
                        },
                        complete: function() {
                            unblock( $form );
                            unblock( $( 'div.cart_totals' ) );
                            $.scroll_to_notices( $( '[role="alert"]' ) );
                        }
                    } );
                },

                /**
                 * Handle when a restore item link is clicked.
                 *
                 * @param {Object} evt The JQuery event
                 */
                item_restore_clicked: function( evt ) {
                    evt.preventDefault();

                    var $a = $( evt.currentTarget );
                    var $form = $( 'form.woocommerce-cart-form' );

                    block( $form );
                    block( $( 'div.cart_totals' ) );

                    $.ajax( {
                        type:     'GET',
                        url:      $a.attr( 'href' ),
                        dataType: 'html',
                        success:  function( response ) {
                            update_wc_div( response );
                        },
                        complete: function() {
                            unblock( $form );
                            unblock( $( 'div.cart_totals' ) );
                        }
                    } );
                }
            };

            cart_shipping.init( cart );
            cart.init();
        } );

标签: phpwordpressbuttonwoocommerceproduct

解决方案


这是在 WooCommerce 结帐页面上添加删除按钮(和数量字段)的方法:https ://www.webroomtech.com/woocommerce-checkout-change-quantity-and-delete-products/


推荐阅读