Vue-strap Carousel: How to select specific slide - vue.js

I have managed to create a carousel (slider) using Vue-strap carousel component with the following code:
<carousel>
<slider v-for="(photo,index) in photos" :key="photo.sequenceID" >
<img v-bind:src="'https://../photo/' + photo.photoFilename " >
</slider>
</carousel>
Carousel is working. I also display thumbnails of images on the page. I want to select a specific slide when I click a thumbnail.
How can I display a specific slide in the carousle? Is there a function in Vue-strap carousle or slider that can displays specific slide if I pass the slide number?

The following code will display the slide fo the pictureID. It uses the indicatorClick() method of the carousel component. Here vm is the Vue object name.
vm.$children[0].indicatorClick(pictureID);

Late reply:
You can use the navigateTo prop as follows:
template.vue > tamplate/transition
<carousel
:perPage="1"
:navigateTo="carouselPosition"
:navigationEnabled="true"
:paginationEnabled="false">
<slide>
...
</slide>
</carousel>
carouselPosition should be stored as a prop:
template.vue > export default {}
data () {
return {
carouselPosition: null // OR 1
}
}
Include the following on your thumbnail element:
template.vue > component thumbnail
v-on:click=";(carouselPosition = index)"
In this case the index value would be generated in a loop:
template.vue > component loop
v-for="(thumbnail, index) in yourData"
NOTE: Nuxtjs used in this example but it should easy to modify these examples to your needs.

Using v-model
See Carousel documentation;
Programmatically control which slide is showing via v-model (which binds to the value prop). Note, that slides are indexed starting at 0
<b-carousel
id="image-carousel"
controls
indicators
img-width="1024"
img-height="480"
v-model="currentSlide"
>
Inside my slide I use a img for every thumbnail. Upon click currentSlide is changed to the index of the thumbnail.
<img
v-on:click="showImage(index)"
/>
store currentSlide in data:
data() {
return {
currentSlide: 0
}
}
method for changing currentSlide
showImage (index) {
this.currentSlide = index;
}
Vue will update the value prop of the slider if the v-model reference is changed.

use v-bind:data-slide-to="index"
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators"
v-for="(image, index) in images" v-bind:key="index"
v-bind:data-slide-to="index"
:class="{'active' : index===0}"></li>
</ol>

Related

Vue Bootstrap, how to interact with plus/minus icon on dynamic generated collapse content separately

I have a VueJS view that creates collapsed contents using Bootstrap Vue Collapse Component.
The data is dynamic and can contains hundreds of items, which is why you see in the code below it was created via a v-for loop in Vue.
<div class="inventory-detail" v-for="(partNumberGroup,index) in inventory" :key="index" >
<b-button block v-b-toggle="partNumberGroup.partNumber" v-bind:id="partNumberGroup.partNumber" variant="primary"
#click="(evt) =>{isActive = !isActive && evt.target.id == partNumberGroup.partNumber}">
<i v-bind:id="partNumberGroup.partNumber" class="float-right fa" :class="{ 'fa-plus': !isActive, 'fa-minus': isActive }"></i>
{{ partNumberGroup.partNumber }}
</b-button>
<div class="inventory-detail__card" v-for="item in partNumberGroup.items">
<b-collapse v-bind:id="partNumberGroup.partNumber" >
<b-card>
<!--Accordion/Collapse content -->
</b-card>
</b-collapse>
</div>
</div>
This works fairly well in that I can individually expand and collapse each content separately. However, the one issue I'm facing is each time I click the icon fa-minus (-) orfa-plus (+), all of them changed as per the images below.
Any tips on how I should implementing this? in my code I tried the dynamic CSS class switching but I still lack the ability to switch on specific element.
I feel like the solution to this is to somehow conditionally apply dynamic CSS class or somehow able to use the attribute 'aria-expanded'.
You can try something like this. Whenever somebody clicks on the icon, set its index as activeIndex (using the setActiveIndex method). Then you can set the class accordingly by comparing the activeIndex with current index
<i
#click="setActiveIndex(index)"
v-bind:id="partNumberGroup.partNumber"
class="float-right fa"
:class="{ 'fa-plus': !isActive(index), 'fa-minus': isActive(index) }">.
</i>
then in the script part:
...
data() {
return {
activeIndex: -1
}
},
methods: {
/* set active index on click */
setActiveIndex(index) {
this.activeIndex = index;
},
/* check if index is active or not */
isActive(index) {
return index === this.activeIndex;
}
}

How to turn off drag slide in Vue agile

