Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to properly handle dom ready for Meteor

Tags:

meteor

I am currently using iron-router and this is my very first attempt to try out the Meteor platform. I has been running into issues where most of the jquery libraries failed to initialized properly because the of the way Meteor renders html, $(document).ready() fires before any templates are rendered. I am wondering is there any callbacks from Meteor/iron-router that allows me to replace the jQuery's dom ready?

Also, how should I (easily and properly) handle the live update of the dom elements if some of them are customized by jQuery/javascript?

This is what i am currently doing, i feel like it is very hackish and probably would run into issues if the elements got updated after the initialization.

var jsInitalized = false;

Router.map(function () {
  this.route('', {
    path: '/',
    layoutTemplate: 'default',
    after: function(){
      if(!jsInitalized){
        setTimeout(function(){
          $(document).ready( function() { $$$(); });
        }, 0);
        jsInitalized = true;
      }
    }
  });
}
like image 518
megablue Avatar asked Dec 06 '13 14:12

megablue


3 Answers

With Meteor you generally want to think about when a template is ready, not when the dom is ready.

For example, let's say you want to use the jQuery DataTables plugin to add sorting to a table element that's created by a template. You would listen to the template's rendered event and bind the plugin to the dom:

HTML:

<template name="data_table">
  <table class="table table-striped" id="tblData">
  </table>
</template>

JavaScript:

Template.data_table.rendered = function () {
  $('#tblData').dataTable();
};

Now anytime the template is re-rendered (for example, if the data changes), your handler will be called and you can bind the jQuery plugin to the dom again.

This is the general approach. For a complete example (that includes populating the table with rows) see this answer.

like image 172
jrullmann Avatar answered Dec 01 '22 15:12

jrullmann


Try making a separate .js file, call it rendered.js if you'd like. and then;

Template.layout.rendered = function ()
{
    $(document).ready(function(){console.log('ready')});
}

I use template layout, but you can do Template.default.rendered. I hope that helps.

Also take a look at this part of documentation, especially the Template.events; http://docs.meteor.com/#templates_api

like image 23
Perspective Avatar answered Dec 01 '22 15:12

Perspective


I use Meteor v0.8.0 with Iron Router (under Windows 7) and here is how I handle 'DOM ready':

When I want to modify the DOM after a specific template has been rendered:

I use Template.myTemplateName.rendered on the client side :

Template.blog.rendered = function()
{
    $('#addPost').click(function() 
    { 
        ...
    });
}

When I want to modify the DOM after any new path has been rendered:

I use Router.onAfterAction, but there seems to be a trick:

Router.onAfterAction(function()
{
    setTimeout(function() 
    {
        $('.clickable').click(function() 
        { 
            ...
        });
    }, 0);
});

Notice the setTimeout(..., 0), it doesn't work for me otherwise (DOM empty).

Notice that you can use onAfterAction on specific path, but most of the time I think it is redundant with the Template.myTemplateName.rendered method above.

What seems to be missing:

A way to modify the DOM after any template has been rendered.

like image 44
steph643 Avatar answered Dec 01 '22 14:12

steph643