O carrinho de atualização do WooCommerce faz com que as setas numéricas desapareçam

Jan 07 2021

Estou usando o WooCommerce e, na página do carrinho, estou usando ícones de números personalizados.

Encontrei o código original aqui: https://codepen.io/komarovdesign/pen/PPRbgb

Está funcionando em meu site ao vivo aqui: http://joshrodg.com/rbtest/shop/cart/ (você pode ter que adicionar algo ao punho do carrinho)

O problema que estou tendo é quando clico no sinal de mais ou menos e, em seguida, clico em "Atualizar carrinho", os ícones de números personalizados desaparecem e tudo o que resta é o número.

Minha jQuery se parece com:

$(function() { // Quantity $('<div class="quantity-nav"><div class="quantity-button quantity-up">+</div><div class="quantity-button quantity-down">-</div></div>').insertAfter(".quantity input");
    
    $('.quantity').each(function() {
        var spinner = jQuery(this),
        input = spinner.find('input[type="number"]'),
        btnUp = spinner.find('.quantity-up'),
        btnDown = spinner.find('.quantity-down'),
        min = input.attr('min'),
        max = 999999;
        
        btnUp.click(function() {
            var oldValue = parseFloat(input.val());
            if (oldValue >= max) {
                var newVal = oldValue;
            } else {
                var newVal = oldValue + 1;
            }
            spinner.find("input").val(newVal);
            spinner.find("input").trigger("change");
        });
        
        btnDown.click(function() {
            var oldValue = parseFloat(input.val());
            if (oldValue <= min) {
                var newVal = oldValue;
            } else {
                var newVal = oldValue - 1;
            }
            spinner.find("input").val(newVal);
            spinner.find("input").trigger("change");
        });
    });
});

Meu palpite é que a página está sendo recarregada com ajax quando "Atualizar carrinho" é clicado e, como insertAfterjá foi disparado, não está disparando novamente.

Testei algo adicionando:

$('.button').click(function(){}e anexando (usando .append) algum texto, pensando que quando o botão for pressionado o texto aparecerá. Isso quase funciona. O texto é mostrado brevemente, então a página parece ser atualizada e o conteúdo desaparece. Eu estava pensando que poderia usar essa lógica para disparar o código original quando o botão enviar for clicado.

Meu código se parece com:

    Preço do produto, quantidade, subtotal
                    <td class="product-remove">
                        <a href="http://joshrodg.com/rbtest/shop/cart/?remove_item=a1d0c6e83f027327d8461063f4ac58a6&amp;_wpnonce=c58b0e5416" class="remove" aria-label="Remove this item" data-product_id="42" data-product_sku="">×</a>                        </td>

                    <td class="product-thumbnail">
                    <a href="http://joshrodg.com/rbtest/product/raw-pecan-pieces/"><img width="300" height="300" src="http://joshrodg.com/rbtest/wp-content/uploads/istockphoto-1136673992-1024x1024-1-300x300.jpg" class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail" alt="" loading="lazy" srcset="http://joshrodg.com/rbtest/wp-content/uploads/istockphoto-1136673992-1024x1024-1-300x300.jpg 300w, http://joshrodg.com/rbtest/wp-content/uploads/istockphoto-1136673992-1024x1024-1-150x150.jpg 150w, http://joshrodg.com/rbtest/wp-content/uploads/istockphoto-1136673992-1024x1024-1-600x600.jpg 600w, http://joshrodg.com/rbtest/wp-content/uploads/istockphoto-1136673992-1024x1024-1-100x100.jpg 100w" sizes="(max-width: 300px) 100vw, 300px"></a>                      </td>

                    <td class="product-name" data-title="Product">
                    <a href="http://joshrodg.com/rbtest/product/raw-pecan-pieces/">Raw Pecan Pieces</a>                     </td>

                    <td class="product-price" data-title="Price">
                        <span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>27.56</bdi></span> </td> <td class="product-quantity" data-title="Quantity"> <div class="quantity"> <label class="screen-reader-text" for="quantity_5ff63bef1bbf0">Raw Pecan Pieces quantity</label> <input type="number" id="quantity_5ff63bef1bbf0" class="input-text qty text" step="1" min="0" max="" name="cart[a1d0c6e83f027327d8461063f4ac58a6][qty]" value="1" title="Qty" size="4" placeholder="" inputmode="numeric"> </div> </td> <td class="product-subtotal" data-title="Subtotal"> <span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">$</span>27.56</bdi></span>                        </td>
                </tr>
                
        
        <tr>
            <td colspan="6" class="actions">

                                        <div class="coupon">
                        <label for="coupon_code">Coupon:</label> <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="Coupon code"> <button type="submit" class="button" name="apply_coupon" value="Apply coupon">Apply coupon</button>
                                                </div>
                
                <button type="submit" class="button" name="update_cart" value="Update cart" disabled="" aria-disabled="true">Update cart</button>

                
                <input type="hidden" id="woocommerce-cart-nonce" name="woocommerce-cart-nonce" value="c58b0e5416"><input type="hidden" name="_wp_http_referer" value="/rbtest/shop/cart/">              </td>
        </tr>

                </tbody>
</table>
</form>

Alguém pode me apontar a direção certa ou lançar alguma luz sobre isso? Eu sinto que estou apenas perdendo algo simples.

Obrigada
Josh

Respostas

JoshRodgers Jan 08 2021 at 00:04

OK...

O código original teve que ser ajustado um pouco, mas um amigo meu me ajudou a fazer isso funcionar :-)

