bouncer icon indicating copy to clipboard operation
bouncer copied to clipboard

Issue with preventDefault call in bouncer library

Open rouilj opened this issue 1 year ago • 1 comments

I am using your bouncer library. The form that it is used on has two submit buttons. When I click on one of them, I expect to see the data for the button's name/value in the posted form.

I was debugging a user's issue today and found out that my form wasn't submitting the button data.

I tracked it down to:

         var submitHandler = function (event) {

                            // Only run on matching elements
                            if (!event.target.matches(selector)) return;

                            // Prevent form submission
                            event.preventDefault();  // <------ this

                            // Validate each field
                            var errors = publicAPIs.validateAll(event.target);

                            // If there are errors, focus on the first one
                            if (errors.length > 0) {
                                    errors[0].focus();
                                    emitEvent(event.target, 'bouncerFormInvalid', {errors: errors});
                                    return;
                            }

                            // Otherwise, submit if not disabled
                            if (!settings.disableSubmit) {
                                    event.target.submit();
                            }

                            // Emit custom event
                            if (settings.emitEvents) {
                                    emitEvent(event.target, 'bouncerFormValid');
                            }
                    };

The event.preventDefault() call prevents the data from the submit button from being included in the post payload when it gets submitted by event.target.submit().

It can be fixed by calling preventDefault() only if errors were found:

                            // If there are errors, focus on the first one
                            if (errors.length > 0) {
                                    // Prevent form submission only on
                                    // error. event.preventDefault() has a
                                    // side effect of preventing the
                                    // submit button's value from being submitted.

                                    event.preventDefault();

                                    errors[0].focus();
                                    emitEvent(event.target, 'bouncerFormInvalid', {errors: errors});
                                    return;
                            }

which makes more sense as we want the default (form submission) to happen in this case if there are no errors.

https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault says:

       Calling preventDefault() during any stage of event flow cancels the
       event, meaning that any default action normally taken by the
       implementation as a result of the event will not occur.

My guess is that preventDefault() stops the button from putting its own data into the form.

This post discussed a similar issue in the context of jQuery:

   https://github.com/foundation/foundation-sites/issues/12066

that lead me to the solution above.

rouilj avatar May 15 '23 02:05 rouilj

This is fixed in https://github.com/cferdinandi/bouncer/pull/76.

xini avatar May 15 '23 02:05 xini