Bootstrap tabs not populating on page reload

I’m using Bootstrap tabs for an app and when I do a page reload via the browser (not navigating in the app) the active bootstrap tab is not populating with it’s Meteor content.

As soon as I interact with the tabs the content starts loading. I assume this has something to do with Meteor and Bootstrap not playing together and Meteor isn’t notified that it has to load/reload content. Anyone else dealt with this and got any pointers?

How do you load the content? Static HTML? Ajax?

If you load content via Ajax, and it is

  • dependent on subscriptions
  • dependent on {{#if}} constructs

You might want to think about setting a timeout on loading the tabs (when depending on {{#if}} for example, or listen for Template.subscriptionsReady() before loading the content.

I assumed you’re using Blaze, for React there might be some similar difficulties, sadly I can’t help you with that.

I’m not sure I understand this question. I’m using a single Meteor template for both tabs, using regular Meteor helper functions. And now that I type that out here, maybe that’s the problem. There are two separate divs in a single template and one div goes into one tab and the other div goes to the other tab.

Here’s my template:

<template name='dl_list'>
  <ul class="nav nav-tabs">
    <li ><a data-toggle="tab" href="#to_download">To Be Downloaded</a></li>
    <li class="active"><a data-toggle="tab" href="#downloaded">Downloaded</a></li>
  </ul>
<div class="tab-content">
  <div class="tab-pane" id="to_download">
    <div class="dl_button"><input type="button" name="get_files" value="Download Selected Files"/></div>
      <div class="dl_list">
        <h2>Zip files to be processed</h2>
        <table class="table table-striped table-responsive table-condensed table-hover">
          <thead>
          <th>Buildings</th><th>Zip Files</th><th>Filename</th><th>Select</th>
          </thead><tbody>
          {{ #each zips_not_downloaded }}
            <tr>
            <td>{{ bldg_label }}</td><td>{{ wireless_zip_url }}</td><td>{{ encoded_bldg }}.zip</td><td align="center"><input class="dl_check" type="checkbox" name="download" id="{{wireless_zip_url}}"/></td>
            </tr>
          {{ /each }}
        </tbody></table>
    </div>
  </div>
  <div class="tab-pane" id="downloaded">
  <div class="dl_list">
    <h2>Zips downloaded</h2>
    <table class="table table-striped table-responsive table-condensed table-hover">
      <thead>
      <th>Zip File Name</th><th>Path</th><th text-align="right">Size</th><th>ID</th>
      </thead><tbody>
      {{ #each upload_list }}
        <tr>
          <td>{{ name }}</td><td>{{ path }}</td><td text-align="right">{{ size }}</td><td>{{ _id }}</td>
        </tr>
      {{ /each }}
    </tbody></table>
  </div>
  </div>
</div>
</template>

I’m going to try separating each tab’s content into it’s own template and see if I get any better results.

I’m not using #if, just #each. And I am dependent on subscriptions.

Yes, using Blaze.

Any thoughts or comments not that you have some more info about my app specifics?

Thanks for clarifying and sorry if my questions were a bit too general :wink:

the templates shouldn’t be the problem, but I am a bit worried about the subscriptions.
In my opinion, bootstrap should automatically adjust the tab content if the subscription becomes available,
but just to be sure you could initialize the tabs manually when the subscription is ready (or put the whole template in an #if block with Template.subscriptionsReady())

You can read more about how to initialize the bootstrap tabs here: http://getbootstrap.com/javascript/#tabs

Separating the tab templates did not make any difference. It still behaves the same, as you suspected.

In reading through the Bootstrap docs it says that you can initialize the tab without javascript/jquery by adding a data-toggle="tab" attribute to the links inside the ul block. I’ve got this in place and no joy. I’ll look into the Template.subscriptionsReady() option and see if that gets me any closer. Thanks for your help.

Followed the documentation in the blazejs.org web site re: Template.subscriptionsReady and still no joy. Here’s my template.

<template name="tab_dloaded">
  {{ #if Template.subscriptionsReady }}
  <div class="tab-pane" id="downloaded">
    <div class="dl_list">
      <h2>Zips downloaded</h2>
      <table class="table table-striped table-responsive table-condensed table-hover">
        <thead>
          <th>Zip File Name</th>
        <!--  <th>Path</th>-->
          <th text-align="right">Size</th>
          <th>ID</th>
        </thead><tbody>
      {{ #each upload_list }}
      <tr>
        <td>{{ name }}</td>
    <!--    <td>{{ path }}</td>-->
        <td text-align="right">{{ size }}</td>
        <td>{{ _id }}</td>
      </tr>
      {{ /each }}
      </tbody></table>
    </div>
  </div>
  {{ else }}
  <div class="loading">
    Loading...
  </div>
  {{ /if }}
</template>

And here’s the template code.

Template.tab_dloaded.onCreated( function () {
  this.subscribe( 'files.uploads.all' );
});

The new template is working as designed, meaning that I can see the “Loading…” message for a half second or so when the page loads. But, after the loading message goes away the template doesn’t render the page content that it’s supposed to.

Anyone have any ideas what is going on here? I can’t believe it’s this hard to make a Meteor app work with a standard Bootstrap feature. I must be doing something wrong somewhere.

If you console.log() the helper data, is anything being output in the browser console? The problem may be that you helper doesn’t know which tab is active?