Greetings. There was a problem with the school basket, the quantity of goods in the input fields is updated, but not saved, which means another problem - the total price is not updated.

Subject: Cart template cart.php

do_action( 'woocommerce_before_cart' ); ?> <form id="doorCart" action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post"> <div class="wooCart"> <?php do_action( 'woocommerce_before_cart_contents' ); ?> <?php $i = 0; 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 ); ?> <div class="col s12 productSelf <?php echo $i; ?>"> <div class="productImg product-thumbnail"> <?php $thumbnail = apply_filters( 'custom_new_product_image', $_product->get_image('full'), $cart_item, $cart_item_key ); if ( ! $product_permalink ) { echo $thumbnail; } else { printf( '<a href="%s">%s</a>', esc_url( $product_permalink ), $thumbnail ); } ?> </div> <div class="productCartInfo"> <?php if ( ! $product_permalink ) { ?> <p class="exo2Medium productText product-name"> <?php echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . '&nbsp;'; } else { echo apply_filters( 'woocommerce_cart_item_name', sprintf( '<a class="exo2Medium productText black-text" href="%s">%s</a>', esc_url( $product_permalink ), $_product->get_title() ), $cart_item, $cart_item_key ); } ?> </p> <?php // Meta data echo WC()->cart->get_item_data( $cart_item ); // Backorder notification if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) { echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>'; } ?> <div class="product-quantity"> <?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->backorders_allowed() ? '' : $_product->get_stock_quantity(), 'min_value' => '0' ), $_product, false ); } echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item ); ?> </div> <div class="product-price"> <p class="exo2Medium green-custom-text"> <?php echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key ); ?> </p> </div> </div> <div class="productArticle"> <p class="openLight grey-text text-lighten-1 productSku">Артикул: <?php echo $_product->get_sku(); ?> </p> </div> <div class="productInfo"> <?php $has_row = false; $alt = 1; $attributes = $_product->get_attributes(); ob_start(); ?> <?php foreach ( $attributes as $attribute ) { if ( empty( $attribute['is_visible'] ) || ( $attribute['is_taxonomy'] && ! taxonomy_exists( $attribute['name'] ) ) ) { continue; } else { $has_row = true; } if ( $attribute['name'] === "pa_manufacturer_out" || $attribute['name'] === "pa_manufacturer_in" || $attribute['name'] === "pa_model" || $attribute['name'] === "pa_color" ) { ?> <div class="attr"> <p class="openLight grey-text text-lighten-1 attrName"> <?php if ( $attribute['name'] === "pa_manufacturer_out" || $attribute['name'] === "pa_manufacturer_in"){ echo 'Производитель'; } else { echo wc_attribute_label( $attribute['name'] ); } ?>: </p> <?php if ( $attribute['is_taxonomy'] ) { $values = wc_get_product_terms( $_product->id, $attribute['name'], array( 'fields' => 'names' ) ); ?> <p class="openLight black-text attrValue"><?php echo strip_tags(apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values ) );?></p> <?php } else { $values = array_map( 'trim', explode( WC_DELIMITER, $attribute['value'] ) );?> <p class="openLight black-text attrValue"><?php echo strip_tags( apply_filters( 'woocommerce_attribute', wpautop( wptexturize( implode( ', ', $values ) ) ), $attribute, $values ) );?> </p> <?php } ?> </div> <?php } } ?> </div> </div> <?php } $i++; } do_action( 'woocommerce_cart_contents' ); ?> <hr class="grey-hr"> <div class="cartTotal"> <input type="submit" class="button update-cart-button" name="update_cart" value="<?php esc_attr_e( 'Update Cart', 'woocommerce' ); ?>" /> <?php woocommerce_cart_totals(); ?> </div> </div> </form> 

Template quantity-input.php

 <img src="<?php echo get_template_directory_uri() ?>/assets/img/minus.png" alt="" name="minus" class="minus"/> <input type="number" step="<?php echo esc_attr( $step ); ?>" min="<?php echo esc_attr( $min_value ); ?>" max="<?php echo esc_attr( $max_value ); ?>" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $input_value ); ?>" data-quantity="<?php echo esc_attr( $input_value ); ?>" title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) ?>" class="input-text qty text exo2Medium" size="4" pattern="<?php echo esc_attr( $pattern ); ?>" inputmode="<?php echo esc_attr( $inputmode ); ?>"/> <img src="<?php echo get_template_directory_uri() ?>/assets/img/plus.png" alt="" name="plus" class="plus"/> 

