awesome-vue shows one icon, but not the other, in a terribly similar situation on the same page - vue.js

I have a navbar, with three links "Login", "Register", "Languages". Here's my vue-awesome setup:
import Icon from 'vue-awesome/components/Icon'
import 'vue-awesome/icons'
import Modal from '#/components/Modal.vue'
import Sidebar from '#/components/Sidebar.vue'
import Uploads from '#/components/Uploads.vue'
import CartDropdown from '#/components/CartDropdown.vue'
import Login from '#/lib/auth/components/Login.vue'
import Register from '#/lib/auth/components/Register.vue'
export default{
name: 'app',
components: {
Icon,
Modal,
Sidebar,
Uploads,
CartDropdown,
Register,
Login
},
And here I am adding the icons. Note that these are the same icons, but this is just for test. The first icon will be changed to sign-in.
{{$t('account.login')}}
<Icon name="language"/>
{{$t('account.register')}}
</li>
<li class="nav-item nav-link dropdown" #click="dropdownOpen = false" :class="{'show': langDropdown}">
<a class="nav-link dropdown-toggle user-nav" #click="langDropdown = !langDropdown" style="color: white; cursor: pointer;">{{selectedLanguage}}</a>
<Icon name="language"/>
<div #click="langDropdown = !langDropdown" class="navbar-toggler">
<icon name="globe" scale="2" class="icon"></icon>
</div>
The first icon doesn't work. Look:
What could be the issue?

Related

bootstrap 4 in Angular 2 dropdown not working

I have followed the following to install bootstrap 4 into my Angular 2 project: Accepted Answer, following the first 1,2,3 and 4 steps
However when I add the following HTML to my header component:
<nav class="navbar-dark bg-inverse">
<div class="container">
<ul class="nav navbar-nav float-xs-right">
<li class="nav-item dropdown">
SomeEmail#hotmail.com
<div class="dropdown-menu" aria-labelledby="nav-dropdown">
Sign Out
</div>
</li>
</ul>
</div>
As you can see its a dropdown basically, when I click on the dropdown the page refreshes, instead it doesn't display the 'sign out' option.
This is my angular-cli.json styles section:
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
],
And inside my Angular 2 module:
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
I then import NgbModule into the imports section.
I've clearly missed something, can someone shed any light into what it maybe exactly?
Variation on #VictorLuchian for newest BS4 beta, it seems 'show' class need to be added on the dropdown-menu as well.
This version include a click outside close instead of mouseout
import { Directive,HostListener,HostBinding, ElementRef } from '#angular/core';
#Directive({
selector: '[customdropdown]'
})
export class CustomDropdownDirective {
private isOpen: boolean =false;
constructor(private _el: ElementRef) {
}
#HostBinding('class.show') get opened() {
return this.isOpen;
}
#HostListener('click') open() {
this.isOpen = true;
this._el.nativeElement.querySelector('.dropdown-menu').classList.add('show')
}
#HostListener('document:click', ['$event.target']) close (targetElement) {
let inside: boolean = this._el.nativeElement.contains(targetElement);
if(!inside) {
this.isOpen = false;
this._el.nativeElement.querySelector('.dropdown-menu').classList.remove('show')
}
}
}
Please install ng-bootstrap from this link Getting Started with the following command:
npm `install --save #ng-bootstrap/ng-bootstrap`
Import it on app.module.ts like
import `{NgbModule} from '#ng-bootstrap/ng-bootstrap';`
Import on
imports:[
NgbModule.forRoot(),
]
Add ngbDropdown on dropdown
Add ngbDropdownToggle on dropdown Toggle DOM
Add ngbDropdownMenu on dropdown menu DOM
<li ngbDropdown class="nav-item dropdown" >
<a ngbDropdownToggle class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Manage
</a>
<div ngbDropdownMenu class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Save Data</a>
<a class="dropdown-item" href="#">Fetch Data</a>
</div>
</li>
</ul>
Some plugins and CSS components depend on other plugins. If you include plugins individually,
make sure to check for these dependencies in the docs. Also note that all plugins depend on
jQuery (this means jQuery must be included before the plugin files).
In .angular-cli.json add the following lines to the scripts section:
# version 4.x
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/bootstrap/dist/js/bootstrap.js",
]
Checkout definition here
Like Andrien's said, you can simplify the code like this.
constructor(private _el: ElementRef) { }
#HostBinding('class.show') isOpen = false;
#HostListener('click') toogleOpen() {
this.isOpen = !this.isOpen;
this._el.nativeElement.querySelector('.dropdown-menu').classList.toggle('show')
}
You will need to add a dropdown directive in order for this to work.
The directive looks like this:
import { Directive,HostListener,HostBinding } from '#angular/core';
#Directive({
selector: '[appcustomdropdown]'
})
export class CustomdropdownDirective {
constructor() { }
#HostBinding('class.open') get opened()
{
return this.isOpen;
}
#HostListener('click') open()
{
this.isOpen=true;
}
#HostListener('mouseleave') close()
{
this.isOpen=false;
}
private isOpen=false;
}
Then, you will add the attribute like so:
<li class="nav-item dropdown" appcustomdropdown >
Example Code StackBliz Link
Firstly Bootstrap 3 & 4 Drop down active state classes are different
In Boostrap 3 : In dropdown open state; .dropdown-toggle parent element is added 'open' CSS class
Where as in Boostrap 4 make use of "show" CSS class
In drop down open state. Here .dropdown-toggle element's parent element and next sibling element with CSS class .dropdown-menu are added "show" css Class
Hence to make boostrap 4 dropdown working with angular 4 we will create new angular directive class and add it to boostrap dropdown in angular template
Step 1 - Crate new angular directive in ng-boostrap-dropdown.directive.ts
import { Directive, HostListener, ElementRef } from '#angular/core';
#Directive({
selector: '[appNgBoostrapDropdown]'
})
export class NgBoostrapDropdownDirective {
private isShow: boolean = false;
private dropdownParentEl = this.elementRef.nativeElement.closest('.dropdown');
constructor(private elementRef: ElementRef) { }
#HostListener('click') open() {
this.isShow = !this.isShow;
if (this.isShow) {
this.dropdownParentEl.classList.add('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
} else {
this.dropdownParentEl.classList.remove('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
}
}
#HostListener('document:click', ['$event'])
clickout(event) {
if (this.elementRef.nativeElement.contains(event.target) && this.isShow) {
this.dropdownParentEl.classList.add('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
} else {
this.dropdownParentEl.classList.remove('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
this.isShow = false;
}
}
}
Step 2 : Import this Directive in app.module.ts
import { NgBoostrapDropdownDirective } from './directives/ng-boostrap-dropdown.directive';
#NgModule({
declarations: [ AppComponent, NgBoostrapDropdownDirective ],
})
Step 3 : Apply directive in Template using appNgBoostrapDropdown
NAVIGATION :
<li class="nav-item dropdown" >
<a class="nav-link dropdown-toggle" appNgBoostrapDropdown href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
BUTTON DROPDOWN :
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" appNgBoostrapDropdown type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</div>
Example Code StackBliz Link
Inspired by Rahul Talar's first version(Step 1 - Crate new angular directive in ng-boostrap-dropdown.directive.ts), i've made some similar using Rendere2
import { Directive, HostListener, ElementRef, Renderer2, OnInit } from '#angular/core';
#Directive({
selector: '[appDropdown]'
})
export class AppDropdownDirective implements OnInit {
private isShow = false;
private classShow = 'show';
private parentNode: HTMLElement;
private siblingNode: HTMLElement;
constructor(private elementRef: ElementRef, private renderer: Renderer2) {}
ngOnInit() {
this.parentNode = this.renderer.parentNode(this.elementRef.nativeElement);
this.siblingNode = this.renderer.nextSibling(this.elementRef.nativeElement);
}
#HostListener('click') open() {
this.isShow = !this.isShow;
if (this.isShow) {
this.addClass();
} else {
this.removeClass();
}
}
#HostListener('document:click', ['$event']) clickout(event) {
if (this.elementRef.nativeElement !== event.target && this.isShow) {
this.removeClass();
this.isShow = false;
}
}
private addClass() {
this.renderer.addClass(this.parentNode, this.classShow);
this.renderer.addClass(this.siblingNode, this.classShow);
}
private removeClass() {
this.renderer.removeClass(this.parentNode, this.classShow);
this.renderer.removeClass(this.siblingNode, this.classShow);
}
}
The CSS needs to be in the <head></head> tag.
I quote from bootstrap
Copy-paste the stylesheet <link> into your <head> before all other
stylesheets to load our CSS.
I continue quoting
Add our JavaScript plugins, jQuery, and Tether near the end of your
pages, right before the closing tag. Be sure to place jQuery
and Tether first, as our code depends on them.
Make sure that you have in this way
here is the link to bootstrap documentation where i get this quotes
https://v4-alpha.getbootstrap.com/getting-started/introduction/
and check this answer in the post that you share the link
https://stackoverflow.com/a/39809447/3284537
Somebody has created a new version of the template library specifically design for Angular 2+. According to the website, it was developed by ng-team, although the link it gives gets a 404 response. It does work, though, and I have used it in multiple places throughout my current project. You'll just have to pull in the library with npm. All of the instructions are on this website:
http://valor-software.com/ngx-bootstrap/#/
That page shows you all of the install and usage instructions you need to get started. I hope this helps!
i have used a different approach for getting drop down on collpased navbar.
STEP 1
Add click event on navbar toggle button
<button type="button" class="navbar-toggle" data-toggle="collapse" (click)="OnClik()" data-target="#myNavbar"
Html
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" (click)="OnClik()" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled}" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Page 1 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Page 1-1</li>
<li>Page 1-2</li>
<li>Page 1-3</li>
</ul>
</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><span class="glyphicon glyphicon-user"></span> Sign Up</li>
<li><span class="glyphicon glyphicon-log-in"></span> Login</li>
</ul>
</div>
</div>
</nav>
Step2:
implement the function inside
Navbar component.ts (Above navbar html template is used inside navbar component)
import { Component} from '#angular/core';
export class HeaderComponent {
buttontoggled:boolean:false;
OnClik(){
this.buttontoggled=!this.buttontoggled;
}
Step 3
based on the navbar toggle button click add class show(bootstrap 4) or open for previous bootstrap versions.
we can use ngClass Directive for this
<div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled}" id="myNavbar">
Work flow
Navbar toggle button will be visible when navbar geting collapsed for smaller resolutions
by handling the button click event we can set one flag to check if the button clicked or not
Based on this flag we will
we will bind the css class show to navabr div using ngClass directive
I am using theme which is not build for Angular and it contain classic bootstrap, I had same issue and fixed by modifying bootstrap.js file.
Issue is that bootstrap listen events with $(document).on and problem is in "document" part.
In my bootstrap file it is line 18001
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
event.preventDefault();
event.stopPropagation();
Dropdown._jQueryInterface.call($(this), 'toggle');
}).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
e.stopPropagation();
});
Change $(document) to $("body") and it will work.
$("body").on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
event.preventDefault();
event.stopPropagation();
Dropdown._jQueryInterface.call($(this), 'toggle');
}).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
e.stopPropagation();
});
navbar.component.html
<li class="nav-item dropdown show" appDropdown>
<a class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Categories
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a routerLink="yourLInk1" class="dropdown-item">Item 1</a>
<a routerLink="yourLInk2" class="dropdown-item">Item 2</a>
<a routerLink="yourLInk3" class="dropdown-item">Item 3</a>
<a routerLink="yourLInk4" class="dropdown-item">Item 4</a>
<div class="dropdown-divider"></div>
<a routerLink="yourLInk5" class="dropdown-item">Item 5</a>
</div>
</li>
dropdown.directive.ts
import { Directive, HostBinding, HostListener, ElementRef } from '#angular/core';
#Directive({
selector: '[appDropdown]'
})
export class DropdownDirective {
constructor(private elementRef: ElementRef) { }
private dropdownParentEl = this.elementRef.nativeElement.closest('.dropdown');
#HostListener('mouseenter') toggleOpen(){
this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
}
#HostListener('mouseleave') toggleClose(){
this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
}
#HostListener('click') toogleOpen() {
this.dropdownParentEl.querySelector(".dropdown-menu").classList.toggle('show');
}
}
import { Directive, HostListener, HostBinding, ElementRef } from '#angular/core';
#Directive({
selector: '[appDropdown]'
})
export class DropdownDirective {
constructor(private _el: ElementRef) {
}
#HostBinding('class.show') isOpen = false;
#HostListener('click') toggleOpen(){
this.isOpen=!this.isOpen;
if(this.isOpen){
this._el.nativeElement.querySelector('.dropdown-menu').classList.add('show');
}
else{
this._el.nativeElement.querySelector('.dropdown-menu').classList.remove('show');
}
}
}

