Bug Can't remove items from cart on checkout page if it has required fields

Status
Not open for further replies.

benFF

Customer
If you have any items in your cart which have required order fields - you then cannot remove that item (or any other item) until the required fields have first been filled in.

I thought adding a simple formnovalidate tag to the delete button would solve this - and whilst it does let the form submit, then the backend validator fails it.
 
Whilst you're looking at the checkout - I suggest that maybe it's a better idea to put the custom order fields above the purchase options, so they're next to the actual items they are linked to.

Most orders don't use a coupon, so it's a bit strange to have to scroll past that just to fill them in.
 
Oh and finally, also related.

The purchase ux is not very intuitive.

When you click the original "purchase" button, the modal gives two options "add to cart" or "checkout"

Most people would assume you need to add to the cart before you can checkout, so they click that and are then returned to the original page, very confusing.

The checkout button text should be changed to "buy now" (or get now if it's free) and I think the icons swapped (shopping cart for add to cart and credit card for buy now)

This is how the original bug above was discovered. Users clicked add to cart, redirected, then clicked purchase again, but this time "checkout" - which of course meant they had two items (which then couldn't be deleted)
 
It gets even more bizarre - if you two or more products to the cart and then try and delete one, it will force me to accept the terms of service, then automatically submit the order and forward to the payment page!

I thought it might be a template edit I made, but I reverted them all now and it's still doing it.
 
The following changes will be made with v4 for XenForo 2.3:
  • Most credit card icons have been changed to a cart icon
  • The "Checkout" button in the purchase overlay has been renamed to "Express checkout" (new phrase)
  • Moved VAT information above Coupon/Store credit
  • Each part of the checkout form now has a separate block
  • The "Order fields" block now has a block header with the phrase "Required information" (new phrase)
  • The "Required information" and "Purchase options" blocks now have their own Save buttons
  • It is now possible to update item quantity in your cart on the Checkout page without filling in required information
  • It is now possible to delete items from your cart on the Checkout page without filling in any required information
  • It is now possible to update Coupon code/Store credit on the Checkout page without filling in any required information
Here's a preview screenshot of the new Checkout page:
1715436824196.png

This does have one downside; the entire form will no longer be saved when pressing any of the individual save buttons. When pressing "Proceed to payment", it will save & validate the entire form, but otherwise, only the button next to the block in question will save that particular block.

I don't believe there is a way around this without running into the same form validation issue.

Is that an acceptable compromise in your eyes, or do I need to look into alternate solutions?
 
Hi Fillip,

Looks good - I have been going over a lot of the UI/X in the last week or so as my order completion ratio was abysmal (1 in 10).

I think you have touched on basically everything I found, but yes I did the following:

On the overlay - changed the checkout text to Buy Now. I think I also swapped the icons around.
1715705617316.webp

Then did as you have, put the product options just below the item list, then the purchase options below that.

I then removed the scroll of text for the terms and conditions and changed it to a modal, with just the checkbox:
1715705706414.webp

Finally I moved the save button to below that and next to the payment button, renaming it to "Update cart"
1715705747509.webp

I think your solution with multiple save buttons should work, I will probably change the phrases though.

However the biggest change that I made was backend. The current system works well if you are registered, but if not, the flow is terrible and many customers are lost at this point as when they fill in their registration forms, they are either:

1) If no email validation required, they are taken to the default XF page that just says thanks for signing up.
2) If email validation is required, as soon as they click the link, like above, they are just taken to a default XF page.

At which point, non-technical minded people have no idea what to do.

To get around this, I extended the following controllers:

Register
PHP:
    public function actionComplete()
    {
        $reply = parent::actionComplete();

        // If the user has something in their cart, we will assume they are just signing up for a purchase, in which case redirect directly to the shopping cart
        $visitor = \XF::visitor();

        if ($visitor->user_state == 'valid'
            && $visitor->canViewDbtechEcommerceProducts()
            && $visitor->canPurchaseDbtechEcommerceProducts()
            && $visitor->getDbtechEcommerceCartItems())
        {
            return $this->redirect($this->buildLink('dbtech-ecommerce/checkout'));
        }

        return $reply;
    }

AccountConfirmation
PHP:
    public function actionEmail(ParameterBag $params)
    {
        $reply =  parent::actionEmail($params);

        $visitor = \XF::visitor();

        // If $view is a typeof view AND something in the cart, then it was a successful login, so redirect to checkout
        if ($reply instanceof \XF\Mvc\Reply\View
            && $visitor->user_state == 'valid'
            && $visitor->canViewDbtechEcommerceProducts()
            && $visitor->canPurchaseDbtechEcommerceProducts()
            && $visitor->getDbtechEcommerceCartItems())
        {
            return $this->redirect($this->buildLink('dbtech-ecommerce/checkout'));
        }

        return $reply;
    }

Since making all these changes, the failure rate has dropped considerably and at this point I think it's just down to people backing out, rather than an issue with the cart flow :)
 
Interesting, I had no idea there was no dynamic redirect. I’ll steal those extensions and implement them into the core :)
 
This does have one downside; the entire form will no longer be saved when pressing any of the individual save buttons. When pressing "Proceed to payment", it will save & validate the entire form, but otherwise, only the button next to the block in question will save that particular block.
I was thinking about this - and I'm not sure this is the best solution after all.

The goal is to try and make the checkout page as small and with as few clicks as possible.

The reason we need to be able to change quantity and delete items separately is because these actions are done without an order submission.

Updating the required fields and coupons though are expected to be done at the same time - just before someone is getting ready to checkout - so I would still think a single "Update cart" or "Update cart options" is best.

Less clutter and not as confusing (will a customer realise that the save button only saves that current section?) - Also - they now have to do 2 clicks to fill in custom fields and a coupon.