Estava funcionando fora da caixa, mas quando clicamos em "Atualizar carrinho" ele parava, então tivemos que criar duas funções para fazer isso funcionar.

Um para os ícones de mais e menos, o outro para o próprio botão.

Queríamos que isso funcionasse desde o início, antes que o botão "Atualizar carrinho" fosse clicado, por isso chamamos a qtyChangefunção no document.ready.

Então, notamos que quando o botão "Atualizar carrinho" foi clicado, o WooCommerce remove e adiciona novamente a entrada do número, então temos que executar novamente nosso script depois que o botão é clicado ... mas há um problema! Visto que isso é feito usando ajax e a página realmente não está sendo recarregada, precisamos esperar até que o processo ajax seja concluído para que nada seja executado muito rapidamente. Se eu não colocasse um tempo limite no código, os botões não apareceriam, o que era meu problema inicial.

Eu também tive um problema em que os botões apareciam, mas os ícones de mais e menos não faziam o número de entrada avançar ou diminuir, que é a função da outra função de tempo limite.

Finalmente, tive que fazer mais uma alteração ... Adicionei .removecomo um seletor porque o X ao lado de cada produto também fazia com que os ícones de mais e menos desaparecessem.

No geral, agora está funcionando. Isso teria sido mais simples se pudéssemos ter modificado o código WooCommerce diretamente, mas isso poderia ser eliminado com uma atualização de plug-in, então esta é uma solução melhor :-)

Agora meu código se parece com:

<script>
        function qtyChange() {
            $('<div class="quantity-nav"><div class="quantity-button quantity-up">+</div><div class="quantity-button quantity-down">-</div></div>').insertAfter(".quantity input"); $('.quantity').each(function() {
                var spinner = jQuery(this),
                input = spinner.find('input[type="number"]'),
                btnUp = spinner.find('.quantity-up'),
                btnDown = spinner.find('.quantity-down'),
                min = input.attr('min'),
                max = 999999;
                
                btnUp.click(function() {
                    var oldValue = parseFloat(input.val());
                    if (oldValue >= max) {
                        var newVal = oldValue;
                    } else {
                        var newVal = oldValue + 1;
                    }
                    spinner.find("input").val(newVal);
                    spinner.find("input").trigger("change");
                });
                
                btnDown.click(function() {
                    var oldValue = parseFloat(input.val());
                    if (oldValue <= min) {
                        var newVal = oldValue;
                    } else {
                        var newVal = oldValue - 1;
                    }
                    spinner.find("input").val(newVal);
                    spinner.find("input").trigger("change");
                });
            });

        }

        function cartUpdate() {
            $('button[name="update_cart"], .remove').click(function() { setTimeout(function(){ qtyChange(); }, 3000); setTimeout(function(){ cartUpdate(); }, 3000); }); } $(document).ready(function() {
            qtyChange();
            cartUpdate();
        });
    </script>

* O tempo limite de 3000 parece um pouco alto, mas cada número menor que tentei ainda produziu vários problemas em que algo não estava funcionando. Tudo executa com aquele timeout o tempo todo, que é o objetivo :-) Só tem que aguentar um pouco e tudo funciona!