What is a correct way to use jQuery plugins which manipulate DOM on every page onload? (Ember 2.8.0)

There are multiple jQuery plugins which parse entire page content and manipulate DOM onload, for example Materialize. They work fine on first page load but break when another route template is rendered because it doesn’t fire document.ready event. How to properly hook initializing these plugins to every template render?

You could use GitHub - mike-north/ember-cli-materialize: Material Design (via Materialize) for Ember.js Apps

1 Like

This is not an answer. I want to use multiple different jQuery plugins and certainly will NOT move to some Ember-native alternatives only because I don’t know how to force Ember router to reload them correctly (yet).

Hey @senthe — I think that @broerse was trying to point you in a helpful direction that might give you an answer. That addon contains a number of examples of how you might use components to invoke jQuery plugins. Components have lots of hooks that can replace the need for DOM Onload.

That being said, this type of question might be better suited for Stack Overflow or the Ember Slack Help channel.

3 Likes

I figured that probably you guys will know better what is “correct way” to do it than SO, I also don’t have any code or want code, just a right direction and a space to discuss Ember-y solutions.

Let’s say I have a plugin that goes through all the DOM, not only some specific selected elements.

Generally what you suggest is to wrap plugin initialization in a component’s didRender and then render it in some place. Pollutes DOM a bit but I guess can’t hurt. Is there a way to be certain that some specific didRender hook is run when ALL the components are already rendered? (Like document.ready?)

Or should I include this component’s template in every template that uses it (so didRender fires when parent component is certainly already rendered)? Because if so it means sometimes I’ll run init for a plugin 20 times during the same page render, feels inefficient.

I just… don’t really get how it makes sense that Ember router doesn’t fire document.ready?..

There’s is an Application.ready event that gets fired (http://emberjs.com/api/classes/Ember.Application.html#event_ready) but its fired prior to routing occurring (due to some opinions mentioned below).

To answer your question here though. Ember views your page as a bunch of small chunks (components) that come and go on the page depending on actions you take. Rather than having a high-level event listener watching the entire page (and manipulating the DOM based on events) as you do with jQuery, the goal is for the components to handle the DOM internally (if needed) so that when those components are removed things remain clean.

The reason the Materialize Ember plugin was recommended is because in general plugins that watch the entire page (like Bootstrap, Materialize, etc) don’t work well with Ember philosophy (or really SPA philosophy, as React and Angular add this same constraint). So folks work hard on breaking down the “entire body” listener approach that many jQuery plugins use into Ember addons that use those plugins in an Ember-compatible way.

It sounds like right now you’re working hard to do something that Ember deliberately discourages. Generally I find when I’m fighting the framework it’s because my understanding of the problem is different (and often not as complete as the framework authors).

Is there something else you can do to accomplish your same goals? What plugins are you trying to use? Can you find corresponding ones on EmberObserver.com?

Oh and also, welcome to Ember! Glad to have you join us and do keep asking questions, folks are quite interested in helping around here …

1 Like