I followed the examples for setting up a nav-bar.html and a nav-bar.js in the Aurelia tutorial. Later, I wanted to add some functionality to the nav-bar.js VM but found that non of it's properties or methods are ever called.
I'm trying to use Aurelia Auth filtering on my top navigation, but even when omitting the auth functionality, nothing in top-nav-bar.js is ever called.
Code below:
top-nav-bar.js
import {bindable} from 'aurelia-framework';
import {inject} from 'aurelia-framework';
import {AuthService} from 'aurelia-auth';
//import {AuthFilterValueConverter} from './authFilter';
//import {Router} from 'aurelia-router';
#inject(AuthService )
export class TopNavBar {
_isAuthenticated=false;
#bindable router = null;
constructor(auth){
console.log('called nav bar constructor'); //NEVER CALLED
this.auth = auth;
}
//#computedFrom(this.auth)
get isAuthenticated(){
return this.auth.isAuthenticated(); //NEVER CALLED
}
}
top-nav-bar.html
<template>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<!-- <require from="paulvanbladel/aurelia-auth"></require> -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">
<i class="fa fa-home"></i>
<span>${router.title}</span>
</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li repeat.for="row of router.navigation | authFilter: isAuthenticated" class="${row.isActive ? 'active' : ''}">
<a data-toggle="collapse" data-target="#bs-example-navbar-collapse-1.in" href.bind="row.href">${row.title}</a>
</li>
</ul>
<ul if.bind="!isAuthenticated" class="nav navbar-nav navbar-right">
<li>Login</li>
</ul>
<ul if.bind="isAuthenticated" class="nav navbar-nav navbar-right">
<li>Profile</li>
<li>Logout</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="loader" if.bind="router.isNavigating">
<i class="fa fa-spinner fa-spin fa-2x"></i>
</li>
</ul>
</div>
</nav>
</template>
app.html
<template>
<require from="./top-nav-bar.html"></require>
<require from="bootstrap/css/bootstrap.css"></require>
<top-nav-bar router.bind="router"></top-nav-bar>
<div class="page-host">
<router-view></router-view>
</div>
</template>
If you have aurelia VM with js and html you need to import it to the view like (without *.html):
<require from="./top-nav-bar"></require>
Sometimes you do not have VM for the view, in that case you import just the html, like you do:
<require from="./top-nav-bar.html"></require>
Related
I have a HomeNavbar.vue component that has my Navbar links (I'm using Vue-Router).
HomeNavbar.vue:
<template>
<div>
<b-container fluid>
<b-row>
<b-col>
<nav class="navbar navbar-expand-lg">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<a class="navbar-brand logo" href="/"></a>
<ul class="navbar-nav ml-auto mt-2 mt-lg-0">
<li class="nav-item">
<router-link to="/" class="nav-link">Home</router-link>
</li>
<li class="nav-item">
<router-link to="/about" class="nav-link">About</router-link>
</li>
<li class="nav-item">
<ScrollToLink
href="#features"
class="nav-link"
>Features
</ScrollToLink>
</li>
<!-- <li class="nav-item">-->
<!-- <router-link to="/pricing" class="nav-link">Pricing</router-link>-->
<!-- </li>-->
<li class="nav-item">
<router-link to="/faqs" class="nav-link">FAQ's</router-link>
</li>
<li class="nav-item">
<router-link to="/contact" class="nav-link">Contact</router-link>
</li>
</ul>
</div>
<!-- <a class="nav-link" id="searchBox"><i class="fa fa-search"></i></a>-->
</nav>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import ScrollToLink from '../components/ScrollToLink';
export default {
name: "HomeNavbar",
components: {
ScrollToLink
}
}
</script>
As you can see I created a simple component for smooth scrolling called ScrollToLink.vue,
that is being used in the code above.
ScrollToLink.vue:
<template>
<a :href="href" #click.prevent="scroll">
<slot></slot>
</a>
</template>
<script>
export default {
name: "ScrollToLink",
props: ['href'],
methods: {
scroll() {
document.querySelector(this.href)
.scrollIntoView({ behavior: 'smooth' });
}
}
}
</script>
<style scoped>
</style>
The code works well when I'm on the Home page, which contains the features section with the id="#features" where it will scroll down to.
But if I click on About page, and then click on Features button it points to http://highrjobsadminlte.test/about#features, instead of this http://highrjobsadminlte.test/#features.
How can I get it to link back to /#features via the Home page?
This is App.vue File
<template>
<div id="app">
<main-header/>
<router-view/>
<main-footer/>
</div>
</template>
<script>
import MainHeader from './components/layouts/MainHeader'
import MainFooter from './components/layouts/MainFooter'
export default {
name: 'App',
components: {
'main-header': MainHeader,
'main-footer': MainFooter
}
}
</script>
Header.vue file is
<ul class="nav nav-pills" id="mainNav">
<li class="dropdown">
<a class="active" href="/">
Home
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test1">
test1
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test2">
test2
</a>
</li>
</ul>
I want to activate "active class" differently for each page.
I don't know how to do
if I click a "test2", active class have to maintain only with the tag with "test2"
How can I resolve this issue?
You can consider using Vue-router with active-class prop
<ul class="nav nav-pills" id="mainNav">
<router-link to="/" tag="li" class="dropdown" active-class="active">Home</router-link>
<router-link to="/test1" tag="li" class="dropdown-item dropdown-toggle" active-class="active">Test1</router-link>
<router-link to="/test2" tag="li" class="dropdown-item dropdown-toggle" active-class="active">Test2</router-link>
</ul>
Another naive solution is checking window.location.href, but it's not simple to cover all possible cases.
<ul class="nav nav-pills" id="mainNav">
<li class="dropdown">
<a class="active" href="/">
Home
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test1" :class="getClass('/test1')">
test1
</a>
</li>
<li>
<a class="dropdown-item dropdown-toggle" href="/test2" :class="getClass('/test2')">
test2
</a>
</li>
</ul>
<script>
export default {
methods: {
getClass(url) {
if (window.location.href.includes(url)) {
return "active"
}
return ""
}
}
}
</script>
I need to display the name of the user next to the logout option on my navbar. The way I did this was as follows:
<ul class="nav navbar-nav navbar-right">
<li>${userName}</li>
<li repeat.for="row of router.navigation" if.bind="row.settings.pos == 'right'" class="${ row.isActive ? 'link-active' : '' }">
<a href.bind="row.href" if.bind="!row.settings.nav">${ row.title }</a>
I thought that if I added another list item it in the nav navbar-nav it would display as all the other menu items do. Instead I got:
I have highlighted the name admin as, if I didnt it would be black on black. Its not receiving the correct styling as the other menu items have.
How do I render the admin list item so it displays like all the other list items?
EDIT
Looking at the question it was pointed out it was light on on background. It was late at night.
Yes I am using bootstrap version 3.
Here is the full html of the navbar view model:
<template>
<require from="./navmenu.css"></require>
<div class="main-nav">
<div class="navbar navbar-inverse">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#/home">Jobsledger</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-left">
<li repeat.for="row of routes" if.bind="row.settings.pos == 'left'" class="${ row.isActive ? 'link-active' : '' }">
<a href.bind="row.href" if.bind="!row.settings.nav">${ row.title }</a>
<a href.bind="row.href" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"
if.bind="row.settings.nav">
${row.title}
<span class="caret"></span>
</a>
<ul if.bind="row.settings.nav" class="dropdown-menu">
<li repeat.for="menu of row.settings.nav">
<a href.bind="menu.href">${menu.title}</a>
</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>${userName}</li> //HERE - THIS LINE DOESNT RENDER PROPERLY.
<li repeat.for="row of routes" if.bind="row.settings.pos == 'right'" class="${ row.isActive ? 'link-active' : '' }">
<a href.bind="row.href" if.bind="!row.settings.nav">${ row.title }</a>
<a href.bind="row.href" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"
if.bind="row.settings.nav">
${row.title}
<span class="caret"></span>
</a>
<ul if.bind="row.settings.nav" class="dropdown-menu">
<li repeat.for="menu of row.settings.nav">
<a href.bind="menu.href">${menu.title}</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
${userName}
</template>
Here is the typescript file behind it:
import { autoinject, bindable, bindingMode } from "aurelia-framework";
import { Router } from 'aurelia-router'
import { AuthService } from '../../auth/auth-service'
#autoinject
export class Navmenu {
public userName: string = 'anonymous';
private userRole = localStorage.getItem("user_role");
constructor(public authService: AuthService, public router: Router) {
this.userName = authService.getUserName();
}
get routes() {
return this.router.navigation.filter(r => r.settings.roles.indexOf(this.userRole) > -1);
}
}
I wanted to separate the left menu items with the right menu items so there are two sections. This is the right side where you have the user name and the option to logout. The display of the user name is done as a list item in the unordered list tag but before repeat for the right menu items.
I have navigation component like this:
<template>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="">Website Builder</a>
</div>
<div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li>
Create
</li>
<li>
How
</li>
<li>
About
</li>
<li>
Videos
</li>
</ul>
</div>
</div>
</nav>
</template>
and my js:
Vue.component('navigation', Navigation)
Vue.component('create', Create)
Vue.component('how', How)
Vue.component('about', About)
Vue.component('youtube', Youtube)
new Vue({
el: '#app',
data: {
currentView: 'create'
}
and html:
<div id="app">
<navigation></navigation>
<keep-alive>
<transition name="slide-fade" mode="out-in">
<component :is="currentView"></component>
</transition>
</keep-alive>
</div>
However when I click on navigation, it doesn't change therefore I am assuming it's not working properly. if I put navigation away from component and stick it in div id=app it works fine, why is this happening?
The .native modifier is not necessary on native elements - it can only be used on component elements. Remove it.
It seems you want to change data in the root component. Your current code changes data in the navigation component.
Two ways to do this:
1) The clean way:
In the navigation component, we emit an event with the new value to the parent:
<a href="#" #click="$emit('current-view', 'youtube')">
in the parent (here, the root) component, we receive the event and set the value:
<navigation #current-view="currentView = $event"></navigation>
2) The hacky way:
<a href="#" #click="$root.currentView='youtube'">
i put a collapsing navbar on my website.
the problem is that on mobile the navbar isnt collapsing
what is the problem?
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#main"><?php bloginfo ('name') ?></a>
</div>
<div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li>צור קשר</li>
<li>פרויקטים</li>
<li>שירותים</li>
<li>אודות</li>
<li>ראשי</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</nav>
In your code a <ul><li> added mistake.
Delete it.
Then your code is working properly.