New(ish) Marketo Forms bug w/required Checkbox fields, and a fix

Hey there! Here's a workaround for another forms bug.

Wish it were really new, but it seems to have been introduced in the forms2.js dated 2017-06-23. Just tuned in to it today thanks to a DM on the Community.

The bug: unchecked required checkboxes no longer show an error message. The checkbox is focused and it does stop the form from submitting, but because of the lack of error message, users won't know why.

Compare this buggy behavior when Submit is pressed:


And this expected behavior:


It's annoying that we have to fix it, but at least it's easy:[1]

MktoForms2.whenReady(function(form) {
   form.onValidate(function(native) {
      // Your error message as the 1st argument
      fixCheckboxValidation20170623("This field is required.", form, native);


fixCheckboxValidation20170623 = function(errorMessage, form, native) {
   var formEl = form.getFormElem()[0],
      topInvalid = formEl.querySelector(".mktoInvalid"),
      topInvalidCheckbox = formEl.querySelector(".mktoInvalid.mktoCheckboxList");

   if (!native && topInvalidCheckbox == topInvalid) {
      form.showErrorMessage(errorMessage, MktoForms2.$(topInvalidCheckbox));

I tagged the function very specifically with the buggy release in hopes it'll be solved soon. Let me know how you fare with the fix!

For the learners

Let me run through my coding approach as I typically do.

What's happening is that the Forms 2.0 library's native validation is successfully catching the unchecked checkbox, but the part of the library that renders the red popup bubble is broken.

So we don't need custom validation, we need custom behavior on the native validation. This is not a typical use of the library, and I don't think I've ever done it before. Usually I'm adding completely custom validation rules instead of the native rules.

To know that we're still in the native validation run, we run our code only if !native is true (meaning “native validation is not yet successful”).

The we fetch the topmost field wrapper (in DOM order), of any field type, that's marked as native-invalid:

topInvalid = formEl.querySelector(".mktoInvalid")

fetch the topmost field of checkbox field type that's native-invalid:

topInvalidCheckbox = formEl.querySelector(".mktoInvalid.mktoCheckboxList")

and compare the two results: topInvalidCheckbox == topInvalid.

If they refer to the same element, that means the topmost invalid element is a checkbox and therefore the library must be trying, but failing, to signal an error. We then call showErrorMessage to manually show a message on that element.

In all other cases, we let the native validation and error popup do its stuff..


[1] As usual I eschew jQuery as much as technically possible, but showErrorMessage requires a jQ object, so I have to bite the bullet there.