For reference, here is my condensed checkout form:

1716371595921.png

Even this is still a little confusing (does someone need to update cart options before they proceed to payment) - so I'm still thinking if I should put an "OR" in between those.
 
Oh also, one more thing I forgot.

On the registration form, due to the removal of the "Don't have an account..." section, people were also getting a bit confused here - so I moved the block to the top of the page and that seemed to solve that.

1716371849252.webp

Code:
<xf:breadcrumb href="{{ link('dbtech-ecommerce/checkout') }}">{{ phrase('dbtech_ecommerce_checkout') }}</xf:breadcrumb>

<xf:set var="$registerBackup" value="{$xf.options.registrationSetup.enabled}" />

<xf:if is="$xf.options.registrationSetup.enabled">
    <div class="blocks">
        {{ phrase('dont_have_account_question') }} <xf:button href="#register-form">{{ phrase('register_now') }}</xf:button>
    </div>
</xf:if>

<xf:include template="login">
    <xf:set var="$xf.options.registrationSetup.enabled" value="0" />
</xf:include>

<xf:set var="$xf.options.registrationSetup.enabled" value="{$registerBackup}" />

<xf:if is="$xf.options.registrationSetup.enabled">
    <div class="blocks-textJoiner"><span></span><em>{{ phrase('or_separator') }}</em><span></span></div>

    <span class="u-anchorTarget" id="register-form"></span>
    
    <xf:include template="register_form" />

    <xf:title>{{ phrase('dbtech_ecommerce_login_or_register') }}</xf:title>   
</xf:if>
 
Oh also, one more thing I forgot.

On the registration form, due to the removal of the "Don't have an account..." section, people were also getting a bit confused here - so I moved the block to the top of the page and that seemed to solve that.

View attachment 10530

Code:
<xf:breadcrumb href="{{ link('dbtech-ecommerce/checkout') }}">{{ phrase('dbtech_ecommerce_checkout') }}</xf:breadcrumb>

<xf:set var="$registerBackup" value="{$xf.options.registrationSetup.enabled}" />

<xf:if is="$xf.options.registrationSetup.enabled">
    <div class="blocks">
        {{ phrase('dont_have_account_question') }} <xf:button href="#register-form">{{ phrase('register_now') }}</xf:button>
    </div>
</xf:if>

<xf:include template="login">
    <xf:set var="$xf.options.registrationSetup.enabled" value="0" />
</xf:include>

<xf:set var="$xf.options.registrationSetup.enabled" value="{$registerBackup}" />

<xf:if is="$xf.options.registrationSetup.enabled">
    <div class="blocks-textJoiner"><span></span><em>{{ phrase('or_separator') }}</em><span></span></div>

    <span class="u-anchorTarget" id="register-form"></span>
   
    <xf:include template="register_form" />

    <xf:title>{{ phrase('dbtech_ecommerce_login_or_register') }}</xf:title>  
</xf:if>
There was no part of me that would ever have assumed people would get confused by having to move their mouse slightly further down to see the registration form 🤣

Thanks, I'll implement this in v4.
 
I was thinking about this - and I'm not sure this is the best solution after all.

The goal is to try and make the checkout page as small and with as few clicks as possible.

The reason we need to be able to change quantity and delete items separately is because these actions are done without an order submission.

Updating the required fields and coupons though are expected to be done at the same time - just before someone is getting ready to checkout - so I would still think a single "Update cart" or "Update cart options" is best.

Less clutter and not as confusing (will a customer realise that the save button only saves that current section?) - Also - they now have to do 2 clicks to fill in custom fields and a coupon.

For reference, here is my condensed checkout form:

View attachment 10529

Even this is still a little confusing (does someone need to update cart options before they proceed to payment) - so I'm still thinking if I should put an "OR" in between those.
Right.

I think I prefer having the separate buttons, but this is contingent on being able to stop a partially filled out form from erroring out if they use any other save button than the one next to the required field(s) or the one in the bottom.

I'll post back when I know more.
 
Alrighty so, I worked out how to disable validation conditionally.

Now, it works like this:
  • The "Delete selected" button is now completely separate. Ticking an item for deletion and then proceeding to payment does not actually delete said item. Users must press "Delete selected". This button also does not save the rest of the form.
  • All the other save buttons now save the entirety of the form. Any changes to required order fields are saved, but they are not validated (in HTML nor in PHP).
  • Pressing "Proceed to payment" will save the full form and trigger any and all validation. If anything changed that materially affected the price (store credit amount, coupon code), the form will reload rather than actually going to payment, in order to give users the option to review the order further.
Does this work better for you?
 
Hello @benFF,

We hope your ticket regarding DragonByte eCommerce has been addressed to your satisfaction. This ticket has now been scheduled to be closed.

If your ticket has not been resolved, you can reply to this thread at any point in the next 7 days in order to reopen the ticket, afterwards this thread will be closed.

Please do not reply to this thread if your ticket has been resolved.

Thank you.


- DragonByte Technologies, Ltd.
 
Hello @benFF,

As we have not heard back from you, your ticket regarding DragonByte eCommerce has now been closed.

If your ticket has not been resolved, please feel free to start a new support ticket and link back to this ticket.

If you have time, please leave a review on XenForo.com's Resource Manager.

Thank you.


- DragonByte Technologies, Ltd.
 
Status
Not open for further replies.

DragonByte eCommerce

XenForo 2.0.6+ XenForo 2.1.x XenForo 2.2.x XenForo 2.3.x
Seller
DragonByte Technologies
Release date
Last update
Total downloads
2,800
Customer rating
4.83 star(s) 6 ratings
Back
Top