Adding a class to a DOM element inside a template created by a 3rd party package


#1

I’m cross-posting this from my post on stackoverflow. I tried to link it but being a new user the forums wont let me.

I am currently utilizing Meteor, the materializecss atmosphere package, and the user-accounts:materialize atmosphere package. I am attempting to use materialize class-based styling to change the style of the user-accounts:materialize sign-in page, which is created by the {{>atForm}} template.

Template.atForm.onRendered( function(){
var element = $(".at-form, .at-btn");
element.addClass(“grey lighten-2 grey-text text-darken-4”);
});

This works great when the page is initially rendered. However, if I sign-in, then sign-out, the sign-in template is again presented but this time the onRendered() function isn’t called and my styling is lost. How do I avoid that?

And is there a better way to influence elements inside a 3rd party template than calling onRendered()?


#2

The current accepted way to customize the useraccounts package is to either [extend or write your own templates] (https://github.com/meteor-useraccounts/core/blob/master/Guide.md#extending-templates) or to apply css rules to the [classes already being used. ] (https://github.com/meteor-useraccounts/core/blob/master/Guide.md#css-rules)

The onRendered callback is only called on the first instance of a template being rendered, if parts of a template or the whole template is reRendered without being destroyed then it is not called.


#3

Exactly, the cleanest solution is probably to extend/override the existing templates.
Otherwise what will likely help you here is if you wrap your code inside the onRendered callback inside a this.autorun() call so it gets rerun every time its dependencies change. So you’d have to access inside that autorun whatever your styles should depend on – which sounded like Meteor.userId().

Template.atForm.onRendered( function(){
  var self = this;
  this.autorun(function() {
    var element = self.$(".at-form, .at-btn"); // good idea in general to limit scope of $ to the current template
    if (Meteor.userId()) {
      element.addClass("grey lighten-2 grey-text text-darken-4");
    } else {
      // something else...
    }
  });
});

(Even if you don’t need the userId itself, in order for the dependency to register and the function to be rerun every time the user/userId changes you have to “touch it” inside the autorun.)