After obtaining more data the open panel is not correct - vue.js

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>

Related

Build v-for src image

I'm doing a VUE 3 project and I have problems with v-for src image. I have the next code:
<template>
<div class="container">
<h2 class="title">Últimas incorporaciones</h2>
<div class="row">
<div
class="col-sm-6 col-md-4 col-lg-3"
v-for="pet in pets"
:key="pet.nombre"
>
<article class="card">
<div class="card-header">
<img
class="card-img-top"
v-bind:src="'../assets/pets/' + pet.imatge"
alt="Thor"
/>
</div>
<div class="card-body">
<div class="card-main">
<!-- <h3 class="card-title">{{ pet.nombre }}</h3> -->
<h3 class="card-title">{{ pet.nombre }}</h3>
<p class="card-text">{{ pet.ciudad }}</p>
</div>
<ul class="card-icons">
<li>
<img
class="card-icon"
src="../assets/icons/icon_cat.svg"
alt="Gato"
/>
</li>
<li>
<img
class="card-icon"
src="../assets/icons/icon_male.svg"
alt="Macho"
/>
</li>
</ul>
</div>
</article>
</div>
</div>
</div>
</template>
I want a v-for to show the images to each card. The pet.nombre and pet.ciudad is working good, but pet.image not.
My script is like this:
<script>
export default {
name: "PetList",
data() {
return {
pets: [
{
nombre: "Thor",
ciudad: "Barcelona",
imatge: "thor.png",
},
};
},
};
How can I show the images with this code?
You can use
<img class="card-img-top"
:src="`../assets/pets/${pet.image}`"
:alt="pet.nombre"
/>

How to use bootstrap carousel in Vue.js

I am quite new in vue and I am trying to make a bootstrap carousel using bootstrap.
<template>
<!-- Start Banner Hero -->
<div
id="webshop-hero-carousel"
class="carousel slide"
data-bs-ride="carousel"
>
<ol class="carousel-indicators">
<li
data-bs-target="#webshop-hero-carousel"
data-bs-slide-to="0"
class="active"
></li>
<li
data-bs-target="#webshop-hero-carousel"
data-bs-slide-to="1"
></li>
<li
data-bs-target="#webshop-hero-carousel"
data-bs-slide-to="2"
></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item" v-for="picture in pictures" :key="'picture-' + picture.id">
<div class="container">
<div class="row p-5">
<div class="col-lg-6 mb-0 d-flex align-items-center">
<div class="text-align-left align-self-center">
<!-- <h1 class="h1 text-success"><b>Jassa</b> eCommerce</h1> -->
<h3 class="h2">{{picture.text}}</h3>
</div>
</div>
</div>
</div>
</div>
</div>
<a
class="carousel-control-prev text-decoration-none w-auto ps-3"
href="#webshop-hero-carousel"
role="button"
data-bs-slide="prev"
>
<i class="fas fa-chevron-left"></i>
</a>
<a
class="carousel-control-next text-decoration-none w-auto pe-3"
href="#webshop-hero-carousel"
role="button"
data-bs-slide="next"
>
<i class="fas fa-chevron-right"></i>
</a>
</div>
<!-- End Banner Hero -->
</template>
<script>
export default {
data() {
return {
pictures: [
{
id: 1,
text: "Freibad",
},
{
id: 2,
text: "Hallenbad",
},
],
};
},
};
</script>
So here is my component but it doesnt work properly. I basically just want to show {{picture.text}} on each carousel but it doesnt display anything properly.
None of the carousel-item elements are active.
You can control the "active" item programmatically using Vue. Here is one example:
new Vue({
el:"#app",
data: () => ({
pictures: [ { id: 1, text: "Freibad" }, { id: 2, text: "Hallenbad" } ],
active: 0
}),
methods: {
setActive(index) {
let active = index;
if(index === this.pictures.length) active = 0;
else if(index === -1) active = this.pictures.length - 1;
this.active = active;
}
}
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div id="webshop-hero-carousel" class="carousel slide" data-bs-ride="carousel">
<ol class="carousel-indicators">
<li data-bs-target="#webshop-hero-carousel" data-bs-slide-to="0"></li>
<li data-bs-target="#webshop-hero-carousel" data-bs-slide-to="1"></li>
<li data-bs-target="#webshop-hero-carousel" data-bs-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div
v-for="(picture, index) in pictures"
:key="'picture-' + picture.id"
:class="{ 'carousel-item': true, 'active': index === active }"
>
<div class="container">
<div class="row p-5">
<div class="col-lg-6 mb-0 d-flex align-items-center">
<div class="text-align-left align-self-center">
<h3 class="h2">{{picture.text}}</h3>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="carousel-control-prev text-decoration-none w-auto ps-3" href="#webshop-hero-carousel" role="button" data-bs-slide="prev" #click="setActive(active-1)">
<i class="fas fa-chevron-left"></i>
</a>
<a class="carousel-control-next text-decoration-none w-auto pe-3" href="#webshop-hero-carousel" role="button" data-bs-slide="next" #click="setActive(active+1)">
<i class="fas fa-chevron-right"></i>
</a>
</div>
</div>
I would also suggest taking a look at bootstrap-vue.

Vue Js v-for using

I'm a vue.js beginner. I want to get data from app.js using v-for in html and show it in separate divs. I want to add an independent background and an independent text for each todo.
var example = new Vue({
el:"#example",
data: {
todos : [
{id:1 , name: "ŞEHİR MERKEZİ"},
{id:2 , name: "HÜDAİ KAPLICA"},
{id:3 , name: "AFYONKARAHİSAR"}
]
}
})
<div class="container" id="example">
<div class="row">
<div class="col-lg-6">
<div class="flip flip-vertical">
<div
class="front"
style="background: url(./static/images/sandıklı.jpg)">
<h1 class="text-shadow" >
<div class="hborder" v-for="todo in todos" :key="todo">
{{todo.name}}
</div>
</h1>
</div>
<div class="back">
<h4>ŞEHİR MERKEZİ GÜZERGAHINI ONAYLIYOR MUSUNUZ ?</h4>
<button type="button" class="btn btn-primary btn-lg">EVET</button>
<button type="button" class="btn btn-danger btn-lg">HAYIR</button>
</div>
</div>
</div>
</div>
</div>
<script src="./static/js/vue#2.js"></script>
<script src="./static/js/app.js"></script>
what you could do is add the background color and description to the todos object.
Also I made a little change in your data function.
var example = new Vue({
el:"#example",
data() {
return {
todos : [
{id:1 , name: "ŞEHİR MERKEZİ", bg: '#FFF', desc: 'desc1'},
{id:2 , name: "HÜDAİ KAPLICA", bg: '#ff0000', desc: 'desc2'},
{id:3 , name: "AFYONKARAHİSAR", bg: '#cecece', desc: 'desc3'}
]
}
}
})
<div class="container" id="example">
<div class="row">
<div class="col-lg-6">
<div class="flip flip-vertical">
<div
class="front"
style="background: url(./static/images/sandıklı.jpg)">
<h1 class="text-shadow" >
<div class="hborder" v-for="todo in todos" :key="todo" :style="background-color: todo.bg;">
{{todo.name}}
{{todo.desc}}
</div>
</h1>
</div>
<div class="back">
<h4>ŞEHİR MERKEZİ GÜZERGAHINI ONAYLIYOR MUSUNUZ ?</h4>
<button type="button" class="btn btn-primary btn-lg">EVET</button>
<button type="button" class="btn btn-danger btn-lg">HAYIR</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2"></script>

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,
}
},

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

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/