jQuery validation doesn't load first time template is rendered


#1

Hi all,

I have a simple form with jQuery validation, using https://atmospherejs.com/themeteorchef/jquery-validation and autoNumeric: https://github.com/gibson/meteor-autonumeric.

To see the form, you need to be logged in.

Whenever Meteor restarts the local server or when I log in to view the form, then I don’t see any of the jQuery validation nor the autoNumeric input formatting (one of the fields is currency).

In order to “get” the jQuery validation, I need to click to a different route and click back or refresh the page while logged in. Then everything works as it should, jQuery appears, all the front-end validation is working, etc.

I thought it was a loading issue and tried https://themeteorchef.com/snippets/loading-patterns/#tmc-smooth-loading-using-the-onready-callback and the other examples TMC has, but the issue persists.

I apply jQuery via Template.userRequests.onRendered.

Does anyone know what could be causing jQuery to not apply on the first render of the template? Why do I need to render it twice?


#2

Sounds like you’re applying the validation after onRendered (HTML tag from templates is complete) but before your subscription is ready (data context is still empty).

Then your subscribed data arrives, and is filled in. But the validator does not know this.

As you move to a different route and comes back, data is already available when the template gets rendered, and this time when the validator runs it runs on the correct data.


#3

Isn’t the arrival of subscribed data irrelevant though?

From what I understand, the form doesn’t need to wait on any subscribed data (as it doesn’t use any), so it loads and then validation is applied to it via onRendered.


#4

Sounds like an issue with the javascript event loop. Try wrapping your jQuery call in your onRendered callback within a Meter.defer or Meteor.setTimeout.


#5

Thank you, Meteor.setTimeout solved it.

For anyone who has this issue in the future this is what I did:

Template.userRequests.onRendered(function() {
  return Meteor.setTimeout(userRequestsChecks, 2000);
});

Where userRequestsChecks is a function containing the front-end jQuery validation.


#6

Using setTimeout in this way is an anti-pattern.

Please show some sample-code of your application, in particular your onRendered-callback.