I am using vue-agile, and I have to show videos and images in it. The images work fine but for videos, whenever I drag the pointer to move to a certain position in the player, the slider drags and moves to the next slider. Is there any way to stop the drag/swipe feature. Thanks.
https://www.npmjs.com/package/vue-agile
As a workaround, I first watch the mouse events on the clicked element (#mousedown, #mouseup)
On mousedown, I set the swipe-distance prop to a very high pixel value in the example below I used 1,000,000,000 (Default is 50).
Doc: https://github.com/lukaszflorczak/vue-agile
This worked for my case.
<template>
<agile :dots="false" :infinite="false" :center-mode="true"
:nav-buttons="false" :swipe-distance="noSweep ? 1000000000 : 50" >
<div v-for="(card, index) in cards" :key="index">
<div
#mousedown="noSweep=true"
#mouseup="noSweep=false"
>
Card content - example
</div>
</agile>
</template>
<script>
export default {
data() {
return {
noSweep: false,
cards:['A','B','C']
}
}
}
</script>

Vue: Why only the last object is only associated to every modal which is in for loop

This is the first time I am using modal component. Inside a for loop of an array of objects, I also added a modal component, "Add Item". The v:onClick="showSectionID" function in the SHOW button within the modal should just consolelog the id of the object who's associated modal was opened and click it's respective SHOW button. But instead it is giving the id of the last object wherever I click the SHOW button from any of associated modals.
Just to test, I removed the whole modal and only kept the SHOW button and in this case it gives me the correct id. I really cannot figure out what s is wrong in the modal and searched several sources in the internet to see a similar solution but couldn't find. See code:
<div v-for="(section) in allDataObject['Section']" :key="section['uuid']">
<h4>Section Name: {{ section["sectionName"] }}</h4>
<h4>Section Description: {{ section["sectionDescription"] }}</h4>
<template>
<div>
<b-button #click="modalShow = !modalShow">Add Item</b-button>
<b-modal v-model="modalShow">Fill form to add an item !
<button v-on:click="showSectionID (section['uuid'])">SHOW</button>
</b-modal>
</div>
</template>
</div>
In your code, you are creating a modal component for each section within the for loop.
I wouldn't be surprised if actually all your modals show up on the screen, but you see the last one because it's on top of all the other ones. But it also depends on how the modal is implemented.
I suggest you to move the modal template outside your for loop and change what you store in your component data so that you know which section to show in the modal.
Let's say your data() will look like this:
data() {
return {
modalVisible: false,
modalSectionUUID: null
}
}
Then you can create two methods to show and hide the modal:
methods: {
showModal(sectionUUID) {
this.modalVisible = true;
this.modalSectionUUID = sectionUUID;
},
hideModal() {
this.modalVisible = false;
this.modalSectionUUID = null;
}
}
Now, your template will finally look something like this:
<b-modal v-model="modalVisible">Fill form to add an item !
<button v-on:click="showSectionID(modalSectionUUID)">SHOW</button>
</b-modal>
<div v-for="(section) in allDataObject['Section']" :key="section['uuid']">
<h4>Section Name: {{ section["sectionName"] }}</h4>
<h4>Section Description: {{ section["sectionDescription"] }}</h4>
<template>
<div>
<b-button #click="showModal(section['uuid'])">Add Item</b-button>
</div>
</template>
</div>

Using v-model inside nested v-for

I am trying to use multiple carousel components inside card components with nested v-for loops but I’m having trouble figuring out the correct way to assign the carousel v-model so that it’s unique and doesn’t update all the carousels when the slide is changed which is what I currently have,
Here is the code I have so far:
<q-card
v-for="(item, index) in inventory"
:key="index"
style="width: 20rem;"
>
<q-card-section
class="q-pa-none text-white"
>
<q-carousel
animated
arrows
navigation
infinite
style="height: 15rem;"
v-model="slide" // What should this be assigned so that
>
<q-carousel-slide
v-for="(image, index) in item.images"
:key="index"
:name="index" //It works with the slide name and only updates the respective q-carousel
:img-src="image.url"
>
</q-carousel-slide>
</q-carousel>
</q-card-section>
</q-card>
slide is simply a data prop assigned to 0, this works but when I change the slide of one carousel all of the carousels change too.
Hopefully this makes sense, It’s a bit hard for me to explain it but let me know anything that needs clarification
Edit: Dropped the code in codepen here is the link: https://codepen.io/launchit-studio/pen/jOVrKzQ
The issue I am having is that the v-model affects all of the carousel slides not just the one that is clicked. I understand this is because the slide prop is shared by all the carousels but I am not sure of what to use in order for it to be 'independent'
Instead of using a single model slide for all the slides, use an array of models. (An object would work too).
data() {
return {
slide: 1, ❌
activeSlides: [] ✅
}
}
The index of the carousel in the v-for will also be used as the index in the array:
<q-carousel
animated
arrows
navigation
infinite
style="height: 15rem;"
v-model="activeSlides[index]"
>
Since each carousel's model needs to start at 1, you can initialize activeSlides accordingly:
created() {
const numCarousels = this.inventory.length;
this.activeSlides = Array(numCarousels).fill(1);
},
Here is the updated CodePen.

Bootstrap-Vue pagination not displaying the updated sliced array content on screen

Im using bootstrap vue's pagination component to break up and display content from a v-for loop. I am slicing the array perPage. Everything seems to be working. the correct number of perPage is displayed. The correct number of rows. The only problem is that when I select a new page, the content is never updated on the screen. It shows the same data on every page.
I have console logged the sliced array depending on what page and the slice is happening and working on everyPage click, I just cant get that new array to display on screen.
<b-paggination v-model="currentPage" :total-rows="rows" :per-
page="perPage" aria-controls="my-table" </b-pagination>
<b-col v-if="!showLoad" class="mb-4" v-for="(data,index) in
listOfData" id="my-table" :key="index" cols="12>
<app-card v-bind:data="Data[index]></app-card>
</b-col>
computed: {
rows() {
return this.data.length;
}
listOfData() {
const items = this.Data
return items.slice((this.currentPage - 1) * this.perPage,
this.currentPage * this.perPage);
}
}
Update: I discovered that injecting the content from the v-for into the imported card component (app-card) was somehow stoping the content from updating from page to page. I just removed the app-card component and hard coded a card in its place.. Now for some reason the content is changing from page to page.
```
//This Works:
<div v-for="(data, index) in listOfData" :key="index">
<b-card
overlay
img-src="https://picsum.photos/900/250/?image=3"
img-alt="Card Image"
text-variant="white"
title="Image Overlay"
sub-title="Subtitle"
>
<b-card-text>
{{ data.Data }}
</b-card-text>
</b-card>
</div>
//This Doesnt Work:
<div v-for="(data, index) in listOfData" :key="index">
<app-card v-bind:Dataprop="Data"></app-card>
</div>```