Passing WSForm Lite selection to cart

Hi everybody,

I am trying to show products in a page using WSForm Lite and allow user to select and pass that to cart page. I am able to generate a code using ChatGPT, but the issue is it only able to send the one selection, but there is two radio option and one checkbox. So if customers select them all, it supposes to send the 3 products to cart.

Here is the code for functions.php

add_action('wp_enqueue_scripts', function () {
    if (is_page('booking')) { // Replace 'booking' with the slug of your page
        wp_enqueue_script('wc-add-to-cart');
        wp_localize_script('wc-add-to-cart', 'wc_add_to_cart_params', array(
            'ajax_url' => admin_url('admin-ajax.php'),
            '_wpnonce' => wp_create_nonce('woocommerce-add-to-cart'),
        ));
    }
});

Here is the JS code

(function ($) {
    // Store selected product URLs
    let selectedProductURLs = [];

    // Helper function to add product URL
    function addProductURL(url) {
        if (!selectedProductURLs.includes(url)) {
            selectedProductURLs.push(url);
        }
    }

    // Helper function to remove product URL
    function removeProductURL(url) {
        selectedProductURLs = selectedProductURLs.filter(item => item !== url);
    }

    // Event handler for WSForm rendering
    $(document).on('wsf-rendered', function (e, form, form_id, instance_id) {
        // Ensure the script runs only for the specific form ID (1 in this case)
        const my_form_id = 1;
        if (form_id != my_form_id) return;

        // Gearbox radio button logic
        const gearboxButtons = document.querySelectorAll(".gearbox .gearbox-child");
        const radios = document.querySelectorAll(".course-radio [role='radiogroup']");
        gearboxButtons.forEach((button) => {
            if (button.checked) {
                radios[1].style.display = "none";
            }

            button.addEventListener('click', () => {
                if (button.value === "Automatic") {
                    radios[1].style.display = "flex";
                    radios[0].style.display = "none";
                } else {
                    radios[0].style.display = "flex";
                    radios[1].style.display = "none";
                }
            });
        });

        // Handle course radio buttons
        const courseRadios = document.querySelectorAll(".course-radio input[type='radio']");
        courseRadios.forEach((radio) => {
            radio.addEventListener('change', (e) => {
                const linkTagMatch = radio.value.match(/href="([^"]+)"/);
                if (linkTagMatch && linkTagMatch[1]) {
                    // Remove previously selected course from the same group
                    courseRadios.forEach(r => {
                        const valueMatch = r.value.match(/href="([^"]+)"/);
                        if (valueMatch && valueMatch[1]) removeProductURL(valueMatch[1]);
                    });

                    // Add the selected course
                    addProductURL(linkTagMatch[1]);
                }
            });
        });

        // Handle practical test checkbox
        const practicalTestCheckbox = document.querySelector(".p-test input[type='checkbox']");
        practicalTestCheckbox.addEventListener('change', (e) => {
            const linkTagMatch = e.target.value.match(/href="([^"]+)"/);
            if (linkTagMatch && linkTagMatch[1]) {
                if (e.target.checked) {
                    addProductURL(linkTagMatch[1]);
                } else {
                    removeProductURL(linkTagMatch[1]);
                }
            }
        });

        // Handle theory test radio buttons
        const theoryTestRadios = document.querySelectorAll(".t-test input[type='radio']");
        theoryTestRadios.forEach((radio) => {
            radio.addEventListener('change', (e) => {
                const linkTagMatch = radio.value.match(/href="([^"]+)"/);
                if (linkTagMatch && linkTagMatch[1]) {
                    // Remove previously selected theory test
                    theoryTestRadios.forEach(r => {
                        const valueMatch = r.value.match(/href="([^"]+)"/);
                        if (valueMatch && valueMatch[1]) removeProductURL(valueMatch[1]);
                    });

                    // Add the selected theory test
                    addProductURL(linkTagMatch[1]);
                }
            });
        });

        // Form submission handling
        $('#wsf-1-field-2').closest('form').on('submit', function (e) {
            e.preventDefault();

            // Debugging: Log selected URLs before proceeding
            console.log("Selected product URLs: ", selectedProductURLs);

            if (selectedProductURLs.length > 0) {
                const addToCartPromises = selectedProductURLs.map(url => {
                    // Ensure correct product ID extraction
                    const productId = url.split('add-to-cart=')[1];
                    console.log('Adding Product ID:', productId);


                    return $.ajax({
                        url: wc_add_to_cart_params.ajax_url, // WooCommerce's AJAX URL
                        type: 'POST',
                        data: {
                            action: 'woocommerce_add_to_cart',
                            product_id: productId,
                            quantity: 1,
                            _wpnonce: wc_add_to_cart_params._wpnonce // WooCommerce nonce
                        }
                    });
                });

                Promise.all(addToCartPromises)
                    .then(() => {
                        // Redirect to cart after adding all items
                        // window.location.href = '/cart';
                    })
                    .catch(error => {
                        console.error('Error adding to cart:', error);
                    });
            } else {
                console.log("No products selected.");
            }
        });
    });
})(jQuery);

