• Resolved mohammedmalleck

    (@mohammedmalleck)


    Hi!,
    If I filter products by ajax the custom quantity input elements are not rendered after ajax filtering is finished…
    This is my custom code for adding quantities in archive page

    // Adding quantity for products on the archive page
    add_filter('woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_loop_ajax_add_to_cart', 20, 2);
    function quantity_inputs_for_loop_ajax_add_to_cart($html, $product) {
    if ($product && $product->is_type('simple') && $product->is_purchasable() && !$product->is_sold_individually()) {
    // Get product stock quantity and stock status
    $stock_quantity = $product->get_stock_quantity();
    $stock_status = $product->is_in_stock() ? 'in-stock' : 'out-stock';

    // Get the necessary classes for the button
    $class = implode(' ', array_filter(array(
    'button',
    'product_type_' . $product->get_type(),
    $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
    $product->supports('ajax_add_to_cart') ? 'ajax_add_to_cart' : '',
    )));

    if ($product->is_in_stock()) {
    // If product is in stock, display quantity and add to cart

    $html = sprintf('%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>',
    woocommerce_quantity_input(array(
    'min_value' => 1, // Minimum value
    'max_value' => $stock_quantity, // Maximum value based on stock
    'input_value' => 1, // Default value
    ), $product, false),
    esc_url($product->add_to_cart_url()),
    esc_attr(1),
    esc_attr($product->get_id()),
    esc_attr($product->get_sku()),
    esc_attr($class),
    esc_html($product->add_to_cart_text())
    );
    } else {
    // If product is out of stock, display "View Product" button
    $html = sprintf('<a href="%s" class="button view_product view-product-btn-archive">%s</a>',
    esc_url(get_permalink($product->get_id())), // Link to the product page
    esc_html__('View Product', 'woocommerce') // Text for the button
    );
    }
    }

    return $html;
    }

    I will really appreciate if you guys can figure out why this occurs, thanks !

    The page I need help with: [log in to see the link]