Edit in cart.js

 var cart = { init: function () { this.qty_click = this.qty_click.bind(this); $(document).on( 'click', '.quantity img', this.qty_click); qty_click: function (evt) { var $clicked = $(evt.target); var qty = $('.quantity').find('.qty'); var currVal = qty.val(); var $form = $('#doorCart'); if ($clicked.is('.minus')) { evt.preventDefault(); if (currVal > 0) { var newVal = parseFloat(qty.val()) - 1; } else { newVal = 0; } $clicked.next('.qty').attr('data-quantity', newVal).change(); $clicked.next('.qty').attr( 'value', newVal ).change(); $clicked.next('.qty').val( newVal ).change(); }; if ($clicked.is('.plus')) { evt.preventDefault(); newVal = parseFloat(qty.val()) + 1; $clicked.prev('.qty').attr('data-quantity', newVal).change(); $clicked.prev('.qty').attr( 'value', newVal ).change(); $clicked.prev('.qty').val( newVal ).change(); }; } $(document).bind('ready ajaxComplete', function(){ $('[name="update_cart"]').attr("disabled",false); }); 

Filter in functions.php

 add_action( 'woocommerce_after_cart', 'custom_after_cart' ); function custom_after_cart() { echo '<script> jQuery(document).ready(function($) { var upd_cart_btn = $(".update-cart-button"); upd_cart_btn.hide(); $("#doorCart").find(".qty").on("change", function(){ upd_cart_btn.trigger("wc_update_cart"); }); }); </script>'; 

}

The change in the quantity of goods in the basket occurs, then the basket is updated, but in fact the value does not change, since only the value in the input fields is updated, and the price, for example, remains unchanged. When the page is reloaded, the quantity of goods is also reset. Most likely, I do not take into account something, I will be grateful for the help, or at least an indication in which direction to dig (I assume that AYAX requests to the server). I tried to follow the path of least resistance - use the plugins that solve this, they did not fit. I wrote a plugin on the forum, there is no reaction. Thanks in advance.

    1 answer 1

    It is not clear that you wanted to make this hook, but this design can not work exactly.

    WooCommerce has hooks for almost all occasions, you need to use them. Processing in these hooks is on the server, in php code.

    UPDATE

    Still, I had to script, because there are no hooks that are triggered when the quantity is updated.

    function.php

     function action_enqueue_scripts() { wp_enqueue_script('update-cart', get_stylesheet_directory_uri().'/update-cart.js', array('jquery')); } add_action( 'wp_enqueue_scripts', 'action_enqueue_scripts' ); 

    update-cart.js

     function click_update_cart_btn(upd_cart_btn) { jQuery(".cart_item").parents('form').find('[name="update_cart"]'); upd_cart_btn.trigger('click'); } jQuery(document).ready(function($) { var update_cart; jQuery('body').delegate(".cart_item .qty").on("change", function(){ if(update_cart != null){ clearTimeout(update_cart); } update_cart = setTimeout(click_update_cart_btn, 1000); }); }); 

    The working code is here .

    PS It is clear why the developers of WooCommerce did not include this feature. Updating the cart - this is anyway ajax request, and hanging it for every click on a change in the number - it turns out slowly.

    • This hook automatically triggers the cart update button for every change in the quantity field. And it is possible in more detail, regarding the question, what kind of hook can I use? I work with a tutor for the first time, and therefore there are difficulties. - spirit-infernal
    • Thank you, I saw this option on the Internet, but it did not work, although I tried to adapt it again, rendering, for example, the functionality of changing the quantity of goods into separate functions. If you use it in its pure form, as you wrote, a jerking error appears. Cannot create property 'guid' on string '.productSelf .qty' caused due to jquery version (3.1.1) and changes in the basket template (instead of a table, the necessary information rolled up in separate blocks in the cycle) Perhaps there are more options? - spirit-infernal
    • Have you seen the link to the working code on my site? What are these theories for? Go and see how it works. - KAGG Design