Nav tabs not working as expected - javascript

Please bear with me as I'm extremely new to Meteor. I am attempting to dynamically create both tabs and their respective content within one template using the following code. The expected data does show up, but on my first tab (let's say the value of {{Name}} is "FirstTab") I see the {{Name}} for all of the items in my levels collection. However, when I click on the other tabs, I see only the expected {{Name}} values, even when I return to the "FirstTab" tab. Obviously, I'm iterating incorrectly somewhere...but I don't understand why it works when I click out of the first tab. How should I be implementing this?
<ul class="nav nav-tabs" role="tablist">
{{#each indexedArray levels}}
{{#if _isFirstIndex }}
<li role="presentation" class="active">{{Name}}</li>
{{ else }}
<li role="presentation" class="">{{Name}}</li>
{{/if}}
{{/each}}
</ul>
<div class="tab-content">
{{#each indexedArray levels}}
<div role="tabpanel" class="tab-pane active" id="{{removeSpaces Name}}">
<h2>{{Name}}</h2>
</div>
{{/each}}
</div>

Realized I could just add the same {{#if _isFirstIndex }} around the tabpanel div to make it work as expected. However, I agree with #MasterAM that this is definitely un-Meteor-like and I'll need to refactor following that advice.

Related

Update a partial in dust.js without touching the rest of the template

I'm experimenting around with dust.js and am wondering about the most efficient way to solve this:
I have a simple template structure with 2 levels of navigation and content.
The first level of navigation is static - while the second level (the subnavigation) changes with each change in the primary navigation.
Parent Template:
<nav class="navbar navbar-fixed-top navbar-dark">
<div class="container">
{>"navigation/navigation_primary"/}
{>"navigation/navigation_secondary"/}
</div>
</nav>
<div class="container"></div>
Primary Navigation Template:
<div class="navbar-container navbar-primary">
<ul class="nav navbar-nav">
{#navigation_primary}
<li class="nav-item">
<a class="nav-link" href="#{slug}">{label}</a>
</li>
{/navigation_primary}
</ul>
</div>
Secondary Navigation Template:
<div class="navbar-container navbar-secondary">
<ul class="nav navbar-nav">
{#navigation_secondary}
<li class="nav-item">
<a class="nav-link" href="#{slug}">{label}</a>
</li>
{/navigation_secondary}
</ul>
</div>
Now, my problem is this: Without reloading the page, I'ld like to update the "secondary navigation", when I click on the primary navigation elements.
The way I'ld do this, is to re-render the "Secondary Navigation Template" and then replace the old ".navbar-secondary" with the newly rendered template ( with jQuery.html() ) - but I was wondering if dust.js has it's own feature for this, since it's able to load partials asynchroneusly?
To be honest, I didn't find most of the dust.js documentation very informative, so I'm having a hard time figuring the details out.
Is there a better way to update only a partial and leaving the rest of the template untouched, without using something like jQuery.html() and replace the partial in dust.js?

Bootstrap collapse is not working with the each loop of Meteor.js

I'm retrieving a list of locations in the following template
<template name="explore">
<h2>Explore Places</h2>
<ul>
{{#each locations}}
<h4><a data-toggle="collapse" data-target="#info">{{name}}</a></h4>
<p id="info" class="collapse">{{{information}}}</p>
{{/each}}
</ul>
</template>
Whenever a location is clicked I want to show its corresponding hidden information by the use of the bootstrap collapse. But clicking on any link in the list always shows information of the first item in the list.
Solved it, I was using the same 'id' for each collapsible tag:
<template name="explore">
<h2>Explore Places</h2>
<ul>
{{#each locations}}
<h4><button class="btn btn-mini" data-toggle="collapse" data-target="#{{name}}">{{name}}</button></h4>
<li>
<p id="{{name}}" class="collapse">{{{information}}}</p>
</li>
{{/each}}
</ul>
</template>

Materialize: dropdown in "if" statement doesn't work

I tried to implement a dropdown list that is only visible when the user is signed in. The dropdown list works when outside the "if" statement but not inside. The buttons "Foo" and dropdown button are shown, however it doesn't "dropdown".
header.html
<!-- Header -->
<template name="header">
<nav>
<div class="nav-wrapper">
<a class="brand-logo" href="{{pathFor 'home'}}">Logo</a>
<ul id="nav-mobile" class="right hide-on-med-and-down">
{{#if currentUser}}
<!-- dropdown1 trigger -->
<li>
<a class="dropdown-button" href="#!" data-activates="dropdown1">
<i class="mdi-navigation-more-vert"></i>
</a>
</li>
<li>Foo</li>
{{else}}
<li>Sign in</li>
{{/if}}
<li>About</li>
</ul>
</div>
</nav>
<!-- dropdown1 structure -->
<ul id="dropdown1" class="dropdown-content">
<li class="signout">Sign out</li>
</ul>
</template>
header.js
Template.header.rendered = function () {
$(".dropdown-button").dropdown({
belowOrigin: true // Displays dropdown below the button
});
};
What could be the problem?
When your Template.header.onRendered lifecycle event is first fired, the dropdown HTML elements are not yet inserted into the DOM because the condition {{#if currentUser}} is not yet met (it takes a small amount of time before being actually logged in a Meteor app, that's why Meteor.user being reactive is handy !).
This is why your jQuery dropdown initialization fails : the DOM is not yet ready ! The solution is quite simple thoug : refactor your Spacebars code to put the dropdown markup in its own separate template :
<template name="dropdown">
<li>
<a class="dropdown-button" href="#!" data-activates="dropdown1">
<i class="mdi-navigation-more-vert"></i>
</a>
</li>
<li>Foo</li>
</template>
Then insert the child template inside your header template :
{{#if currentUser}}
{{> dropdown}}
{{else}}
{{! ... }}
{{/if}}
This way the dropdown will have its own onRendered lifecycle event that will get triggered only after the user is logged in, and at this time the dropdown DOM will be ready.
Template.dropdown.onRendered(function(){
this.$(".dropdown-button").dropdown({
belowOrigin: true // Displays dropdown below the button
});
});
Sometimes refactoring your code into smaller subtasks is not just a matter of style, but it makes things work the way intended.

Meteor accounts-ui dropdown behavior when embedded in the navbar dropdown

I am trying to place the standard Meteor accounts-ui into a navbar dropdown with the cog icon as shown in the screenshot and code snippet below. However, two issues arise:
Before signing in, there is an odd extra whitespace on the right side. After signing in, it aligns fine.
After a single click on any of the elements in the dropdown, the dropdown immediately closes. This is fine when I click Sign in with Google or Sign in, but it should not do that when I click into the text input fields, Forgot password or Create account.
How can I address the above behaviors accordingly while still using the accounts-ui package? For instance, is there some sort of JS code I can use to override the behavior to fix #2? Thanks!
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<span class="glyphicon glyphicon-cog"></span>{{loginText}}
<ul class="dropdown-menu">
<li><b>{{> loginButtons align="right"}}</b></li>
</ul>
</li>
</ul>
</div>
</nav>
ian:accounts-ui-bootstrap-3 provides a Bootstrap dropdown out of the box. The code will look like:
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<ul class="nav navbar-nav navbar-right">
{{> loginButtons}}
</ul>
</div>
</nav>
But this does not display a cog-wheel. If you want to override the default dropdown link to a custom one, you need to override the template in the package. AFAIK, Meteor core doesn't have an easy way to do this, but you can use aldeed:template-extension to achieve this quite simply. First copy the template code from the accounts-ui-bootstrap-3 repo, then create a new template with similar content but different name:
<template name="my_loginButtonsLoggedInDropdown">
<li id="login-dropdown-list" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown">
... custom content here ...
</a>
<div class="dropdown-menu col-sm-3">
{{#if inMessageOnlyFlow}}
{{> _loginButtonsMessages}}
{{else}}
{{#if inChangePasswordFlow}}
{{> _loginButtonsChangePassword}}
{{else}}
{{> _loginButtonsLoggedInDropdownActions}}
{{/if}}
{{/if}}
</div>
</li>
</template>
Then use
Template.my_loginButtonsLoggedInDropdown.replaces("_loginButtonsLoggedInDropdown")
It will replace the template, but still use the helpers and events from the original template.

AngularJS : Appending the same structure on the click of each item

My index.html page is like following:
<div id="sidepanel" ng-controller="myCtrl">
<ul class="drop-down">
<li ng-repeat="item in items">
{{item.name}}
</li>
</ul>
</div>
<div id="mainpanel" ng-controller="listCtrl">
<div ng-view></div>
</div>
For this ng-view I have record-list.html to show all the records which is like following:
<div class="container">
<ul class="design">
<li id="{{record.name}}" ng-repeat="record in records">
<div>......</div>
</li>
</ul>
</div>
Now i want to add the same structure (as like each record) append on the click of each item of the side panel.
what is the logic for that ?
My recent UI Looks like this & i want to add the same structure on each click which should be append the existing structure.
Please Help.Thanks.
It sounds like perhaps each "record" has a set of children "records." If this is the case, I would recommend using angular's ng-switch directive to conditionally display the correct (or no) set of sub-records on the side.

Categories

Resources