Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I don't find any way to stop request from htmx:beforeRequest listener #2681

Open
YannCharlou-CleverAge opened this issue Jun 27, 2024 · 2 comments

Comments

@YannCharlou-CleverAge
Copy link

Hi,

I'm using htmx 1.9.12 in a Symfony 6.4 project with assetMapper.

I've made lot of try but not found any way to stop the request when a included form is not valid.

Event is correctly catched by my event Listener, everything seems working well except the htmx request is not aborted.
If I check evt.detail.xhr.readyState when receiving the event, his value is 1 (opened).

<button hx-post="/step4_payment/pay" hx-include="#register_form,#occupants_form,#payment_plans_form,#optin_form,#terms_form,#cartItemId" hx-swap="none" >
        <span class="btn-text">Continuer</span>
</button>
import htmx from 'htmx.org';

window.htmx = htmx;

// validate included forms
document.body.addEventListener('htmx:beforeRequest', function(evt){

    let hxInclude = evt.target.getAttribute('hx-include');
    if (!hxInclude){
        return
    }

    let isValid = true;
    hxInclude.split(',').forEach(selector => {
        let elements = document.querySelectorAll(selector.trim());
        elements.forEach(elem => {
            if (elem.tagName === 'FORM') {
                isValid = isValid && elem.reportValidity();
            }
        });
    });

    if(!isValid){
    
        // I don't find any way to stop request... :(
        // this 3 lines below don't stop the request.
        evt.detail.xhr.abort(); // abort request
        evt.target.dispatchEvent(new CustomEvent('htmx:abort'));
        evt.preventDefault();

        // scroll to first one
        const invalidInputs = Array.from(document.querySelectorAll(':invalid, .is-invalid, .form-error'))
        invalidInputs.sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top)
        invalidInputs[0].scrollIntoView({ behavior: 'smooth' })
    }

})
@Telroshan
Copy link
Collaborator

Hey, it's likely to be an error with your scripting logic, as calling event.preventDefault should work just fine, see this JSFiddle for instance. If the checkbox is unticked, I call preventDefault in a body's htmx:beforeRequest listener callback just like you did above, and the request is correctly prevented from happening.

If you add logs to your script, could it be possible that isValid is simply not false when you expect it to be so? Thus your request abortion logic wouldn't be called at all

@YannCharlou-CleverAge
Copy link
Author

Hi Telroshan,

Thank you for your answer.

I've already checked that isValid is correct. (By placing a console.log in the if)
I've also checked this way that the event is only called once.

Maybe it comes from another script. On this project I'm using Alpinejs too and the alpine-morph extension but I never heard that any of these can cause any trouble with HTMX.

I will double check the network log to see if I missing something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants