meteor-foundation icon indicating copy to clipboard operation
meteor-foundation copied to clipboard

Meteor-Foundation + Iron-Router = no js for Foundation

Open imkost opened this issue 11 years ago • 19 comments

What? No js for Foundation works if we have iron-router package installed.

Steps to get issue:

  1. mrt add foundation
  2. mrt add iron-router
  3. write in js:
Router.map(function() {
  this.route("hello", { path: "/" });
});
  1. 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>
  1. mrt (run server)
  2. 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.

imkost avatar Aug 26 '13 00:08 imkost

I am having the same exact issue!

flaborda avatar Aug 28 '13 15:08 flaborda

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.

imkost avatar Aug 29 '13 12:08 imkost

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!

ewall avatar Sep 03 '13 22:09 ewall

Thank you, ewall!

imkost avatar Sep 03 '13 22:09 imkost

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>&nbsp;|&nbsp;
  <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 &lt;poof!&gt; appeared!</p>
  <p>Even more burbling goes here.</p>
  <a class="close-reveal-modal">&#215;</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.

ewall avatar Sep 04 '13 04:09 ewall

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?

flaborda avatar Sep 04 '13 16:09 flaborda

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();
}

Fiachna avatar Sep 27 '13 05:09 Fiachna

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

jadus avatar Jan 09 '14 21:01 jadus

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.

ewall avatar Jul 12 '14 02:07 ewall

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.

flaborda avatar Jul 22 '14 21:07 flaborda

@ewall This hack seems not work any more after meteor 0.9.0 and iron:router 0.9.1?

chuangbo avatar Aug 27 '14 03:08 chuangbo

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.

chuangbo avatar Aug 27 '14 03:08 chuangbo

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.)

ewall avatar Dec 17 '14 03:12 ewall

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.

adrianmcli avatar Jan 20 '15 15:01 adrianmcli

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);
      };
    }
  }
});

znerol avatar Mar 11 '15 13:03 znerol

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);
    }
  }
}

znerol avatar Mar 20 '15 12:03 znerol

Adding: $(document).foundation('#####', 'reflow'); On template rendered worked for me, thanks @ewall =)

ssoulless avatar Aug 19 '15 04:08 ssoulless

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.

ewall avatar Aug 19 '15 14:08 ewall

same issue nothing helps

masterofdaemon avatar Mar 16 '16 23:03 masterofdaemon