How can I limit when Marketo forms call their validation method?

Anonymous
Not applicable

How can I limit when Marketo forms call their validation method?

Hello!

I've implemented a floating label pattern, like this one:
http://dribbble.s3.amazonaws.com/users/6410/screenshots/1254439/form-animation-_gif_.gif

You can see my version working properly in the form at http://www.mobify.com/contact

That's a regular form that uses a workaround to send the data at an associated Marketo landing page. Not ideal. 

Embedding forms into pages with the API is a much more sustainable solution, but it has issues that can be seen on http://www.mobify.com/blog/ if you click the "Subscribe Now" button in the sidebar without typing anything in. 

It should result in you getting errors that overlap with other labels. Gross.

The way Marketo handles validation makes it really hard for me to either:

A) Detect the moment when Marketo has inserted an error message
B) Use a different, first layer of validation before submission that is easier for me to control, such as jQuery's validate plugin.

I tried using the onValidate() callback function, but it only works on submit. The docs list the same named function (onValidate(callback)) twice with two different use cases, but I only can make the submit one work. Kinda leaves me scratching my head. 

I'm totally open to new ways of doing this. Right now my first idea is to limit the calls to Marketo's validation function.

Do you have any thoughts/ideas on how to solve this issue? Thanks in advance!
Tags (1)
2 REPLIES 2
Anonymous
Not applicable

Re: How can I limit when Marketo forms call their validation method?

Hi Rowan,

I can confirm the same behavior: the onValidate callback is only called when the form is submitted; required fields appear to validate input without calling the onValidate callback when the field is focused or blurred. It would be nice if we could get that callback to happen every time a .mktoError bubble popped up.

I initially thought of selectively unbinding the focus and blur event handlers responsible for triggering the validation when you click between fields (so it would work like your other form: not validate until submit), but this is not really an option because the handler callback functions are anonymous and bound during form initialization. Unbinding event handlers requires a reference to the callback to disambiguate multiple handlers on the same event.

The best idea I have is to bind additional focus and blur event handlers on each field. This would allow you to either specify a separate callback that is responding to essentially the same events as the validation system, or to actually call the validate() function explicitly each time a field is focused or blurred (causing it to behave as you would initially expect: the onValidate callback actually happens when tabbing/clicking between fields).

Please let me know if this makes any sense, or have general questions about the technique.

Best,
Kyle
Anonymous
Not applicable

Re: How can I limit when Marketo forms call their validation method?

Hey Kyle,

Thanks for the response! That makes a lot of sense, and is how my current implementation works.

If that's the best route to do this, then I'll share how I'm doing it, and where it gets challenging for me. 

CODE DUMP!

var INPUT_SELECTOR = 'input:not(:checkbox), textarea';

/* Listen for activity on any input or textarea's values */
$(document).on('keyup blur focus', INPUT_SELECTOR, function(e) {
    var $target = $(e.target);
    var $label = $('label[for="' + $target.prop('name') + '"]');
    var $error = $target.siblings('.mktoError');
 
    /* We use setTimeout here because we want this to run after other
       event handlers */
    setTimeout(function() {
        /* Check if there's an error and hide the label if there is one */
        $label.toggleClass('hide', $error.is(':visible'));
        /* Make sure that focusing triggers the label */
        $label.toggleClass('focus', $target.is(':focus'));
 
        /* Keep the label triggered if the input has any value */
        $label.toggleClass('triggered', !!$target.val());
        $target.toggleClass('triggered', (!!$target.val() || $error.is(':visible')));
    }, 0);
});

END CODE DUMP!

Here's the issue I'm having: sometimes an error will still be fading in and doesn't meet the "is(':visible')" criteria. This means the label just stays there, oblivious to the fact that it's overlapping with the error message. 

I'm using the "is(':visible')" criteria in the first place because Marketo likes to hide/show .mktoError, and they don't necessarily remove the error from the DOM when it clears, so I can't simply check for the .mktoError's existence.

It just seemed inefficient to try and combat this specific problem with opacity on the .mktoError, so I came here looking for a better way. If this is the road we have to go down... any idea on what to do to optimize this pattern?

Thanks so much,
Rowan

P.S - Is there a better way to format code on discussion boards here?