Using Font Awesome 5 with Bootstrap 3 Collapse Component -- change arrow icon on collapse? - vuejs2

I'm trying to use Font Awesome 5 with Bootstrap 4 for an accordion/collapse section in my VUEJS SPA.
How can I get the Font Awesome arrow icon to point DOWN when a collapseable element is clicked?
Paste bin link
<template>
<div>
<div class='card-header' data-toggle='collapse' href='#collapseZero'>
<a class='card-title'>Heading Title One</a>
<font-awesome-icon :icon='faAngleUp' class='float-right'></font-awesome-icon>
</div>
<div id='collapseOne' class='card-body collapse' data-parent='#accordion'>
Content blah
</div>
</div>
</template>
<script>
import { faAngleUp, faAngleDown } from '#fortawesome/free-solid-svg-icons';
export default {
name: 'MyName'
computed: {
faAngleUp() {
return faAngleUp;
}
faAngleDOwn() {
return faAngleDown;
}
}
</script>

I don't know if you're looking for pure CSS approach or not, but just in case you do:
HTML
Simple accordin example. Pay attention the .collapsed class and <i class="fas"></i> on each card-header. You can change the content of the icon to display either arrow up or down based on whether card-header has the .collapsed class or not.
<div class="accordin">
<div class="card">
<div class="card-header collapsed" data-toggle="collapse"
data-target="#collapse-card-1">
Card 1
<span class="float-right">
<i class="fas"></i>
</span>
</div>
<div id="collapse-card-1" class="collapse" data-parent=".accordin">
<div class="card-body">
...
</div>
</div>
</div>
<div class="card">
<div class="card-header collapsed" data-toggle="collapse"
data-target="#collapse-card-2">
Card 2
<span class="float-right">
<i class="fas"></i>
</span>
</div>
<div id="collapse-card-2" class="collapse" data-parent=".accordin">
<div class="card-body">
...
</div>
</div>
</div>
<div class="card">
<div class="card-header collapsed" data-toggle="collapse"
data-target="#collapse-card-3">
Card 3
<span class="float-right">
<i class="fas"></i>
</span>
</div>
<div id="collapse-card-3" class="collapse" data-parent=".accordin">
<div class="card-body">
...
</div>
</div>
</div>
</div>
CSS
.card-header i.fas:before {
content: "\f107"; /* angle-down */
}
.card-header.collapsed i.fas:before {
content: "\f106"; /* angle-up */
}
Fiddle Demo
http://jsfiddle.net/davidliang2008/tgq2j0fh/

Related

Header component is not registered first time properly

I want to showing profile on click for logged in user, when i click to that, my profile page is rendered, but header content is not loaded properly, i checked in console, it shown me an error, did you register component properly. but if i refresh or reload page, header content is showing and console error also cleared that showing did you register component properly.
please help me where i mistaken.
header.vue
<template>
<div>
<div class="top-header">
<div class="container">
<div class="row">
<div class="col-md-6">
<p>Free shipping on all orders over $100</p>
</div>
<div class="col-md-6">
<div class="links" v-if="!this.$page.auth.user">
<inertia-link :href="route('login.page')"> Log in </inertia-link>
<InertiaLink :href="route('RegistrationForm')">Register</InertiaLink>
</div>
<div class="id-link" v-else>
<div class="profile-content" #click="OpenProfile"> <b-link href="#"> Welcome {{this.$page.auth.user.name}} </b-link> </div>
<div class="profile" v-if="expanded">
<b-img src="/images/profile.jpg" alt="image"></b-img>
<ul>
<li> <b-button variant="primary"> <inertia-link :href="route('User-Profile')" method="get"> Profile </inertia-link> </b-button> </li>
<li> <b-button variant="primary"> <inertia-link :href="route('logout')" method="post"> Logout </inertia-link> </b-button> </li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<header>
<div class="container">
<div class="row">
<div class="col-md-3">
<div class="logo">
<img src="images/logo.png">
</div>
</div>
<div class="col-md-9">
<div class="navbar">
<ul>
<li> <InertiaLink :href="route('home')">Home</InertiaLink> </li>
<li>Fruits</li>
<li>Vegetables</li>
<li>Single</li>
<li> <inertia-link :href="route('Contact-Us')">Contact US</inertia-link> </li>
</ul>
</div>
</div>
</div>
</div>
</header>
</div>
</template>
<script>
import Dropdown from '#/Shared/Dropdown'
import Icon from '#/Shared/Icon'
import Profile from './Profile.vue'
export default {
components: {Dropdown,Icon,Profile},
data() {
return{
expanded:false,
profile:false,
}
},
methods:{
OpenProfile(){
if(this.expanded==false){
this.expanded=true;
}
else{
this.expanded=false;
}
},
}
}
</script>
profile.vue
<template>
<div class="contact-page">
<div>
<header-content> </header-content>
</div>
<div class="table-content">
<b-container>
<div class="table-heading">
<h1>User Profile</h1>
</div>
<b-row>
<b-col cols="3">
<div class="login-id">
<div class="id-img">
<b-img src="images/profile.jpg"></b-img>
</div>
<h2>{{this.$page.auth.user.name}}</h2>
</div>
</b-col>
<b-col cols="9">
<div class="table-area">
<div class="out-layer">
<div class="head">
<h4>User Information</h4>
</div>
<b-link>
<div class="pencil">
<b-img src="images/edit.png"></b-img>
</div>
</b-link>
</div>
<div class="user">
<b-row no-gutters>
<b-col cols="6"><span class="text">NAME</span></b-col>
<b-col cols="6"><span class="link">{{this.$page.auth.user.name}}</span></b-col>
</b-row>
</div>
</div>
</b-col>
</b-row>
</b-container>
</div>
<div>
<footer-content> </footer-content>
</div>
</div>
</template>
<script>
import HeaderContent from './Header.vue';
import FooterContent from './Footer.vue';
export default {
components: {HeaderContent,FooterContent},
data(){
return {
}
},
}
</script>
I see an error in profile.vue, you don't have to use this inside <template>.
Are other components you call in profile.vue registered correctly?
Try to remove some portions of code to debug which tags throw the error.

Vue v-for is displaying more than one image on click

I am using vue to show a photo that is being pulled from a mysql DB.
I loop through the images but when I click to show, all the images show instead of just the one that I want to show (the single image button I clicked). How do I get only one image to show up at a time?
UPDATED
<div>
<div v-for="(image, index) in images" :key="index">
<div class="dropdown">
<div>
<a class="dropdown-item preview-link" #click="togglePreview(index)">
Preview
</a>
</div>
</div>
<div v-if="currentIndex === index" class="modal-dialog modal-dialog-centered modal-md" role="image" style="max-width: 700px;">
<div class="modal-content" style="overflow: hidden;">
<div class="modal-header">
<h5 class="modal-title">{{image.title}}</h5>
<button type="button" class="close modal-close-button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<img :src="'/storage/images/' + image.name + '.jpg'">
</div>
</div>
</div>
</div>
</div>
In my vue methods:
togglePreview(index) {
this.currentIndex = this.currentIndex === index?-1:index
},
Vue Data
data() {
return {
currentIndex: -1,
}
},

After obtaining more data the open panel is not correct

When loading the panels the first time and opening the panel in the third position. Everything is Ok.
When loading more elements, the panel that opens is not correct but it is still the one in the third position.
<div id="load-conversation">
<div class="row" style="margin-bottom: 10px;" v-show="referencesList.length >0">
<div class="col-md-12 text-center">
<button v-on:click="getEmails" class="btn btn-sm btn-blue">Cargar más</button>
</div>
</div>
<div class="panel panel-info" v-for="email in emails">
<!-- Head Panel-->
<div class="panel-heading" v-bind:class=" email.incoming ? 'white-inbox' : 'blue-reply'"
data-toggle="collapse" :href="`#collapse-new${email.id}`">
<!--Email Title-Button -->
<div class="row">
<div class="col-md-8">
<h5 v-if="email.incoming"><span class="fas fa-reply" aria-hidden="true"></span> ${email.sender_name}</h5>
<h5 v-else><span class="fas fa-share-square" aria-hidden="true"></span> ${email.sender_name}</h5>
</div>
</div>
</div>
<!--Body Panel-->
<div :id="`collapse-new${email.id}`" class="panel-collapse collapse">
<div class="panel-body">
<!--Email Head-->
<div class="container-fluid">
<div class="row">
<strong>SUBJECT: </strong><span class="text-info">${email.subject}</span></br>
<strong>FROM: </strong><span class="text-info">${email.sender_email}</span></br>
<strong>TO: </strong><span class="text-info"><span v-for="to in email.to">${to.email}, </span></span></br>
<strong>DATE: </strong><span class="text-info">${email.date}</span></br>
<strong v-if="email.cc.length > 0">CC: </strong><span class="text-info"><span v-for="cc in email.cc">${cc.email}, </span></span>
</div>
</div>
<br>
<!--Email Body-->
<div class="row container-fluid">
<div class="list-group-item"v-html="email.content_html">
</div>
<div>
<div class="bs-component">
<ul class="pager">
<li class="previous" data-toggle="collapse" :data-target="`#open-details-new${email.id}`">
<a href="javascript:void(0)">
<span class="glyphicon glyphicon-option-horizontal" aria-hidden="true"></span>
</a>
</li>
</ul>
</div>
<div :id="`open-details-new${email.id}`" class="collapse" v-html="email.complete_html">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The important thing is to see that the new elements are placed in the order of the old elements, that is, the order is reversed in the list. By only adding the elements without changing the order everything works correctly.
<script>
var loadMore = new Vue({
el: '#load-conversation',
delimiters: ['${', '}'],
data: {
limit : 3,
referencesList : [1,2,3,4,5],
emails : [],
showLoadBtn: true,
},
mounted() {
this.getEmails()
},
methods: {
getEmails(){
axios.post("get_more_emails", { references: this.getReferences() })
.then(response => {
//console.log(response.data);
this.emails = [ ...response.data, ...this.emails ]
}).catch(function (error) {
console.log('error', error)
});
},
getReferences(){
...
}
},
})
</script>

How to call VueJS component from another component

I'm new to VueJS, i have different pages which i organized in 'components'. Now, different pages have different layouts, for example, some pages will not include the header and the footer (which are also individual components).
This is the code for a component that is supposed to include the header
<template>
<Header />
<div class="container main-content">
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-8">
<h3 style="font-weight: bold;color: #000;">What will you like to do?</h3>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/dashboards" class="">
<i class="fa fa-user fa-4x"></i>
<p>View Dashboards</p>
</router-link>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/home" class="">
<i class="fa fa-cogs fa-4x"></i>
<p>Manage Settings</p>
</router-link>
</div>
</div>
</div>
<div class="col-lg-2"></div>
</div>
</div>
</template>
<script>
import Header from './Header.vue'
export default{
name: 'Loyalty',
components:{
'Header': Header
}
}
</script>
And this is my Header.vue
<template>
<div>
<div class="head">
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
<span class="pull-left" style="padding-left: 10px;">
<router-link to="/home" class="header-text page-link"><span class="fa fa-arrow-left"></span> Home</router-link>
</span>
</div>
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6 custom-hidden-sm">
<span class="pull-right" style="padding-right: 10px;">
<span class="header-text">Waje Loyalty</span>
</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
name: 'Header',
data(){
return{
page_name: this.$router.currentRoute.name
}
}
}
</script>
When i compile, i get the error:
- Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.
How can i solve this?
The issue is caused by the two root elements in your Loyalty.vue template: <Header /> and <div class="container main-content">.
VueJS component templates can contain one and only one root node.
To solve this, wrap the content of your Loyalty.vue template with a root div.
<template>
<!-- root div -->
<div>
<Header />
<div class="container main-content">
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-8">
<h3 style="font-weight: bold;color: #000;">What will you like to do?</h3>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/dashboards" class="">
<i class="fa fa-user fa-4x"></i>
<p>View Dashboards</p>
</router-link>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-6 dash-menu-item">
<div class="item-body">
<router-link to="/home" class="">
<i class="fa fa-cogs fa-4x"></i>
<p>Manage Settings</p>
</router-link>
</div>
</div>
</div>
<div class="col-lg-2"></div>
</div>
</div>
</div>
</template>

