I'm making a plugin for Elementor. It must show a product from WooCommerce on the page. Picture, name, price, quantity window, +/- buttons, add to cart button for each product. The quantity window does not work, the quantity 1 initial digit is indicated there, it accepts it, and that's it. If I enter the number 3, it will not record anything and add 1. Build custom-product-widget.php script.js style.css folder "widgets": class-custom-product-widget.php The main pludin file custom-product-widget.php: <?php /* Plugin Name: Custom Product Widget for Elementor v1.00000000 Description: Додає віджет для Elementor, який відображає WooCommerce продукти. Version: 1.00000000 Author: blvckfamily */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } // Connecting the necessary files function cpw_enqueue_scripts() { wp_enqueue_style( 'cpw-style', plugin_dir_url( __FILE__ ) . 'style.css' ); wp_enqueue_script( 'cpw-script', plugin_dir_url( __FILE__ ) . 'script.js', array('jquery'), null, true ); } add_action( 'wp_enqueue_scripts', 'cpw_enqueue_scripts' ); // Widget registration function cpw_register_widget() { require_once( plugin_dir_path( __FILE__ ) . 'widgets/class-custom-product-widget.php' ); \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \Custom_Product_Widget() ); } add_action( 'elementor/widgets/widgets_registered', 'cpw_register_widget' ); The script.js file: jQuery(function($) { $('.product-card').each(function() { var minusBtn = $(this).find('.minus'), plusBtn = $(this).find('.plus'), qtyInput = $(this).find('.qty'), addToCartBtn = $(this).find('.add-to-cart'); function updateAddToCartButton(qtyInput) { qtyInput.closest('.product-card').find('.add-to-cart').attr('data-quantity', qtyInput.val()); } minusBtn.on('click', function () { var currentVal = parseInt(qtyInput.val()); if (currentVal > 1) { qtyInput.val(currentVal - 1); updateAddToCartButton(qtyInput); } }); plusBtn.on('click', function () { var currentVal = parseInt(qtyInput.val()); qtyInput.val(currentVal + 1); updateAddToCartButton(qtyInput); }); qtyInput.on('input', function () { updateAddToCartButton(qtyInput); }); addToCartBtn.on('click', function() { var productId = $(this).data('product-id'); var quantity = $(this).siblings('.quantity-box').find('.qty').val(); $.ajax({ url: wc_add_to_cart_params.ajax_url, type: 'POST', data: { action: 'woocommerce_ajax_add_to_cart', product_id: productId, quantity: quantity }, success: function(response) { if (response.error && response.product_url) { window.location = response.product_url; } else { $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $this]); } } }); }); }); }); The style.css file: .custom-product-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; } .product-card { text-align: center; padding: 10px; border: 1px solid #eee; margin-bottom: 15px; } .product-card img { max-width: 100%; height: auto; } .product-card h3 { font-size: 16px; margin: 10px 0; } .product-card .quantity-box { display: flex; justify-content: center; align-items: center; margin: 10px 0; } .product-card .quantity-box input { width: 50px; text-align: center; margin: 0 10px; } .product-card .add-to-cart { background-color: #000; color: #fff; padding: 10px 20px; text-transform: uppercase; border: none; cursor: pointer; } .product-card .add-to-cart:hover { background-color: #333; } .quantity-box button { background-color: #ddd; border: none; padding: 0 10px; cursor: pointer; } .quantity-box button:hover { background-color: #ccc; } /* Remove arrows from number input */ .quantity-box input[type="number"] { -moz-appearance: textfield; -webkit-appearance: none; appearance: none; } .quantity-box input[type="number"]::-webkit-inner-spin-button, .quantity-box input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } In the folder "widgets", the file "class-custom-product-widget.php": <?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } class Custom_Product_Widget extends \Elementor\Widget_Base { public function get_name() { return 'custom_product_widget'; } public function get_title() { return __( 'Custom Product Widget', 'cpw' ); } public function get_icon() { return 'eicon-product-grid'; } public function get_categories() { return [ 'general' ]; } protected function _register_controls() { // Add controls here if needed } protected function render() { $args = array( 'post_type' => 'product', 'posts_per_page' => 10 ); $products = new WP_Query( $args ); if ( $products->have_posts() ) { echo '<div class="custom-product-grid">'; while ( $products->have_posts() ) { $products->the_post(); global $product; ?> <div class="product-card"> <?php if ( has_post_thumbnail() ) { ?> <img src="<?php echo esc_url( get_the_post_thumbnail_url() ); ?>" alt="<?php the_title(); ?>" /> <?php } ?> <h3><?php the_title(); ?></h3> <div class="quantity-box"> <button type="button" class="minus">-</button> <input type="number" class="input-text qty text" step="1" min="1" value="1" /> <button type="button" class="plus">+</button> </div> <a href="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="add-to-cart button"> <?php echo esc_html( $product->add_to_cart_text() ); // Button "Add to cart" ?> </a> </div> <?php } echo '</div>'; wp_reset_postdata(); } } } I've done so many things, even tried searching stackoverflow.