Lập TrìnhWordpress

[Woocommerce] Thêm Nút Xóa – Tăng Giảm Số Lượng Trong Trang Thanh Toán Woocommerce

 Thêm nút xóa và tăng giảm số lượng sản phẩm trong trang thanh toán WooCommerce đối với các bạn sử dụng wordpress plugin Woocommerce

  • Tăng giảm số lượng trực tiếp ở trang thanh toán cho từng sản phẩm
  • Xóa từng sản phẩm đã thêm vào giỏ hàng ngay trực tiếp trang thanh toán

Cho code sau vào file funtion.php

function add_flatsome_product_controls_checkout_wat($product_subtotal, $cart_item, $cart_item_key) {
    if (!is_checkout()) {
        return $product_subtotal;
    }

    $quantity = $cart_item['quantity'];
    $nonce = wp_create_nonce('woocommerce-cart');

    // html
    $controls_html = sprintf(
        '<div class="checkout-product-controls_wat">
            <div class="product-total-price-wat">%s</div>
            <div class="product-controls-wrapper-wat">
                <div class="quantity-controls flatsome-quantity-wat buttons_added">
                    <input type="button" value="-" class="minuswat button is-form" data-cart-key="%s">
                    <input type="number" class="quantity-input" value="%s" min="1" step="1" data-cart-key="%s">
                    <input type="button" value="+" class="pluswat button is-form" data-cart-key="%s">
                </div>
                <a href="%s" class="remove-product-wat remove" aria-label="%s" data-product_id="%s">×</a>
            </div>
        </div>',
        $product_subtotal,
        esc_attr($cart_item_key),
        esc_html($quantity),
        esc_attr($cart_item_key),
        esc_attr($cart_item_key),
        esc_url(wc_get_cart_remove_url($cart_item_key)),
        esc_html__('Xóa sản phẩm này', 'flatsome'),
        esc_attr($cart_item['product_id'])
    );

    // CSS styles
    $style = '
        <style>
            /* Container cho tất cả controls */
            .checkout-product-controls_wat {
                display: flex;
                flex-direction: column;
                gap: 10px;
            }

            /* Style cho phần giá */
            .product-total-price-wat {
                margin-bottom: 5px;
            }

            /* Wrapper cho phần controls */
            .product-controls-wrapper-wat {
                display: flex;
                gap: 10px;
                align-items: center;
            }

            /* Style cho phần quantity controls */
            .flatsome-quantity-wat {
                display: inline-flex;
                align-items: center;
                border: 1px solid #ddd;
                border-radius: 3px;
                overflow-x: hidden;
            }

            .flatsome-quantity-wat .button.is-form {
                border-radius: 0;
                background-color: #f9f9f9;
                border: none;
                height: 25px;
                width: 25px;
                padding: 0;
                margin: 0;
                font-size: 14px;
            }

            /* Style cho input số lượng */
            .flatsome-quantity-wat .quantity-input {
                padding: 0 8px;
                width: 35px;
                text-align: center;
                border: none;
                background: #fff;
                height: 20px;
                line-height: 25px;
                display: inline-block;
                -moz-appearance: textfield;
                box-shadow: none;
            }

            .flatsome-quantity-wat .quantity-input::-webkit-outer-spin-button,
            .flatsome-quantity-wat .quantity-input::-webkit-inner-spin-button {
                -webkit-appearance: none;
                margin: 0;
            }
            input.minuswat.button.is-form {
    width: 20px;
}

input.pluswat.button.is-form {
    width: 20px;
}

            /* Style cho nút xóa */
            .remove-product-wat {
                display: flex;
                align-items: center;
                justify-content: center;
                width: 25px;
                height: 25px;
                color: #ccc !important;
                font-size: 20px !important;
                font-weight: bold;
                text-decoration: none;
                border: 1px solid #ddd;
                border-radius: 3px;
                transition: all 0.2s;
            }

            .remove-product-wat:hover {
                color: #334862 !important;
                background-color: #f9f9f9;
            }

            /* Loading overlay */
            .checkout-loading-overlay-wat {
                display: none;
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(255, 255, 255, 0.8);
                z-index: 9999;
                justify-content: center;
                align-items: center;
            }

            .checkout-loading-overlay-wat.active {
                display: flex;
            }

            .checkout-loading-spinner-wat {
                width: 50px;
                height: 50px;
                border: 4px solid #f3f3f3;
                border-top: 4px solid #334862;
                border-radius: 50%;
                animation: spin 1s linear infinite;
            }

            /* Loading states */
            .flatsome-quantity-wat.loading,
            .remove-product-wat.loading {
                opacity: 0.5;
                pointer-events: none;
            }

            @keyframes spin {
                to { transform: rotate(360deg); }
            }

            /* Responsive */
            @media (max-width: 849px) {
                .flatsome-quantity-wat .button.is-form,
                .remove-product-wat {
                    height: 30px;
                    width: 30px;
                }
            }
        </style>
    ';

    // JavaScript
    $script = '
        <script>
        jQuery(document).ready(function($) {
            var ajaxUrl = "' . admin_url('admin-ajax.php') . '";
            var nonce = "' . $nonce . '";
            var isUpdating = false;
            var updateTimeout;

            // Thêm overlay loading vào body nếu chưa có
            if (!$(".checkout-loading-overlay-wat").length) {
                $("body").append(\'<div class="checkout-loading-overlay-wat"><div class="checkout-loading-spinner-wat"></div></div>\');
            }

            function showLoadingwat() {
                $(".checkout-loading-overlay-wat").addClass("active");
            }

            function hideLoadingwat() {
                $(".checkout-loading-overlay-wat").removeClass("active");
            }

            function updateQuantitywat(cartKey, newQuantity, element) {
                if (isUpdating) return;
                
                var controls = element.closest(".flatsome-quantity-wat");
                var quantityInput = controls.find(".quantity-input");
                
                // Kiểm tra giá trị tối thiểu
                if (newQuantity < 1) {
                    newQuantity = 1;
                    quantityInput.val(1);
                    return;
                }
                
                isUpdating = true;
                showLoadingwat();
                controls.addClass("loading");
                
                $.ajax({
                    url: ajaxUrl,
                    type: "POST",
                    data: {
                        action: "flatsome_update_quantity",
                        cart_key: cartKey,
                        quantity: newQuantity,
                        security: nonce
                    },
                    success: function(response) {
                        if(response.success) {
                            quantityInput.val(newQuantity);
                            $("body").trigger("update_checkout");
                            
                            // Tính toán tổng số lượng mới
                            var totalQuantity = 0;
                            $(".quantity-input").each(function() {
                                totalQuantity += parseInt($(this).val());
                            });
                            
                            // Cập nhật số lượng trực tiếp trên icon giỏ hàng
                            $(".icon-shopping-cart").attr("data-icon-label", totalQuantity);
                        } else {
                            alert("Không thể cập nhật số lượng. Vui lòng tải lại trang.");
                            quantityInput.val(newQuantity - 1);
                        }
                    },
                    error: function() {
                        alert("Có lỗi xảy ra. Vui lòng thử lại.");
                        quantityInput.val(newQuantity - 1);
                    },
                    complete: function() {
                        controls.removeClass("loading");
                        hideLoadingwat();
                        isUpdating = false;
                    }
                });
            }

            // Xử lý nhập số lượng trực tiếp
            $(document).on("input", ".quantity-input", function() {
                var $this = $(this);
                var cartKey = $this.data("cart-key");
                var newQuantity = parseInt($this.val());
                
                // Clear timeout cũ nếu có
                if (updateTimeout) {
                    clearTimeout(updateTimeout);
                }
                
                // Đặt timeout mới
                updateTimeout = setTimeout(function() {
                    if (!isNaN(newQuantity) && newQuantity > 0) {
                        updateQuantitywat(cartKey, newQuantity, $this);
                    }
                }, 500); // Đợi 500ms sau khi người dùng ngừng nhập
            });

            // Ngăn chặn nhập các ký tự không phải số
            $(document).on("keypress", ".quantity-input", function(e) {
                if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
                    return false;
                }
            });

            // Xử lý nút giảm
            $(document).on("click", ".flatsome-quantity-wat .minuswat", function() {
                if (isUpdating) return;
                
                var cartKey = $(this).data("cart-key");
                var quantityInput = $(this).siblings(".quantity-input");
                var currentQty = parseInt(quantityInput.val());
                
                if (currentQty > 1) {
                    updateQuantitywat(cartKey, currentQty - 1, $(this));
                }
            });

            // Xử lý nút tăng
            $(document).on("click", ".flatsome-quantity-wat .pluswat", function() {
                if (isUpdating) return;
                
                var cartKey = $(this).data("cart-key");
                var quantityInput = $(this).siblings(".quantity-input");
                var currentQty = parseInt(quantityInput.val());
                
                updateQuantitywat(cartKey, currentQty + 1, $(this));
            });

            // Xử lý nút xóa cải tiến không reload trang
            $(document).on("click", ".remove-product-wat", function(e) {
                e.preventDefault();
                if (isUpdating) return;
                
                var link = $(this).attr("href");
                var $this = $(this);
                var $productRow = $this.closest("tr");
                
                isUpdating = true;
                showLoadingwat();
                $this.addClass("loading");

                $.ajax({
                    url: link,
                    type: "GET",
                    success: function() {
                        $productRow.fadeOut(300, function() {
                            $(this).remove();
                            $("body").trigger("update_checkout");
                            
                            // Tính toán tổng số lượng mới sau khi xóa
                            var totalQuantity = 0;
                            $(".quantity-input").each(function() {
                                totalQuantity += parseInt($(this).val());
                            });
                            
                            // Cập nhật số lượng trực tiếp trên icon giỏ hàng
                            $(".icon-shopping-cart").attr("data-icon-label", totalQuantity);
                            
                            if ($(".checkout-product-controls_wat").length === 0) {
                                window.location.reload();
                            }
                        });
                        hideLoadingwat();
                        isUpdating = false;
                    },
                    error: function() {
                        alert("Có lỗi xảy ra. Vui lòng thử lại.");
                        hideLoadingwat();
                        $this.removeClass("loading");
                        isUpdating = false;
                    },
                    complete: function() {
                        $this.removeClass("loading");
                    }
                });
            });

            // Xử lý blur input để cập nhật khi click ra ngoài
            $(document).on("blur", ".quantity-input", function() {
                var $this = $(this);
                var cartKey = $this.data("cart-key");
                var newQuantity = parseInt($this.val());
                
                if (!isNaN(newQuantity) && newQuantity > 0) {
                    updateQuantitywat(cartKey, newQuantity, $this);
                } else {
                    $this.val(1);
                    updateQuantitywat(cartKey, 1, $this);
                }
            });
        });
        </script>
    ';

    if (!wp_script_is('flatsome-product-controls-wat', 'enqueued')) {
        add_action('wp_footer', function() use ($style, $script) {
            echo $style . $script;
        });
        wp_register_script('flatsome-product-controls-wat', null);
    }

    return $controls_html;
}

// Xử lý Ajax cho cập nhật số lượng
function handle_flatsome_quantity_update_wat() {
    check_ajax_referer('woocommerce-cart', 'security');

    $cart_key = sanitize_text_field($_POST['cart_key']);
    $quantity = intval($_POST['quantity']);
    $success = false;

    if ($cart_key && $quantity > 0) {
        $success = WC()->cart->set_quantity($cart_key, $quantity);
        WC()->cart->calculate_totals();
    }

    wp_send_json(array('success' => $success));
}

// Đăng ký Ajax actions
add_action('wp_ajax_flatsome_update_quantity', 'handle_flatsome_quantity_update_wat');
add_action('wp_ajax_nopriv_flatsome_update_quantity', 'handle_flatsome_quantity_update_wat');
add_filter('woocommerce_cart_item_subtotal', 'add_flatsome_product_controls_checkout_wat', 10, 3);

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Back to top button