Viewing 11 replies - 1 through 11 (of 11 total)
  • Plugin Support fesupportteam

    (@fesupportteam)

    Hi @mohammedmalleck

    Please check this page – https://filtereverything.pro/resources/ajax-instructions-only/ under AJAX-related problems.

    Some of the functions (JS code) are not AJAX compatible by default, so you need to make them AJAX compatible.

    Best Regards – Victor

    Thread Starter mohammedmalleck

    (@mohammedmalleck)

    ty for the response ,
    From what I can understand from the guide it says me to add “ready” listener in the jQuery function if only the “functionality” is not working after ajax…
    the theme toggler example explains that it is not a rendering issue but a functionality issue…

    Whereas for me , it appears to be my custom quantity is not being re-rendered on filter ajax…
    let me know if I mis read something

    Plugin Support fesupportteam

    (@fesupportteam)

    @mohammedmalleck

    AJAX updates all of the elements of the chosen container, those new elements that appear do not have applied counters JS code on them with the needed event listeners.

    So you can use this “wrapper” to re-init your JS code that will place the needed event listeners on those new elements.

    jQuery(document).on('ready', function(e){
    /* Plugin function to re-init, e.g. jQuery("[data-fancybox]").fancybox(); */
    });

    Best Regards – Victor

    Thread Starter mohammedmalleck

    (@mohammedmalleck)

    I am not sure if I am following correctly , when you say

    those new elements that appear do not have applied counters JS code on them with the needed event listeners.

    you mean that the elements are being added they are just not interactive right?? if yes , that is not the case since as I said the elements are in fact not being added in the HTML after the ajax filtering….

    You can inspect dev tools to see that the html structure is different after and before the filtering…

    Although , I did made my JS have that “ready”listener but that did not help either
    heres the code

    add_action('wp_footer', 'archives_quantity_fields_script');
    function archives_quantity_fields_script() {
    ?>
    <script type='text/javascript'>
    jQuery(function($) {
    // Update data-quantity on input change
    $(document.body).on('click input ready', '.wpsf-cart-button input.qty, .product-action-wrap input.qty', function() {
    var quantityInput = $(this);
    var quantityValue = parseInt(quantityInput.val(), 10);
    var maxQuantity = parseInt(quantityInput.attr('max'), 10); // Get max value from attribute

    // Ensure quantity does not exceed max
    if (quantityValue > maxQuantity) {
    quantityInput.val(maxQuantity);
    }

    // Update data-quantity on the corresponding add to cart button within the same parent
    quantityInput.closest('.wpsf-cart-button, .product-action-wrap').find('a.ajax_add_to_cart').attr('data-quantity', quantityInput.val());
    $(".added_to_cart").remove(); // Optional: Removing other previous "view cart" buttons
    });

    // Ensure data-quantity is updated on button click
    $(document.body).on('click ready', '.add_to_cart_button', function() {
    var button = $(this);
    var quantityInput = button.closest('.wpsf-cart-button, .product-action-wrap').find('input.qty');
    var quantityValue = quantityInput.val(); // Get the current quantity value

    // Ensure the button has the correct quantity
    button.attr('data-quantity', quantityValue);

    setTimeout(function() {
    quantityInput.val(1); // reset quantity to 1 after adding to cart
    }, 2000); // After 1 second
    });
    });
    </script>
    <?php
    }
    Plugin Support fesupportteam

    (@fesupportteam)

    @mohammedmalleck

    Something more like this, we just:

    jQuery(document).on('ready', function (e) {
    // Update data-quantity on quantity input change
    jQuery(document.body).on('click input ready', '.wpsf-cart-button input.qty, .product-action-wrap input.qty', function() {
    var quantityInput = jQuery(this);
    var quantityValue = parseInt(quantityInput.val(), 10);
    var maxQuantity = parseInt(quantityInput.attr('max'), 10); // Get max value from attribute

    // Ensure quantity does not exceed max
    if (quantityValue > maxQuantity) {
    quantityInput.val(maxQuantity);
    }

    // Update data-quantity on the corresponding add to cart button within the same parent
    quantityInput.closest('.wpsf-cart-button, .product-action-wrap').find('a.ajax_add_to_cart').attr('data-quantity', quantityInput.val());
    jQuery(".added_to_cart").remove(); // Optional: Removing other previous "view cart" buttons
    });

    // Ensure data-quantity is updated on button click
    jQuery(document.body).on('click ready', '.add_to_cart_button', function() {
    var button = jQuery(this);
    var quantityInput = button.closest('.wpsf-cart-button, .product-action-wrap').find('input.qty');
    var quantityValue = quantityInput.val(); // Get the current quantity value

    // Ensure the button has the correct quantity
    button.attr('data-quantity', quantityValue);

    setTimeout(function() {
    quantityInput.val(1); // reset quantity to 1 after adding to cart
    }, 2000); // After 1 second
    });
    });

    Best Regards – Victor

    Thread Starter mohammedmalleck

    (@mohammedmalleck)

    Same result on my end :/ , the issue still persists
    Updated code:


    add_action('wp_footer', 'archives_quantity_fields_script');
    function archives_quantity_fields_script() {
    ?>
    <script type='text/javascript'>

    jQuery(document).on('ready', function (e) {
    // Update data-quantity on quantity input change
    jQuery(document.body).on('click input ready', '.wpsf-cart-button input.qty, .product-action-wrap input.qty', function() {
    var quantityInput = jQuery(this);
    var quantityValue = parseInt(quantityInput.val(), 10);
    var maxQuantity = parseInt(quantityInput.attr('max'), 10); // Get max value from attribute

    // Ensure quantity does not exceed max
    if (quantityValue > maxQuantity) {
    quantityInput.val(maxQuantity);
    }

    // Update data-quantity on the corresponding add to cart button within the same parent
    quantityInput.closest('.wpsf-cart-button, .product-action-wrap').find('a.ajax_add_to_cart').attr('data-quantity', quantityInput.val());
    jQuery(".added_to_cart").remove(); // Optional: Removing other previous "view cart" buttons
    });

    // Ensure data-quantity is updated on button click
    jQuery(document.body).on('click ready', '.add_to_cart_button', function() {
    var button = jQuery(this);
    var quantityInput = button.closest('.wpsf-cart-button, .product-action-wrap').find('input.qty');
    var quantityValue = quantityInput.val(); // Get the current quantity value

    // Ensure the button has the correct quantity
    button.attr('data-quantity', quantityValue);

    setTimeout(function() {
    quantityInput.val(1); // reset quantity to 1 after adding to cart
    }, 2000); // After 1 second
    });
    });
    </script>
    <?php
    }
    Thread Starter mohammedmalleck

    (@mohammedmalleck)

    @fesupportteam
    any updates?

    Plugin Support fesupportteam

    (@fesupportteam)

    Hi @mohammedmalleck

    No, unfortunately, there are no updates, as you perhaps use the wrong code or anything else.

    Please check the video – https://www.youtube.com/watch?v=IqQ27jlAKYc

    Here is the test code from the video

    function add_red_circle_js() {
    ?>
    <script>
    document.addEventListener('DOMContentLoaded', function() {
    // jQuery(document).on('ready', function(e){
    // Select all elements with the class 'wc-block-product'
    const products = document.querySelectorAll('.wc-block-product');

    products.forEach(product => {
    // Create a red circle element
    const redCircle = document.createElement('div');
    redCircle.style.width = '20px';
    redCircle.style.height = '20px';
    redCircle.style.backgroundColor = 'red';
    redCircle.style.borderRadius = '50%';
    redCircle.style.position = 'absolute';
    redCircle.style.top = '10px';
    redCircle.style.left = '10px';
    redCircle.style.zIndex = '10';

    // Add a container for position relative if missing
    product.style.position = 'relative';

    // Append the red circle to the product element
    product.appendChild(redCircle);
    });
    });
    </script>
    <?php
    }
    add_action('wp_footer', 'add_red_circle_js');

    This part is a simple approach that not working with the AJAX :
    document.addEventListener('DOMContentLoaded', function() {
    // jQuery(document).on('ready', function(e){

    This is a second approach that work with the AJAX
    // document.addEventListener('DOMContentLoaded', function() {
    jQuery(document).on('ready', function(e){

    As you see we simply commented out one and uncommented the second one. Both uncommented would make errors.

    Best Regards – Victor

    Thread Starter mohammedmalleck

    (@mohammedmalleck)

    Hi @fesupportteam ,
    I get it your point here. When generating html in client side we need “ready” event to display it on ajax filtering BUT thats not my case as I am not rendering the HTML on client side but server side.

    I tried mixing the php with jQuery to re-render my html but I am failing so far.
    I think if maybe a specific ajax call is being made when filtering is done with the plugin I should then again invoke the add_filter function responsible for custom quantity selector html in products archive page.

    I initially came here with a hope that you might provide me with any such ajax call using which i can re-invoke the function , here is that function:

    add_filter('woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_loop_ajax_add_to_cart', 20, 2);
    function quantity_inputs_for_loop_ajax_add_to_cart($html, $product) {
    if ($product && $product->is_type('simple') && $product->is_purchasable() && !$product->is_sold_individually()) {
    // Get product stock quantity and stock status
    $stock_quantity = $product->get_stock_quantity();
    $stock_status = $product->is_in_stock() ? 'in-stock' : 'out-stock';

    // Get the necessary classes for the button
    $class = implode(' ', array_filter(array(
    'button',
    'product_type_' . $product->get_type(),
    $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
    $product->supports('ajax_add_to_cart') ? 'ajax_add_to_cart' : '',
    )));

    if ($product->is_in_stock()) {
    // If product is in stock, display quantity and add to cart

    $html = sprintf('%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>',
    woocommerce_quantity_input(array(
    'min_value' => 1, // Minimum value
    'max_value' => $stock_quantity, // Maximum value based on stock
    'input_value' => 1, // Default value
    ), $product, false),
    esc_url($product->add_to_cart_url()),
    esc_attr(1),
    esc_attr($product->get_id()),
    esc_attr($product->get_sku()),
    esc_attr($class),
    esc_html($product->add_to_cart_text())
    );
    } else {
    // If product is out of stock, display "View Product" button
    $html = sprintf('<a href="%s" class="button view_product view-product-btn-archive">%s</a>',
    esc_url(get_permalink($product->get_id())), // Link to the product page
    esc_html__('View Product', 'woocommerce') // Text for the button
    );
    }
    }

    return $html;

    }
    Plugin Support fesupportteam

    (@fesupportteam)

    Hi @mohammedmalleck

    In this case you can try to run JS code in the browser in order to make it work like that.

    Unfortunately, we cannot help here with anything else.

    Best Regards – Victor

    Thread Starter mohammedmalleck

    (@mohammedmalleck)

    Hi @fesupportteam

    So I was finally able to solve the issue , leaving the code here for anyone having the same issue as me!

    //re-add quantity on prodcuts archive page on filtering with ajax with filter everything plugin
    function addQuantityOnAjax() {
    ?>
    <script>
    jQuery(document).on('ready', function(e){
    // check if you are in products archive
    if(document.body.classList.contains("woocommerce-shop") && document.body.classList.contains("post-type-archive-product")){
    // iterate thorough all quantity elements in prodcut details!
    document.querySelectorAll(".products > li .product-details .product-action-wrap .quantity").forEach( quantityContainer =>{
    //save dynamic values , like min,max,id & name
    const minValue = parseFloat(quantityContainer.querySelector(".input-text").getAttribute('min'));
    const maxValue = parseFloat(quantityContainer.querySelector(".input-text").getAttribute('max'));
    const id = quantityContainer.querySelector(".input-text").id;
    const name = quantityContainer.querySelector("label").textContent;
    //add quantity added class for styling purposes
    quantityContainer.classList.add("spinners-added");
    //add html to re-render the part which was not rendering previously

    quantityContainer.innerHTML =
    <br> <input type="button" value="-" class="minus"><br> <label class="screen-reader-text" for="${id}">${name}</label><br> <input type="number" id="${id}" class="input-text qty text" name="quantity" value="1" aria-label="Product quantity" min="${minValue}" max="${maxValue}" step="1" placeholder="" inputmode="numeric" autocomplete="off"><br> <input type="button" value="+" class="plus"><br>;
    });
    }
    });
    </script>
    <?php
    }
    add_action('wp_footer', 'addQuantityOnAjax');
    • This reply was modified 1 year, 6 months ago by mohammedmalleck. Reason: typos :/
Viewing 11 replies - 1 through 11 (of 11 total)

The topic ‘Quantity Issue with Ajax’ is closed to new replies.