How to run JQuery code when document is ready in Meteor?

I want to do the following in Meteor

		if($(".modal").length>0) {
			$(".modal").each(function() {
				$(".modal").prependTo( "body" );

I’ve tried in layout.js

Template.layout.onRendered(function () {
    if($(".modal").length>0) {
        $(".modal").each(function() {
            $(".modal").prependTo( "body" );

not working.
How to prepend to modals to body in Meteor? Thanks a lot!

Instead of using jQuery document ready, use Meteor.startup(function () { /* Your code goes here */ }).

Also, how are your modals defined? Are they Blaze templates? If they are, then you should use Blaze.render(Template.yourModalTemplate, document.body).

I tried the following in client/modal.js , and not working.

Meteor.startup(function () {
    if($(".modal").length>0) {
        $(".modal").each(function() {
            $(".modal").prependTo( "body" );

The strange thing is in Template.layout.onRendered way, if I go to /admin and return to /, the modals prepend, but if I go to /posts and return to /, nothing happens.

How are your modals defined? As in where did you put the HTML code for them?


<template name="homePage">
<div class="page-top">
    <div class="container">
      <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="modal fade" id="videoModal" tabindex="-1" role="dialog" aria-labelledby="videoModel" aria-hidden="true">

<template name="layout">
  <div class="scrollToTop"><i class="fa fa-arrow-up"></i></div>
  <div class="page-wrapper">
    {{> headerTop }}
    {{> header }}
    {{> yield }}
    {{> footer }}

layout.js as above.

Are your modals supposed to be available site wide or only on certain routes?

Maybe its something related to
My admin layout template is adminLayout.html and the front side layout template is layout.html, If the layout template changes, the layout.js will work? But my scroll up function can work anyway.

//Scroll totop in layout.js

        $(window).scroll(function() {
            if($(this).scrollTop() != 0) {
            } else {
        $(".scrollToTop").click(function() {

If I detect there are modals in current route(page), then automatically prepend them to body. So I think it’s site wide.

The reason to prepend the modals is , otherwise, the modal is behind the body.

And I tried JQ the code in console, it works.

Oh in that case you can’t use layout.onRendered because it only runs once. You need to do it on the onRendered of the route templates because when you change route they will get re-run because they get destroyed when you go to a different route. The layout template doesn’t get destroyed unless you set a different layout somewhere else.

If you use the aldeed:template-extension package it’ll help you to attach the onRendered on a global level.

Thanks for the aldeed:template-extension, I’ll try it later.

In Template.layout.onRendered(function () {}
I tried

if($(".modal").length>0) {
            console.log('has modals');
            $(".modal").each(function() {
                $(".modal").prependTo( "body" );

When goto /, nothing, seems JQ doesn’t find modals. When goto /admin return to /, console shows has modals. That’s so weird.

If the reason is related to layout.onRendered because it only runs once, why I enter /, nothing happens?

Not really answering your question, but you could use jchristman:reactive-modal, which is a library for reactive bootstrap modals… There are a couple of other options also so you don’t need to re-roll your own code.

Quick note about the link above - it is a fork of pahans:reactive-modal, which was not being maintained. I fixed all of the bugs I knew about and added a few reactive features.

Thanks a lot! I’ll try your extension later! Because I only have one modal here at homepage. I decide to leave it and fix the bug later.

Fix the problem and understand the problem.

do it on the onRendered of the route templates move JQ code into home_page.js will work.

aldeed:template-extension modify template.js Template.onRendered(function () {} will work.