In wplocal it sometimes works but in staging site it sends last product or the middle product to cart not 3 product every time.

Anyone know how to fix this issue?
TIA

Please rewite the whole JS code to the following. This will sove the issue. The AJAX call was the issue.

(function ($) {
    // Store selected product URLs
    let selectedProductURLs = [];

    // Helper function to add product URL
    function addProductURL(url) {
        if (!selectedProductURLs.includes(url)) {
            selectedProductURLs.push(url);
        }
    }

    // Helper function to remove product URL
    function removeProductURL(url) {
        selectedProductURLs = selectedProductURLs.filter(item => item !== url);
    }

    // Event handler for WSForm rendering
    $(document).on('wsf-rendered', function (e, form, form_id, instance_id) {
        // Ensure the script runs only for the specific form ID (1 in this case)
        const my_form_id = 1;
        if (form_id != my_form_id) return;

        // Gearbox radio button logic
        const gearboxButtons = document.querySelectorAll(".gearbox .gearbox-child");
        const radios = document.querySelectorAll(".course-radio [role='radiogroup']");
        gearboxButtons.forEach((button) => {
            if (button.checked) {
                radios[1].style.display = "none";
            }

            button.addEventListener('click', () => {
                if (button.value === "Automatic") {
                    radios[1].style.display = "flex";
                    radios[0].style.display = "none";
                } else {
                    radios[0].style.display = "flex";
                    radios[1].style.display = "none";
                }
            });
        });

        // Handle course radio buttons
        const courseRadios = document.querySelectorAll(".course-radio input[type='radio']");
        courseRadios.forEach((radio) => {
            radio.addEventListener('change', (e) => {
                const linkTagMatch = radio.value.match(/href="([^"]+)"/);
                if (linkTagMatch && linkTagMatch[1]) {
                    // Remove previously selected course from the same group
                    courseRadios.forEach(r => {
                        const valueMatch = r.value.match(/href="([^"]+)"/);
                        if (valueMatch && valueMatch[1]) removeProductURL(valueMatch[1]);
                    });

                    // Add the selected course
                    addProductURL(linkTagMatch[1]);
                }
            });
        });

        // Handle practical test checkbox
        const practicalTestCheckbox = document.querySelector(".p-test input[type='checkbox']");
        practicalTestCheckbox.addEventListener('change', (e) => {
            const linkTagMatch = e.target.value.match(/href="([^"]+)"/);
            if (linkTagMatch && linkTagMatch[1]) {
                if (e.target.checked) {
                    addProductURL(linkTagMatch[1]);
                } else {
                    removeProductURL(linkTagMatch[1]);
                }
            }
        });

        // Handle theory test radio buttons
        const theoryTestRadios = document.querySelectorAll(".t-test input[type='radio']");
        theoryTestRadios.forEach((radio) => {
            radio.addEventListener('change', (e) => {
                const linkTagMatch = radio.value.match(/href="([^"]+)"/);
                if (linkTagMatch && linkTagMatch[1]) {
                    // Remove previously selected theory test
                    theoryTestRadios.forEach(r => {
                        const valueMatch = r.value.match(/href="([^"]+)"/);
                        if (valueMatch && valueMatch[1]) removeProductURL(valueMatch[1]);
                    });

                    // Add the selected theory test
                    addProductURL(linkTagMatch[1]);
                }
            });
        });

// Function to add products to cart sequentially with delay
function addProductsToCartSequentially(selectedProductURLs) {
    console.log("Selected product URLs: ", selectedProductURLs);

    if (selectedProductURLs.length > 0) {
        let index = 0;
        
        // Function to process the next product
        function processNext() {
            if (index < selectedProductURLs.length) {
                const url = selectedProductURLs[index];
                // Ensure correct product ID extraction
                const productId = url.split('add-to-cart=')[1];
                console.log(`Adding Product ID (${index}):`, productId);

                $.ajax({
                    url: wc_add_to_cart_params.ajax_url, // WooCommerce's AJAX URL
                    type: 'POST',
                    data: {
                        action: 'woocommerce_add_to_cart',
                        product_id: productId,
                        quantity: 1,
                        _wpnonce: wc_add_to_cart_params._wpnonce // WooCommerce nonce
                    }
                }).then(response => {
                    console.log(`Success for Product ID (${index}):`, response);
                }).catch(error => {
                    console.error(`Error for Product ID (${index}):`, error);
                }).always(() => {
                    index++; // Move to the next product
                    setTimeout(processNext, 500); // Delay before the next request
                });
            } else {
                console.log('All products processed');
                // Redirect to cart after adding all items
                window.location.href = '/cart';
            }
        }

        // Start processing the first product
        processNext();
    } else {
        console.log("No products selected.");
    }
}

// Form submission handling
$('#wsf-1-field-2').closest('form').on('submit', function (e) {
    e.preventDefault();
    addProductsToCartSequentially(selectedProductURLs); // Call the sequential add function
});


    });
})(jQuery);

1 Like

@galibweb Thank you so much. The code is working. Really appreciate your effort.