Router-view not load second component

The redirect to new link and styles css works, but no method or event inicialize on the new component.
The component navbar keep going perfectly and the inspector not display no error. If reload page, all works again. Apologize my english
main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Routes from './routes'
import App from './componentes/App.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes: Routes,
// mode: 'history'`Texto preformateado`
});
const app = new Vue({
router,
el: '#app',
render: h => h(App)
})
app.vue
<template>
<div id="app">
<encabezado></encabezado>
<!-- <keep-alive> -->
<router-view></router-view>
<!-- </keep-alive> -->
</div>
</template>
<script>
import encabezado from './encabezado.vue'
export default {
name: 'app',
components: {
encabezado
},
}
</script>
route.js
import Financiero from './componentes/vistas/financiero.vue';
import Principal from './componentes/principal/principal.vue';
export default [
{
path: '/financiero',
component: Financiero,
name: 'Financiero'
},
{ path: '/principal', component: Principal, name: 'principal' },
]
component
<template>
<div :class="{dvContainer:movil}">
<div v-if="movil" class="fixed-action-btn">
<a class="btn-floating btn-large sidenav-trigger pulse waves-effect waves-light purple darken-3" href="#" data-target="slide-out">
<i class="large material-icons">chat</i>
</a>
</div>
<ul id="slide-out" class="collapsible" :class="{sidenav: movil, enCelularSide: movil, menuLateral: !movil }" style="padding-bottom: 30px !important;">
<li class="active">
<div class="collapsible-header" ><i class="material-icons">filter_drama</i>Analisar proyecto</div>
<div class="collapsible-body cuerpoItemColapse">
<mapa></mapa>
</div>
</li>
</ul>
</div>
</template>
<script>
import evaluacion from '../navegacion/evaluacion.vue'
import mapa from '../navegacion/mapa.vue'
import resumen from '../navegacion/resumen.vue'
export default{
import Financiero from '#/componentes/vistas/financiero.vue';
import Principal from ' #/componentes/principal/principal.vue';
Example here

Vue js, footer not displaying

I have installed vue cli, when i try to show my navbar(component) it shows but when i try to show my footer(component)it shows.
When i show other cms pages the navbar and footer are together the text is not displaying between...
Find the image, Output:
This is my navbar where it is a component under component folder
<template>
<div>
<ul class="navbar-nav">
<li class="nav-item">
<router-link to="/" class="nav-link">Home</router-link>
</li>
<li class="nav-item">
<router-link to="/contacts" class="nav-link">Contacts Us</router-link>
</li>
<li class="nav-item">
<router-link to="/login" class="nav-link">Login</router-link>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Navbar'
}
</script>
This is my HomePage where it is a component under component folder
<template>
<div>
test
</div>
</template>
<script>
export default {
name: 'HomePage'
}
</script>
This is App.vue Where it is inside the Src/ Folder
<template>
<div id="app">
<app-header></app-header>
<app-footer></app-footer>
<router-view></router-view>
</div>
</template>
<script>
import Navbar from '#/components/Navbar'
import Footer from '#/components/Footer'
export default {
name: 'App',
components: {
'app-header': Navbar,
'app-footer' : Footer
}
}
</script>
This the Footer Component
<template>
<div class="hello">
<footer class="text-muted">
<div class="container">
<p class="float-right">
Back to top
</p>
<p>Album example is © Bootstrap, but please download and customize it for yourself!</p>
<p>New to Bootstrap? Visit the homepage or read our getting started guide.</p>
</div>
</footer>
</div>
</template>
<script>
export default {
name: 'Footer',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
In your App.vue template you have the order of the elements wrong.
Move the <app-footer> below rhe <router-view>:
<template>
<div id="app">
<app-header></app-header>
<router-view></router-view>
<app-footer></app-footer>
</div>
</template

Vue on click inside component

I have component like this:
<template>
<!-- Content for section1 -->
<div id="section1" class="container-fluid home-div">
<h1 class="text-center">Create Your own Website!</h1>
<p>Welcome to website builder a place where magic comes true. This website will allow you to create your own website, host it on our webserver and change the content or add content as you go!
</p>
<button v-on:click="next" class="btn btn-primary"></button>
</div>
</template>
and my js:
import Vue from 'vue';
import VueRouter from 'vue-router';
import Section1 from '../vue/components/homepage.vue';
import Section2 from '../vue/components/section2.vue';
const routes = [
{ path: '/', component: Section1 },
{ path: '/about', components: Section2, },
];
Vue.use(VueRouter);
const router = new VueRouter({
routes,
});
new Vue({
el: '#homepage',
router,
});
html:
<div id="homepage">
<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="{{ url('template') }}">Website Builder</a>
</div>
<div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li><router-link to="/">Create</router-link></li>
<li><router-link to="about">How</router-link></li>
</ul>
</div>
</div>
</nav>
<router-view></router-view>
</div>
So now when I click on the link nothing happens, it has a path of /#/ and /#/about respectively, and are being transformed to tags, what is wrong with my current code? Should the navigation be as a template maybe or within the template?
Your component has local scope, meaning it will try and call a next method on the component itself and not on your root instance where you have actually defined your method.
Depending on your situation and what you want you need to either move the method inside your homepage or section2 component.
Or you need to notify your root Vue instance whenever the click event has been called in a child component. There are many communication patterns possible with Vue.js for child-parent communication an easy one would be this:
https://vuejs.org/v2/guide/components.html#Custom-Events
On click you would emit an event from your child component and use a v-on to listen to the event in your root instance.
But by the looks of it you want to implementing routing with one component per page:
https://vuejs.org/v2/guide/routing.html
in your 'new App', when you set 'el' property it should refer to an ID of an html element (the root element).
your html should be like this instead:
<div id="homepage">
<homepage v-if="seen"></homepage>
<section2 v-else></section2>
</div>

vue, animation on dynamic component not triggering?

I have a page like this:
<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>
<keep-alive>
<component :is="currentView" transition="fade" transition-mode="out-in"></component>
</keep-alive>
</div>
js:
import Vue from 'vue';
import VueRouter from 'vue-router';
import Create from '../components/homepage/create.vue';
import How from '../components/homepage/how.vue';
import About from '../components/homepage/about.vue';
import Youtube from '../components/homepage/youtube.vue';
import Navigation from '../components/navigation.vue';
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'
}
})
sass:
.fade-transition {
transition: opacity 0.2s ease;
}
.fade-enter,
.fade-leave {
opacity: 0;
}
and that code apparently should make the components to have animations when they switch. They do switch however without the animation, why is this happening am I missing something?
<keep-alive>
<transition name="fade" mode="out-in">
<component :is="currentView"></component>
</transition>
</keep-alive>
Please see if this works. Also, check that the CSS in included.

Resources