Woocommerce. Количество товара в корзине и общая цена. Проблема с обновлением

812
21 февраля 2017, 18:50

Приветствую. Возникла проблема с корзиной вукомерса, количество товара в полях ввода обновляется, но не сохраняется, из чего следует другая проблема - не обновляется общая цена.

Сабж: Шаблон корзины 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>

Шаблон 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"/>

Правки в 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);
});

Фильтр в 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>';

}

Изменение количества товара в корзине происходит, затем происходит обновление корзины, но фактически значение не меняется, так как обновляется только значение в полях ввода, а цена, к примеру, остаётся не изменённой. При перезагрузке страницы количество товаров также сбрасывается. Скорее всего я что-то не учитываю, буду благодарен за помощь, или хотя бы указание, в каком направлении копать (предположу, что аякс запросы к серверу). Пробовал пойти по пути наименьшего сопротивления - воспользоваться плагинами, решающими это, они не подошли. На форум плагина написал, реакции нет. Спасибо заранее.

Answer 1

Непонятно, что вы хотели сделать этим хуком, но такая конструкция точно работать не может.

В WooCommerce есть хуки почти на все случаи жизни, надо их использовать. Обработка в этих хуках идет на сервере, в php коде.

UPDATE

Все-таки пришлось скриптом, потому что нет хуков, срабатывающих при обновлении количества.

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);
    });
});

Работающий код здесь.

P.S. Понятно, почему разработчики WooCommerce не включили такую возможность. Обновление корзины - это по-любому ajax запрос, и вешать его на каждый клик по изменению количества - получается медленно.

READ ALSO
Как работает [ScriptIgnore]?

Как работает [ScriptIgnore]?

При разработке небольшого приложения на ASPNET MVC, столкнулся с такой проблемой, что когда мой контрол возвращал данные в формате JSON, то возникала...

273
Смена фона body при смене слайдов

Смена фона body при смене слайдов

Привет! Есть слайдер-карусель, сделанный при помощи плагина slickПотребовалось подкрутить его, чтобы при смене слайда автоматически менялся...

388
Stylus|CSS каждое слово выше на ХХpx

Stylus|CSS каждое слово выше на ХХpx

Есть предложение в теге span или div

408
Иконка профиля пользователя на главной

Иконка профиля пользователя на главной

Работаю над дипломным проектом, задание - сверстать лендингНе совсем понимаю, что делать с иконкой пользователя в хедере

367