Two clicks needed to load Modal and SideNav (Meteor with Materialize) - javascript

I have a strange problem with my Materialize navigation in Meteor. The weird thing is that when I click a link in the navigation, the sidebar or modal is only loaded on the SECOND click. Thus, I have to click the link once (where nothing happens) and then again for the element to appear. After that, the element loads on any click (only one click is required).
I have never had this problem, and I think it could be a Materialize problem. Before I count materialize out, though, I want to check with you guys and hear if I am possibly calling my JQuery functions wrong or something. Here is the code:
header.html:
<template name="header">
<nav>
{{> sideNav}}
<div class="nav-wrapper">
<span class="light"></span>hamok
<ul id="nav-mobile" class="left">
<li><i class="mdi-navigation-menu"></i></li>
<li><i class="mdi-action-search left"></i>Search</li>
</ul>
<ul id="nav-mobile" class="right">
{{#if currentUser}}
<li><a id="logout">Sign out</a></li>
{{else}}
<li><a class="modal-trigger-login" href="#loginModal">Account<i class="left mdi-action-account-circle"></i></a></li>
{{/if}}
</ul>
</div>
</nav>
{{> loginModal}}
</template>
<template name="loginModal">
<div id="loginModal" class="modal">
<div class="modal-content">
{{> atForm}}
</div>
</div>
</template>
<template name="sideNav">
<ul id="slide-out" class="side-nav">
<li>First Sidebar Link</li>
<li>Second Sidebar Link</li>
</ul>
</template>
header.js
Template['header'].helpers({
});
Template['header'].events({
'click .modal-trigger-login': function() {
$('.modal-trigger-login').leanModal();
},
'click #logout': function() {
Meteor.logout();
},
'click .button-collapse': function() {
$(document).ready(function(){
$(".button-collapse").sideNav();
});
}
});
Thank you guys for taking a look!

What leanModal does is initializing the jQuery plugin, so it should be called inside of your template onRendered function, not when clicking on the modal trigger button.
Template.header.onRendered(function(){
this.$(".modal-trigger-login").leanModal();
});
You can remove your click .modal-trigger-login event : you currently need 2 clicks simply because the first one will just initialize the plugin.
Likewise, your sideNav initialization call should be made in the onRendered lifecycle event :
Template.header.onRendered(function(){
this.$(".button-collapse").sideNav();
});

Related

Prevent angular 2 from redirecting <a href="#"> to homepage

I have a sample login page which directs to a dashboard. The login page is set as the initial redirect page and this routes to the dashboard. The dashboard contains a dropdown menu with some links. Everytime a link is clicked it keeps redirecting to the login page. However, when the dashboard page is reloaded the dropdown menu works completely fine.
I am thinking of using the "event.preventDefault()" for the links but I hope there is a workaround.
Dashboard Menu - HTML
<div class="navbar-default sidebar" role="navigation">
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<i class="fa fa-calendar fa-fw"></i> Manage Events<span class="fa arrow"></span>
<ul class="nav nav-second-level collapse">
<li>
Lorem Ipsum
</li>
<li>
Lorem Ipsum
</li>
</ul>
<!-- /.nav-second-level -->
</li>
</ul>
</div>
<!-- /.sidebar-collapse -->
</div>
Edit: After getting some replies, I would like to clarify my main problem.The problem exists in the link being a null link and that Angular 2 takes it as a null link and causes it to redirect it. If I could find a workaround to tell Angular, don't take this link as a null link it will be ideal.
If you don't want any redirection when clicking on your link(s), check out these solutions:
Different methods to make a null link?
Or you can put <a> tag without href attribute.
<div class="sidebar-nav navbar-collapse">
<ul class="nav" id="side-menu">
<li>
<i class="fa fa-calendar fa-fw"></i> Manage Events<span class="fa arrow"></span>
<ul class="nav nav-second-level collapse">
<li>
<a [routerLink]="['ManageEvents/LoremIpsum']">Lorem Ipsum</a>
</li>
<li>
<a [routerLink]="['ManageEvents/LoremIpsum']>Lorem Ipsum</a>
</li>
</ul>
<!-- /.nav-second-level -->
</li>
</ul>
</div>
export const routes: Routes = [
{ path: 'ManageEvents/LoremIpsum', component: ManageEventsLoremIpsum }
];
This works for me!!
link
hope this helps link also working by this way
For me I used the routerLink and set it to empty:
<a [routerLink]="" (click)="onClickPage()">Click me</a>
try to remove href, setting cursor: pointer with css and handle click on th a element like <a (click)=yourFunction()></a>. it should work ;)
Just simply use <a href>Lorem Ipsum</a>.
I had a situation after parent received events from child component, it redirect to homepage. I solved the problem in parent
receiveMessage($event) { //do something this.router.navigateByUrl('/parent-route'); }
even the parent route are supposed to accept parameters.
For me it javascript:void(0); works. Angular 14
Last Page // HTML file

HTML Jquery .toggle not toggling back

<div class="row">
<div class="col one-whole">
<nav class="top-nav">
<ul>
<li>Home</li>
<li>About</li>
<li>Central Plumping</li>
<li>Roof</li>
<li>Drainage</li>
<li>Gallery</li>
<li>Contact</li>
<img src="img/title.png">
</ul>
</nav>
<nav class="burger-nav">
<ul>
<li><i class="fa fa-bars x3" aria-hidden="true"></i></li>
<li><img src="img/title.png"></li>
</ul>
</nav>
</div>
</div>
<div class="burger">
<div class="row menu">
<div class="col one-whole">
<ul>
<li>Home<i class="fa fa-times x3" aria-hidden="true"></i></li>
<li>About</li>
<li>Central Plumping</li>
<li>Roof</li>
<li>Drainage</li>
<li>Gallery</li>
<li>Contact</li>
</ul>
</div>
</div>
</div>
Hello all, currently trying to learn basic JQuery. I have managed to create a simple navigation bar, with responsive burger menu that hides and shows each navigation bar based on screen size. I then created a burger div that is 100% screen size fixed when displayed but is currently set it display:none. Now i have got my toggle working to display it, but when i try to close the menu bar, it doesn't seem to toggle back. Any help would be great thankyou.
My Jquery script is as follows:
<script>
$(document).ready(function(){
$("#toggleburger").click(function(){
$(".menu").toggle();
});
});
</script>
i guess your problem is that you're using an anchor tag with empty href attribute.
try chaging in
<i class="fa fa-times x3" aria-hidden="true"></i>
see example in this FIDDLE
I'm getting directed off when I click the element you're trying to tie the click event to.
Here's a working fiddle: https://jsfiddle.net/p85kazv0/
I've simply prevented the a element you're using from its default action (which is of course to direct someone to another location, dictated by whats in the href=""):
$("#toggleburger").click(function(e){
e.preventDefault();
$(".menu").toggle();
});
Reasons for unexpected behaviour:
<a> has href set to some other page. If you have to implement the menu or buttons that are only for in page activity you should set it as href="#". Meaning do not redirect me anywhere just perform the event linked with this action, which in your case is toggling of another div.
While e.preventDefault() is a workaround, it is not recommended here as the link is sitting there doing nothing. It would suit more if say you had a form that would submit itself but you wanted to do some processing/sanitation before submitting, thereby overriding default action with your logic.
There are two elements with id=toggleburger. Keep your id unique on one html page. This can give you a lot of pain while debugging.
Here is a working fiddle, I have replaced the hamburger image with text "ToggleBurger".
Set the href attribute of the <a> element equals to #:
<li><a href="#" id="toggleburger">

Bootstrap animations not working

I'm quite new to Angular/Bootstrap and I downloaded a template that I'm trying to modify and add features to go about learning.
I'm trying to have a collapsible sub-menu as such
<ul class="nav nav-sidebar">
<li ng-class="{active: $state.includes('overview')}"><a ui-sref="overview">Overview <span class="sr-only">(current)</span></a></li>
<li>Products</li> <!-- a click on this should expand the div below... -->
<div class="collapse" id="products">
<ul>
<div ng-repeat="itemType in itemTypes">
<li>{{itemType.Description}}</li>
</div>
</ul>
</div>
</ul>
My attempt is from this example.
Instead of a button, I want the animation to be triggered by a click on an anchor.
I read a version of Bootstrap had problems with animation so I upgraded to bootstrap#3.3.6
Any ideas ?
Thanks.
EDIT: By not working I mean, nothing is happening. I can use an ng-show directive, but there's no smooth animation.
As the docs says,
You can use a link with the href attribute, or a button with the data-target attribute. In both cases, the data-toggle="collapse" is required.
Change the anchor tag to use the href attribute instead of data-target.
Products
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<ul class="nav nav-sidebar">
<li ng-class="{active: $state.includes('overview')}"><a ui-sref="overview">Overview <span class="sr-only">(current)</span></a></li>
<li>Products</li> <!-- a click on this should expand the div below... -->
<div class="collapse" id="products">
<ul>
<div ng-repeat="itemType in itemTypes">
<li>{{itemType.Description}}</li>
</div>
</ul>
</div>
</ul>
I ended up adding jQuery and bootstrap to my 'serve' gulp task and this works, without changing the view's code at all.

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.

Categories

Resources