meteor-foundation
meteor-foundation copied to clipboard
Meteor-Foundation + Iron-Router = no js for Foundation
What?
No js for Foundation works if we have iron-router
package installed.
Steps to get issue:
- mrt add foundation
- mrt add iron-router
- write in js:
Router.map(function() {
this.route("hello", { path: "/" });
});
- write in html:
<head>
<title>fnd</title>
</head>
<body></body>
<template name="hello">
<nav class="top-bar">
<section class="top-bar-section">
<ul class="left">
<li class="has-dropdown"><a href="#">items</a>
<ul class="dropdown">
<li><a href="#">item 1</a></li>
<li><a href="#">item 2</a></li>
</ul>
</li>
</ul>
</section>
</nav>
</template>
- mrt (run server)
- dropdown does not work (
P.S.
If no Router.map is in js then dropdown works.
If write: $(document).foundation()
in console, then dropdown works too.
I am having the same exact issue!
zurb-foundation
package partially solves the problem (but you have to add {{> _init_foundation}}
to your layout). But other issues present (i.e. "Back" button does not appear in mobile dropdown menu).
Tried router
package instead of iron-router
-- same issue. I guess there is no way now to use foundation + any router by simple adding package.
P.S. meteor's standart twitter bootstrap package (mrt add bootstrap
) works like a charm with any router.
Sorry for the slow response on this; I've been out of town and awfully busy.
In any case, I'll finally get a chance to look at this tonight, so I'll see what I can find out!
Thank you, ewall!
Is it possibly just affecting the nav-bar? I can replicate the problem for that, but other JS-based stuff like the tooltips, dropdowns, and modals seem to work okay with HTML like the following (also work when split into different routes and templates):
<h3>JavaScript Testing</h3>
<p>
<span data-tooltip data-options="disable-for-touch:true" class="has-tip" title="Tooltips are awesome, you should totally use them!">Hover here to see the tooltip.</span>
</p>
<p>
<a href="#" data-dropdown="drop1" class="button">Test Dropdown</a> |
<a href="#" data-dropdown="drop2" class="button">Test Content Dropdown</a>
</p>
<ul id="drop1" class="f-dropdown" data-dropdown-content>
<li><a href="#">This is a dead link</a></li>
<li><a href="#">This is another</a></li>
<li><a href="#">Yet another</a></li>
</ul>
<ul id="drop2" class="f-dropdown content" data-dropdown-content>
<li>Some text goes here. Lorem ipsum and all that jazz.</li>
</ul>
<div id="myModal" class="reveal-modal">
<h2>Pop! goes the dialog</h2>
<p class="lead">Did you see that? It just <poof!> appeared!</p>
<p>Even more burbling goes here.</p>
<a class="close-reveal-modal">×</a>
</div>
<p>
<a href="#" data-reveal-id="myModal" class="large success button">Click Me For A Modal</a>
</p>
It's mysterious that re-initializing the Foundation JavaScripts makes the top-nav dropdowns start working, when other items on the page are clearly using stuff from the same foundation.min.js file.
Hi ewall, first, thanks for dedicating time to this.
In my case it also affected the orbit slider. And it also gets fixed after calling $(document).foundation() and waiting for the next slide to pass. Could the issue be related with css?
Hi all,
I got around this issue using the same hack as the one in zurb-foundation
, where I just added a render function on my layout containing $(document).foundation();
I'm not sure if this helps getting this fixed, but it seems to work as a workaround.
So my main template now has:
Template.main.rendered = function() {
$(document).foundation();
}
Has anyone managed to get iron-router and foundation 5 js work together yet with this package or another one ? Or even with a hack ? Nothing seems to work
I think @Fiachna is spot-on with his suggestion. With a "normal" HTML page, you initialize Foundation's JS when the DOM is ready (which this Meteor package can do for you already). With Meteor and Iron Router, you need to initialize the JS when the template is ready. So hooking $(document).foundation();
onto the appropriate Template.NAME.rendered
events is good.
Alternately, the zurb-foundation package now solves the Iron Router problem a different way, by hooking the Router.onAfterAction()
event:
Router.onAfterAction(function () {
Deps.afterFlush(function () {
Foundation.init(document);
});
});
I'm thinking I may tweak my package's initialization code with this, but first I'd like to investigate a bit more.
I think , with newer versions of Meteor, we cannot rely on rendered to hook our stuff since now it is called only once. Meteor update the bits of the templates that change without calling rendered.
More info: https://github.com/avital/meteor-ui-new-rendered-callback
However, it is still very weird to me that dropdown fails to work when changed dynamically but everything gets solved if I run $(document).foundation();
on the console. Still won't work if I hook that line to run reactively when my template changes.
Any tips appreciated.
@ewall This hack seems not work any more after meteor 0.9.0 and iron:router 0.9.1?
Sorry this hack works well with meteor 0.9.0.
In my case which just broken, I used a pause() in a onBeforeAction callback, it prevents the onAfterAction. That's the reason.
Sorry.
It seems recently many of Foundation's documentation pages added a section at the bottom which addresses these kind of situations. (Substitute many of the component names like 'accordion', 'reveal', etc. where I've written '#####'.)
Adding New ##### Content After Page Load
If you add new content after the page has been loaded, you will need to reinitialize the Foundation JavaScript by running the following:
$(document).foundation();
Reflow will make Foundation check the DOM for any elements and re-apply any listeners to them.
$(document).foundation('#####', 'reflow');
So... basically, since Meteor is likely to be swapping out page content frequently, you're going to be need to be reinitializing and reflowing frequently as well.
(I've not yet investigated Zurb's new Foundation for Apps to see if they have made improvements along these lines, but I wouldn't be surprised if they're trying to tackle this refresh problem there.)
Thanks ewall! Adding that line to my template fixed the problem (spent way too long trying to figure this out). I understand it might be constantly reinitializing and reflowing every time I load the template, but for most lightweight cases it should work just fine.
If you do not want to add a rendered
callback to each of your templates, it is possible to add them in an automated fashion from within a Meteor.startup()
.
// Initialize foundation once the document is ready.
$(function() {
$(document).foundation();
});
// Install rendered callback for each defined template on client startup.
Meteor.startup(function(){
var reflow = _.debounce(function() {
$(document).foundation('reflow');
}, 100);
// http://stackoverflow.com/questions/11022131/run-js-after-rendering-a-meteor-template
for(var property in Template){
if(Blaze.isTemplate(Template[property])) {
var template = Template[property];
var orig = template.rendered;
template.rendered = function() {
if (_.isFunction(orig)) {
orig.apply(this, arguments);
}
Tracker.afterFlush(reflow);
};
}
}
});
With the introduction of Template.onRendered
in Meteor 1.0.4, this can be simplified significantly:
$(function() {
$(document).foundation();
});
Meteor.startup(function(){
var reflow = _.debounce(function() {
Tracker.afterFlush(function() {
$(document).foundation('reflow');
});
}, 100);
for (var property in Template) {
if (Blaze.isTemplate(Template[property])) {
Template[property].onRendered(reflow);
}
}
}
Adding:
$(document).foundation('#####', 'reflow');
On template rendered worked for me, thanks @ewall =)
I'll keep this issue open, although it's not exactly a problem with the package but a "feature" of how Foundation works -- but this thread may be useful for reference.
same issue nothing helps