Redirect to thanks page after order not working

Hi everybody. So I have old one MODX Revolution 2.8.3-pl with simple shop. All products are like resources. I made a simple cart with localStorage, after making order it sends to email order information.

General problems

  1. After pressing Order button, it is not redirecting to success page.
  2. I need to delete cart information after order is made.

What is wrong in my code??? Please help, i have spent a lot of hours and still can’t fix it ((((

The button in product page is like this:

[[*available:is=`3`:then=``:else=`<a class="btn" onclick="addToCart([[*id]], '[[*pagetitle]]', '[[+article]]', '[[*thumb]]', [[*price]], '[[~[[*id]]]]')">Add to cart</a>`]]
	    <script>
        function addToCart(id, name, article, thumb, price, url) {
            let cart = JSON.parse(localStorage.getItem('cart')) || [];
            const exists = cart.some(item => item.id === id);
            if (exists) {
                alert('Already added');
                return;
            }
            cart.push({ id, name, article, thumb, price, url });
            localStorage.setItem('cart', JSON.stringify(cart));
            alert('You added product to basket');
        }
        </script>

Next is a main chunk:

<div id="cart-container"></div>
<form method="post" action="[[~[[*id]]]]" class="cart_order_form ajax_form af_example" id="cart-form">
    <input type="text" name="name" placeholder="Name" required>
    <input type="text" name="phone" placeholder="Phone" required>
    <textarea name="comment" placeholder="Comments"></textarea>
    <input type="hidden" name="cart_content" id="cart_content">
    <button type="submit" class="btn">Order</button>
</form>

[[+fi.success:is=1:then=<div class="alert alert-success">[[+fi.successMessage]]</div>]]
[[+fi.validation_error:is=1:then=<div class="alert alert-danger">[[+fi.validation_error_message]]</div>]]

<script>
    function removeFromCart(id) {
        let cart = JSON.parse(localStorage.getItem('cart')) || [];
        cart = cart.filter(item => item.id !== id);
        localStorage.setItem('cart', JSON.stringify(cart));
        location.reload();
    }

    document.addEventListener("DOMContentLoaded", function () {
        let cart = JSON.parse(localStorage.getItem('cart')) || [];
        let container = document.getElementById('cart-container');
        let form = document.getElementById('cart-form');
        let hiddenField = document.getElementById('cart_content');

        if (cart.length === 0) {
            container.innerHTML = '<p>Cart is empty</p>';
            if (form) form.style.display = 'none';
        } else {
            if (form) form.style.display = 'block';

            let tableHtml = `
                <table style="width:100%; border-collapse:collapse;">
                    <thead>
                        <tr>
                            <th>Photo</th>
                            <th>Name</th>
                            <th>Delete</th>
                            <th>Price</th>
                        </tr>
                    </thead>
                    <tbody>
            `;

            let total = 0;

            cart.forEach((item) => {
                total += parseFloat(item.price);
                tableHtml += `
                    <tr>
                        <td><img src="${item.thumb}" alt="" style="width:120px;"></td>
                        <td><a href="${item.url}">${item.name}</a><br><small>аrt. ${item.article}</small></td>
                        <td>
                            <button type="button" onclick="removeFromCart(${item.id})" title="Delete" style="background:none; border:none; cursor:pointer; font-size:18px; color:#cc0000;">
                                <i class="fa fa-trash"></i>
                            </button>
                        </td>
                        <td>${item.price}</td>
                    </tr>
                `;
            });

            tableHtml += `
                    </tbody>
                </table>
            `;

            container.innerHTML = tableHtml;

            let totalElem = document.createElement('p');
            totalElem.style.textAlign = "right";
            totalElem.style.fontWeight = "bold";
            totalElem.style.marginTop = "10px";
            totalElem.textContent = `Total: ${total.toFixed(2)}`;

            container.appendChild(totalElem);

            hiddenField.value = JSON.stringify(cart);
        }
    });
</script>

Next is a cart page with:

[[!AjaxForm?
&form=cartFormTpl
&hooks=spam,email,redirect
&emailTpl=cartEmailTpl
&emailSubject=New order «[[++site_name]]»
&emailTo=[[++emailsender]]
&emailFrom=[[++emailsender]]
&validate=name:required,phone:required
&validationErrorMessage=Please fill all fields
&successMessage=Your order is send!
&redirectTo=[[~1511]]
]]

Next is page success with ID 1511. And last one is a chunk to send:

<p><strong>Name:</strong> [[+name]]</p>
<p><strong>Phone:</strong> [[+phone]]</p>
<p><strong>Comments:</strong> [[+comment]]</p>
<p><strong>Cart:</strong></p>
<pre>[[+cart_content]]</pre>

Hi dfish, just joining in to help. Your redirect issue might be because one of the earlier hooks, like spam or email, fails, so the redirect doesn’t run. Try using only email, redirect in the &hooks to test. Also, make sure [[~1511]] correctly points to your success page by checking the generated URL. To clear the cart, add localStorage.removeItem('cart') on the success page (ID 1511) in a small script.

Thanks for your answer. I tried to use only email and redirect still nothing. After i press order button i see in corner ajax (i think) success message. And thats all… page is not redirecting but email i receive. ((( couple days i am trying to fix it…

The normal FormIt redirect hook doesn’t work with AjaxForm.
Because the form submission is sent with AJAX, the page can’t be redirected on the server with PHP. This has to happen on the client with JS.

Take a look at the documentation here:

Half day of tests and still cant fix it. So resource of cart i changed to:

[[!AjaxForm?
    &snippet=`FormIt`
    &form=`cartFormTpl`
    &hooks=`email`
    &emailTpl=`cartEmailTpl`
    &emailSubject=`New order «[[++site_name]]»`
    &emailTo=`[[++emailsender]]`
    &emailFrom=`[[++emailsender]]`
    &validate=`name:required,phone:required`
    &validationErrorMessage=`Fill all fields!`
    &successMessage=`Your order is send!`
]]

Then i added in core/components/ajaxform/model/ajaxform/ajaxform.class.php after $this->modx->regClientHTMLBlock("<script>{$objectName}.initialize({$config});</script>");
added

$customScript = "
<script>
  document.addEventListener('DOMContentLoaded', function () {
    console.log('DOMContentLoaded OK');
    document.addEventListener('af_complete', function(event) {
      console.log('af_complete WORKS!');
      const form = event.detail.form;
      if (form && form.getAttribute('id') === 'cart-form') {
        localStorage.removeItem('cart');
        window.location.href = '/thanks';
      }
    });
  });
</script>
    ";
$this->modx->regClientScript($customScript, true);

I did it to load it before .I cant find out why i cant see in console “af_complete WORKS” i am really go crazy (((

It’s not good practice to change the code of an extra directly.

In my opinion it’s best to use the property &frontend_js for this.

  1. Add the property &frontend_js to the snippet call
[[!AjaxForm?
    &snippet=`FormIt`
    ...
    &frontend_js=`[[+assetsUrl]]js/mycustom.js`
]]
  1. Duplicate the file assets/components/ajaxform/js/default.js (which is used by default) and give it a new name (mycustom.js in my example here).
  2. Add the code below to the duplicated JS-file
$(document).on('af_complete', function (event, response) {
	console.log('af_complete WORKS!');
});

e.g. after this line in the existing code

halftrainedharry big thanks to you. One week of fight and finally it works. Fuuuf beer from me )

There is only one last thing i am trying to fix. Is it possible in my case to get work quantity badge? i have link to cart with badge.

	<li style="position:relative;">
	    <a href="cart" id="cart-link">Cart</a>
	    <span id="cart-quantity-badge" style="position:absolute; top:20px; right:25px; background-color:red; color:white; font-size:11px; width:15px; height:15px; border-radius:50%; display:none; align-items:center; justify-content:center; display:flex;">0</span>
    </li>

and i added

function updateCartBadge(quantity) {
    const badge = document.getElementById('cart-quantity-badge');
    if (badge) {
        if (quantity > 0) {
            badge.style.display = 'flex';
            badge.textContent = quantity;
        } else {
            badge.style.display = 'none';
        }
    }
}

but its not picking up data from local storage …

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.