Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save webantam43/a0a2439d2ecfdbc75b23a13a5defc1b5 to your computer and use it in GitHub Desktop.

Select an option

Save webantam43/a0a2439d2ecfdbc75b23a13a5defc1b5 to your computer and use it in GitHub Desktop.
Thêm nút xóa và tăng giảm số lượng, ảnh đại diện sản phẩm trong trang thanh toán WooCommerce cho Flatsome
/**
* Thêm nút xóa và tăng giảm số lượng sản phẩm trong trang thanh toán WooCommerce cho Flatsome
* Bổ sung thêm ảnh đại diện sản phẩm
*/
// Thêm ảnh sản phẩm vào trước tên sản phẩm
function add_product_image_before_name_wat($product_name, $cart_item, $cart_item_key) {
if (!is_checkout()) {
return $product_name;
}
$product = $cart_item['data'];
$thumbnail = $product->get_image(array(50, 50));
return sprintf(
'<div class="checkout-product-info-wat">
<div class="checkout-product-image-container-wat">
<a href="%s" class="remove-product-wat remove" aria-label="%s" data-product_id="%s" data-cart-key="%s">×</a>
<div class="checkout-product-image-wat">%s</div>
</div>
<div class="checkout-product-name-wat">%s</div>
</div>',
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']),
esc_attr($cart_item_key),
$thumbnail,
$product_name
);
}
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>
</div>
</div>',
$product_subtotal,
esc_attr($cart_item_key),
esc_html($quantity),
esc_attr($cart_item_key),
esc_attr($cart_item_key)
);
// CSS styles
$style = '
<style>
/* Style cho container thông tin sản phẩm */
.checkout-product-info-wat {
display: flex;
align-items: center;
gap: 10px;
}
.checkout-product-image-container-wat {
position: relative;
}
.checkout-product-image-wat img {
width: 50px;
height: 50px;
object-fit: cover;
border-radius: 3px;
}
.checkout-product-name-wat {
flex: 1;
}
/* Style cho nút xóa */
.remove-product-wat {
position: absolute;
top: -8px;
left: -8px;
display: flex !important;
align-items: center;
justify-content: center;
width: 20px !important;
height: 20px !important;
color: #ccc !important;
font-size: 16px !important;
font-weight: bold !important;
text-decoration: none;
border-radius: 50% !important;
transition: all 0.2s;
z-index: 1;
cursor: pointer;
}
.remove-product-wat:hover {
background-color: #e21b1b !important;
color: white !important;
text-decoration: none;
}
/* Các styles hiện có */
.checkout-product-controls_wat {
display: flex;
flex-direction: column;
gap: 10px;
}
.product-total-price-wat {
margin-bottom: 5px;
}
.product-controls-wrapper-wat {
display: flex;
gap: 10px;
align-items: center;
}
.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;
}
.flatsome-quantity-wat .quantity-input {
padding: 0 4px;
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;
}
.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;
}
.flatsome-quantity-wat.loading,
.remove-product-wat.loading {
opacity: 0.5;
pointer-events: none;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@media (max-width: 849px) {
.flatsome-quantity-wat .button.is-form {
height: 30px;
width: 30px;
}
.checkout-product-image-wat img {
width: 40px;
height: 40px;
}
.checkout-product-info-wat{
padding-left: 12px;
}
.remove-product-wat{
left: -11px !important;
}
}
</style>
';
// JavaScript
$script = '
<script>
jQuery(document).ready(function($) {
var ajaxUrl = "' . admin_url('admin-ajax.php') . '";
var nonce = "' . $nonce . '";
var isUpdating = false;
var updateTimeout;
// Khởi tạo loading overlay một lần
$("body").append(\'<div class="checkout-loading-overlay-wat"><div class="checkout-loading-spinner-wat"></div></div>\');
var $loadingOverlay = $(".checkout-loading-overlay-wat");
function showLoadingwat() {
$loadingOverlay.addClass("active");
}
function hideLoadingwat() {
$loadingOverlay.removeClass("active");
}
function updateQuantitywat(cartKey, newQuantity, element) {
if (isUpdating) return;
var controls = element.closest(".flatsome-quantity-wat");
var quantityInput = controls.find(".quantity-input");
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");
var totalQuantity = 0;
$(".quantity-input").each(function() {
totalQuantity += parseInt($(this).val());
});
$(".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;
}
});
}
$(document).on("input", ".quantity-input", function() {
var $this = $(this);
var cartKey = $this.data("cart-key");
var newQuantity = parseInt($this.val());
if (updateTimeout) {
clearTimeout(updateTimeout);
}
updateTimeout = setTimeout(function() {
if (!isNaN(newQuantity) && newQuantity > 0) {
updateQuantitywat(cartKey, newQuantity, $this);
}
}, 500);
});
$(document).on("keypress", ".quantity-input", function(e) {
if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) {
return false;
}
});
$(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));
}
});
$(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ý sự kiện xóa sản phẩm
$(document).on("click", ".remove-product-wat", function(e) {
e.preventDefault();
if (isUpdating) return;
var $link = $(this);
var cartKey = $link.data("cart-key");
var $productRow = $link.closest("tr");
if (!cartKey || $link.hasClass("loading")) return;
isUpdating = true;
$link.addClass("loading");
// Ẩn sản phẩm ngay lập tức để tạo phản hồi nhanh
$productRow.css("opacity", "0.5");
$.ajax({
url: ajaxUrl,
type: "POST",
data: {
action: "remove_cart_item_wat",
cart_key: cartKey,
security: nonce
},
success: function(response) {
if (response.success) {
$productRow.fadeOut(200, function() {
$(this).remove();
$("body").trigger("update_checkout");
// Cập nhật số lượng giỏ hàng
var totalQuantity = 0;
$(".quantity-input").each(function() {
totalQuantity += parseInt($(this).val() || 0);
});
$(".icon-shopping-cart").attr("data-icon-label", totalQuantity);
if ($(".checkout-product-controls_wat").length === 0) {
window.location.reload();
}
});
} else {
$productRow.css("opacity", "1");
alert("Không thể xóa sản phẩm. Vui lòng thử lại.");
}
},
error: function() {
$productRow.css("opacity", "1");
alert("Có lỗi xảy ra. Vui lòng thử lại.");
},
complete: function() {
isUpdating = false;
$link.removeClass("loading");
}
});
});
$(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));
}
// Xử lý Ajax cho việc xóa sản phẩm
function handle_remove_cart_item_wat() {
check_ajax_referer('woocommerce-cart', 'security');
$cart_key = sanitize_text_field($_POST['cart_key']);
$success = false;
if ($cart_key && isset(WC()->cart->cart_contents[$cart_key])) {
$success = WC()->cart->remove_cart_item($cart_key);
WC()->cart->calculate_totals();
}
wp_send_json(array('success' => $success));
}
// Đăng ký các action và filter
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_action('wp_ajax_remove_cart_item_wat', 'handle_remove_cart_item_wat');
add_action('wp_ajax_nopriv_remove_cart_item_wat', 'handle_remove_cart_item_wat');
add_filter('woocommerce_cart_item_subtotal', 'add_flatsome_product_controls_checkout_wat', 10, 3);
add_filter('woocommerce_cart_item_name', 'add_product_image_before_name_wat', 10, 3);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment