Angular Second Layer Navigation dispear after click on link - lazy-loading

I have two layer navbar and the app is using Lazy loading, but every time I clcik on Team Management button the component is working but the Admin Panel navbar is dispear:
Here is my admin-routing.module.ts:
const routes: Routes = [
{ path: '', component: AdminComponent },
{
path: 'team',
loadChildren: () => import('./team/team.module').then((m) => m.TeamModule),
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AdminRoutingModule {}
Here is HTML for the admin.component.html:
<div>
<nav class="navbar navbar-expand-sm navbar-light bg-light mb-3">
<div class="container">
<a class="navbar-brand" href="#">Admin Panel</a>
<button
class="navbar-toggler"
data-toggle="collapse"
data-target="#team-navbarNav"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="team-navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/team" routerLink="team"
>Team Management</a
>
</li>
<li class="nav-item">
<a class="nav-link" href="">Others</a>
</li>
</ul>
</div>
</div>
</nav>
</div>
<router-outlet></router-outlet>
Here is the result of after click on Team Management button:
As you can see the second navbar is gone, I do set up
<router-outlet></router-outlet>
in admin.component.html, but it feels like never works..
team is the sub component of admin.
admin-routing. module.ts:
Here is my Github repo:
https://github.com/qwe3804132/BusyQA-CRM/tree/main/CRMFrontEnd
any suggestions?

Related

How to add smooth scroll on a navigation link using Vue js between different pages?

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?

How to change a css style each page in vue-cli

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>

passing data between components not working

i have been struggling for hours on this one, i am a newbie in vuejs basically i have a modal based on tabs and i want to show some data into the modal-content of my modal, the place where click event of open modal occurs is in another vue file and the place where i want to populate the modal content is in another vue,here's my code
main blade file
#section('main-content')
<div class="full-page-taps">
<div class="page-head p-4 mb-lg-4">
<h3>Directory</h3>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<employee-search :inplaceholder="'Search Techs'"></employee-search>
</div>
</div>
<employee-card-section :indata="{{ $employees }}"></employee-card-section>
</div>
<modal name="employee-modal"
:width="'94%'"
:height="'94%'"
>
<employee-modal-content v-on:custom="customHandler"></employee-modal-content>
</modal>
</div>
#endsection
employeecard.vue
methods: {
openEmployee() {
// if(this.viewEmployees) {
this.$modal.show('employee-modal');
// this.$emit("passdata",this.employee.id);
this.$emit('chalja');
// this.$emit('custom', 'somedata');
// this.$eventHub.$emit("passdata");
// })
// }
}
},
employee-modal-content.vue
<template>
<div>
<div class="secondary-header no-margin">
<h2>UNEEB</h2>
</div>
<div class="customer-panel">
<input type="hidden" id="eid" value="" />
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#profile" role="tab">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#bio" role="tab">Bio</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#audit" role="tab">Audit</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="profile" role="tabpanel">
</div>
<div class="tab-pane" id="bio" role="tabpanel">
</div>
<div class="tab-pane" id="audit" role="tabpanel">
</div>
</div>
</div>
</div>
</template>
<script>
export default {
methods:{
customHandler : function(e){
console.log(e);
console.log("works");
}
},
mounted(){
this.$eventHub.$on('chalja', ()=> {
alert("agya");
});
}
}
</script>
i basically want to pass in the ID from employeecard.vue to directory-modal-content.vue. i have tried many solutions but none worked for me, any help?
Should be so:
1.Pass your id as dynamic prop of component
<employee-modal-content :id="employee.id"></employee-modal-content>
2.In your child component u have to use props to receive the id variable
<template>
<div>
{{ id }}
</div>
</template>
<script>
export default {
props: ['id'],
methods:{
//...
}
}
</script>

Vue run function from child component?

I have html like this:
<div id="nav">
<homenav v-on:navigation="switchNav(this.nav)" v-if="nav == 'homeNav'"></homenav>
<mainav v-if="nav == 'mainNav'"></mainav>
</div>
My Js is like this:
Vue.component('homenav', Navigation);
Vue.component('mainav', Navigation2);
new Vue({
el: '#nav',
data: {
nav: 'homeNav'
},
methods: {
switchNav: function (test) {
console.log(test);
console.log(this.nav);
}
}
});
Part of homenav component to show what I want to do:
<template>
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="">Website Builder</a>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav nav-fill w-100">
<li class="nav-item">
<a class="nav-link" href="/#/">Create</a>
</li>
<li class="nav-item">
<a v-on:click="navData" class="nav-link" href="/#/how">How</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/#/about">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/#/youtube">Videos</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/#/login">Go to main site</a>
</li>
</ul>
</div>
</nav>
</template>
<script>
export default {
data() {
return {
nav: ''
}
},
methods: {
navData () {
this.nav = 'mainNav';
this.$emit('navigation');
console.log(this.nav);
}
}
}
So what I am trying to accomplish here is a dynamic switch in navigation, for example if user click on Go to main site link the nav would change from homenav to mainav dynamically. However, I don't know how to accomplish it and my attempt is above. Help..
Edit so in my newest attempt I have managed so that it console log from child + parent function. it consoles homeNav and mainNav together. However I need to also pass the child this.nav to parent so parent can update it's this.nav? Because at the moment despite it outputting both, navigation doesn't change.
The best way to achieve that is using Vue Router.
But, if you want to do that without routing you should do it with Dynamic Components
<component is=""></component>
You can see an example here: https://jsfiddle.net/lucaskatayama/256Lo0xa/1/
There is an App, with a button to toggle a component inside <component></component>.
It simulates your switch, by changing the selected component.

Vue 2.x authentication links not hiding until page refresh

I am new to Vue and created a basic authentication application.
AuthService.js
module.exports = {
isLoggedIn: function() {
if (localStorage.getItem("authUser") != null) {
return true;
} else {
return false;
}
},
Logout: function() {
localStorage.removeItem("authUser");
},
}
App.vue
<template>
<div id="app" >
<top-progress ref="topProgress"></top-progress>
<div class="nav is-light is-fixed-top">
<div class="container">
<span class="nav-toggle" v-on:click="toggleNav" v-bind:class="{ 'is-active': isActive }">
<span></span>
<span></span>
<span></span>
</span>
<div class="nav-right nav-menu" v-bind:class="{ 'is-active': isActive }">
<router-link v-ripple to="/" class="nav-item r-item"><i class="fa fa-home"></i>Home</router-link>
<router-link v-ripple to="faq" class="nav-item r-item"><i class="fa fa-file"></i>Features</router-link>
<router-link v-ripple to="dashboard" class="nav-item r-item"><i class="fa fa-dashcube"></i>Dashboard</router-link>
<router-link v-ripple to="faq" class="nav-item r-item"><i class="fa fa-quora"></i>Faq</router-link>
<a class="nav-item r-item" v-if="LoggedIn"><i class="fa fa-sign-out" #click.prevent="Logout"></i>Logout</a>
<div class="nav-item" v-if="!LoggedIn">
<p class="control">
<router-link to="login" class="button is-primary is-outlined">
<span class="icon">
<i class="fa fa-download"></i>
</span>
<span> Join Now</span>
</router-link>
</p>
</div>
</div>
</div>
</div>
<br>
<router-view></router-view>
<footer class="footer is-secondary">
<div class="container">
<div class="columns">
<div class="column">
<p>And this right here is a spiffy footer, where you can put stuff.</p>
</div>
<div class="column has-text-right">
<a class="icon" href="#"><i class="fa fa-facebook"></i></a>
<a class="icon" href="#"><i class="fa fa-twitter"></i></a>
</div>
</div>
</div>
</footer>
</div>
</template>
<script>
import {isLoggedIn,Logout} from "./service"
import miniToastr from 'mini-toastr'
import topProgress from 'vue-top-progress'
export default {
name: 'app',
components:{topProgress},
data:function(){
return {
isActive:false,
LoggedIn:false,
}
},
created(){
this.LoggedIn=isLoggedIn();
},
mounted(){
miniToastr.init()
this.$refs.topProgress.start()
setTimeout(() => {
this.$refs.topProgress.done()
}, 2000)
},
methods:{
Logout:function(){
Logout();
this.$router.push("login");
},
}
}
</script>
<style lang="sass">
..//
</style>
After successful login, I am using this.$router.push("home") to navigate to home component but the Login/Logout button not hiding/showing until I refresh the page.
The problem you are having is the created: hook is only called when App.vue is first created. Since this component holders the router-view it is always there as you move around the app — it's never destroyed, so it never needs to be created again. As a result your this.LoggedIn is only updated when you first load the app (or as you discovered, hit refresh).
You need to find a different way to update this.LoggedIn. One obvious possibility it to set it in the logih/logout methods.
Logout:function(){
Logout();
this.LoggedIn = isLoggedIn(); // or simply this.LoggedIn = false
this.$router.push("login");
},
It looks like users will login in a different component, so you will need to send an event from the child component to App.vue and trigger a method on App.vue to set this.LoggedIn when users login.
There are probably other possibilities that will come to mind now that you see why it isn't working.