Template is not loading showing error [Vue warn]: Error compiling template:

I'm loading default listing using vuejs. When I browse page it show me following error
[Vue warn]: Error compiling template:
My html template is as bellow:
<template id="results-template">
<div class="results-wrap col-lg-8 col-md-8 ">
<h3>Results:</h3>
<div v-for="category in books" class="col-xs-3 col-sm-3 col-md-3 col-lg-3 pl-0">
<div class="single-vertical-book box">
<div class="book mt-20 text-center">
<img v-bind:src="{{category.URL}}" />
<div class="book-title-latest">
{{category.Title}}
</div>
<div class="book-author-lastest">
<a href="#" v-if="(category.Category == result.id)" v-for="(result,key) in genres" v-bind:key="result.id">
{{result.name}}
</a>
</div>
</div>
</div>
</div>
</div>
</template>
I'm using API to get data. When I inspected API response it's showing me response correctly but vuejs is not showing data in template. My VueJs code is as bellow:
Vue.component('Results',{
template : '#results-template',
props: ['books','genres']
})
and VueJs method is as bellow:
getBooks : function(){
var vm = this;
return $.get('apis.php?gtype=Books')
.done(function(d){
vm.books = JSON.parse(d);
});
}
My created on loading page code is as bellow:
created : function(){
var vm = this;
this.getBooks().done(function(){
........
});
}
Code for data :
data : {
books : []
}
Please help me what's wrong I'm doing?
Your are binding image incorrect way first of all make it correct. Replace your code:
<template id="results-template">
<div class="results-wrap col-lg-8 col-md-8 ">
<h3>Results:</h3>
<div v-for="category in books" class="col-xs-3 col-sm-3 col-md-3 col-lg-3 pl-0">
<div class="single-vertical-book box">
<div class="book mt-20 text-center">
<img :src="category.URL" />
<div class="book-title-latest">
{{category.Title}}
</div>
<div class="book-author-lastest">
<a href="#" v-if="(category.Category == result.id)" v-for="(result,key) in genres" v-bind:key="result.id">
{{result.name}}
</a>
</div>
</div>
</div>
</div>
</div>
</template>
with this code:
<template id="results-template">
<div class="results-wrap col-lg-8 col-md-8 ">
<h3>Results:</h3>
<div v-for="category in books" class="col-xs-3 col-sm-3 col-md-3 col-lg-3 pl-0">
<div class="single-vertical-book box">
<div class="book mt-20 text-center">
<img v-bind:src="{{category.URL}}" />
<div class="book-title-latest">
{{category.Title}}
</div>
<div class="book-author-lastest">
<a href="#" v-if="(category.Category == result.id)" v-for="(result,key) in genres" v-bind:key="result.id">
{{result.name}}
</a>
</div>
</div>
</div>
</div>
</div>
</template>
You've to use :src="category.URL" for image src binding not :src="{{category.URL}}"
Secondly in template call you are using "genres" have you initialized genres array or not? this may also cause for error. 1st check both of causes if problem not solved the check further.