Is there something strange about the way Meteor loads jQuery?
Asked Answered
S

5

5

I'm having some difficulties with standard jQuery functionality when I use Meteor. My main 'client/server' JS file looks like this:

if (Meteor.is_client) {
$(document).ready(function(){
$('#myDiv').append("foo");
console.log('bar');
});
}

When I load the app, 'bar' logs fine, but .append doesn't work. If I call the same .append in the console after page load, it works fine. (Similarly if I run the same code in a non-Meteor setting, it also works fine.)

The code I actually want to run looks like this:

$(document).ready(function(){
var myModel = new MyModel({"name": "foo"});
var myModelView = new MyModelView({model: myModel});
});
var MyModel = Backbone.Model.extend({
initialize: function() {  
}
});
var MyModelView = Backbone.View.extend({
el: $('#myEl'),
initialize: function(){
_.bindAll(this, 'render');
this.render();
},
render: function(){
$(this.el).append(this.model.get('name'));
console.log(this.model.get('name'))
}
});

The method that isn't working here is render, in the View. The console.log bit of the render method is fine, but the jQuery append doesn't work. Initially I wondered whether it was something about the way I was using Backbone that was the problem, but now I'm wondering if it's a Meteor/jQuery issue instead?

Saddle answered 13/5, 2012 at 17:35 Comment(0)
B
13

Perhaps try using Meteor.startup on the client-side:

if (Meteor.is_client) {
    Meteor.startup(function () {
        $(document).ready(function (){
            $('#myDiv').append("foo");
            console.log('bar');
        });
    });
}

From what I gather in the Meteor docs, the $(document).ready() call may even be superfluous when using Meteor.startup

Buccinator answered 17/5, 2012 at 17:58 Comment(0)
R
10

The following worked for me:

if (Meteor.is_client) {
    Template.templateNameThatContainsMyDiv.rendered = function(){
        $('#myDiv').append("foo");
        console.log('bar');
    };
}
Response answered 7/11, 2012 at 19:25 Comment(0)
C
5

$(document).ready kicks of when the initial static DOM has finished loading, if you are using any JS templating libraries then the initial static DOM is most likely empty at the time when $(document).ready is ran. So, you will have to subscribe with a callback to kick off your code when the template has done rendering. If that's not possible you'll have to use .on or .bind and listen for the insertion of the DOM node you are looking for...

Concinnous answered 13/5, 2012 at 17:53 Comment(0)
D
0

Both the:

$(document).ready

and the:

Template.templateName.rendered = function(){

solutions are depending on the templates being shown on startup and/or all their content is populated. If you for example use a

{{#if show}} 

for the actual content within a template, jQuery might not always bind. I ended up adding a

{{bindEvents}}

at the end of my template and then:

Template.templateName.bindEvents = function(){
$( "#accordion" ).accordion();
}

Feels hackish but this way my jQuery works properly no matter how the actual content is loaded in relation to the template or document themselves.

Daysidayspring answered 21/9, 2014 at 6:26 Comment(0)
S
0

Meteor Helper

Template.templateName.helpers({
    runJQueryPlugin: function() {
        $('#itemId').dropdown();
    }
}

Blaze

<template name="templateName">
    {{#if currentUser}}
        <div id="itemId">JQuery Dropdown Menu</div>
        {{runJqueryPlugin}}
    {{else}}
        <div>Login Button</div>
    {{/if}}
</template>

This works for me.

Scribbler answered 22/6, 2016 at 4:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.