Swiper.IO pagination dots now showing - javascript

for some reason the swiper does not show the pagination for the image casousel that i crated.
It shows up in the dom but with the height of 0. Changing it manually did not do anything. Any ideas?
import Swiper from '../../vendor/swiper.min.js';
export default {
name: 'ImageCarouselBlock',
components: {
MediaImage,
},
props: {
cmsData: {
type: Object,
default: () => {
return {};
},
},
},
mounted() {
let carouselConfig = {};
if (this.cmsData.auto){
carouselConfig = {
spaceBetween: 30,
centeredSlide: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
};
}
else {
carouselConfig = {
spaceBetween: 30,
loop: true,
pagination: {
el: '.swiper-pagination',
},
};
}
const mySwiper = new Swiper('.swiper-container', carouselConfig);
},
computed: {
images() {
return this.cmsData.images.map( image => {
return {
// TODO maybe get something from amplicence that tells how big they want the carousel to be?
imageData : getMediaAndSources(image.name, '1500'),
};
});
},
},
};
And this is the corresponding template. I tried changing the position of where i put the pagination element but nothing worked. I am out of ideas here and i need some help.
<div class="image-carousel-block">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="image in images">
<media-image preload="true" :sources="image.imageData.sources" :media="image.imageData.media" />
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>

The culprit was in my vue file.
<template src="./template.html"></template>
<script src="./script.js"></script>
<style lang="stylus" scoped> -- wrong here
#import '../../vendor/swiper.styl'
#import './style.styl'
</style>
Removing "scoped" did the trick for me.

Related

How to delay nth child item animation in Vue JS

I want delay animation for another item's directly by Vue Js, not css.
In this moment Vue wait until all items has rendered, and all appear at the same time.
How to do delay by change this.animated = true ?
Item.vue
<template>
<transition name="animation-fade">
<div v-if="this.animated">
{{this.itemProp.content}}
</div>
</transition>
</template>
<script>
export default {
name: 'Item',
props: {
itemProp: Object,
},
data: function() {
return {
animated: false,
loading: true,
};
},
methods: {
delayedShow: function(delay) {
setTimeout(this.toggleItem, delay)
},
},
toggleItem: function() {
this.animated = true;
},
mounted: function() {
this.delayedShow(500);
},
}
</script>
Items are defined in other component and every pass by prop to Item model.
Help me please.

Using vue.js v-show to hide hubspot form

I've been having trouble using vue's v-show to show/hide 2 hubspot form, one at a time depending on the current website locale/language(using vue i18n). The navbar is responsible for changing between languages.
Right now both are always showing, or none of them shows.
I came to a point where I decided to install vuex to try to solve the issue, but no success.
Any thoughts?
The vue component with both forms, one in each div and the JS that generates the hubspot forms:
<b-row>
<b-col class="register-form" md="12">
<div
id="registerFormEN"
v-show="this.getLangEn"
v-once
class="d-flex align-items-center justify-content-center"
></div>
<div
v-show="this.getLangPt"
v-once
id="registerFormPT"
class="d-flex align-items-center justify-content-center"
></div>
</b-col>
</b-row>
<script>
import { mapGetters } from "vuex";
import Vue from "vue";
export default {
name: "Registercourse",
},
computed: {
...mapGetters(["getLangEn", "getLangPt"])},
mounted() {
const script = document.createElement("script");
script.src = "https://js.hsforms.net/forms/v2.js";
document.body.appendChild(script);
script.addEventListener("load", () => {
if (window.hbspt) {
window.hbspt.forms.create({
region: "na1",
portalId: "stuff",
formId: "stuff",
target: "#registerFormEN",
});
}
});
script.src = "https://js.hsforms.net/forms/v2.js";
document.body.appendChild(script);
script.addEventListener("load", () => {
if (window.hbspt) {
window.hbspt.forms.create({
region: "na1",
portalId: "stuff",
formId: "stuff",
target: "#registerFormPT",
});
}
});
</script>
The store that is hosting the state for the v-show booleans:
(Yes, it's completely OP using a state management for 2 booleans... I got desperate)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
lang: {
en: true,
pt: false,
},
},
getters: {
getLangEn(state) {
return state.lang.en;
},
getLangPt(state) {
return state.lang.pt;
},
},
mutations: {
setLangEn(state, en) {
state.lang.en = en;
},
setLangPt(state, pt) {
state.lang.pt = pt;
},
},
actions: {
changeLangEn: function({ commit }, params) {
commit("setLangEn", params);
},
changeLangPt: function({ commit }, params) {
commit("setLangPt", params);
},
},
modules: {},
strict: false,
});
And the navbar's JS that changes the locale/language of the website:
<script>
import { mapActions } from "vuex";
export default {
name: "Navbar",
computed: {
displayLocale() {
let other = "PT";
if (this.$i18n.locale === "pt") {
other = "EN";
}
return other;
},
},
methods: {
...mapActions(["changeLangEn", "changeLangPt"]),
setLocale(locale) {
this.$i18n.locale = locale;
},
switchLocale() {
if (this.$i18n.locale === "pt") {
this.$i18n.locale = "en";
this.$store.dispatch("changeLangEn", true);
this.$store.dispatch("changeLangPt", false);
console.log("En to true, Pt to false");
} else {
this.$i18n.locale = "pt";
this.$store.dispatch("changeLangEn", false);
this.$store.dispatch("changeLangPt", true);
console.log("Pt to true, En to false");
}
},
},
};
</script>
Again, I bet the answer is something ridiculously simple, but I'm just not getting it.
Anyone?
You're using the Bootstrap d-flex class on these elements, which like all of the Bootstrap d-* classes tags its display property with !important. The Vue v-show directive works by toggling display: none on and off the element, but it doesn't tag that with !important. As discussed in this Vue issue, that makes the two approaches incompatible unless you deconflict them like this:
<div
id="registerFormEN"
v-show="getLangEn"
v-once
:class="{ 'd-flex': getLangEn }"
class="align-items-center justify-content-center"
>

how to prevent click to move to the next slide in swiperjs?

How to cancel the click of the next button in swiper base on my logic?
I use swiperjs in vue base on swiperjs, and I want to prevent the from the user to swipe or click on the button to go the next slide base on the results from my logic function.
I try this - not works.
swiper.on('init', async () => {
swiper.navigation.$nextEl.on('click', (e) => {
if (true /* mylogic() */) { e.preventDefault(); }
});
...
});
and this:
<div #click="onNext" slot="button-next"></div>
...
function onNext(e) {
if (true /* mylogic() */) { e.preventDefault(); }
}
Nothing works - the swiper is still move to the next slide.
How to prevent the click to move to the next slide?
Code on Codesandbox.io
By configuring the swiper options to use .swiper-button-prev to trigger the next swipe, it is taking place before your on-click function onNext().
Essentially you need to prevent swiper firing on the next arrow click, and then implement it yourself with the swiper.slideNext() method.
So. Add a ref to the swiper element, remove the swiper-button-prev class, move you onNext() method to the methods object (where it should be, right?), call the swiper.slideNext() method in your function, if someCondition is true.
codesandbox...
<template>
<div id="app">
<h2>1</h2>
<swiper ref="mySwiper" :options="swiperOption1">
<swiper-slide v-for="(game, index) in jackpotGames" v-bind:key="index">
<div class="game-item game-item__1">
game_id: {{game.game_id}},
<br>
provider: {{game.provider}},
<br>
img: {{game.img}}
</div>
</swiper-slide>
<div class="swiper-button-prev" slot="button-prev">←</div>
<div #click="onNext" class="" slot="button-next">→</div>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
export default {
name: "App",
components: {
swiper,
swiperSlide
},
data() {
return {
swiperOption1: {
slidesPerView: 4,
slidesPerColumn: 1,
spaceBetween: 16,
freeMode: true,
pagination: {
el: ".swiper-pagination",
type: "progressbar"
},
navigation: {
// nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
},
breakpoints: {
640: {
slidesPerView: 2,
spaceBetween: 8,
pagination: {
el: ".swiper-pagination",
type: "bullets"
},
navigation: {}
}
}
},
jackpotGames: [
// Removed to save space in this answer.
]
};
},
methods: {
onNext(e) {
let someCondition = true;
if (someCondition) {
this.swiper.slideNext();
}
}
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper
}
},
mounted() {
console.log('swiper', this.swiper);
}
};
</script>

vue gallery adding loading spinner

I created a gallery using Vue, Nuxt.
The full code of my gallery you can find on GitHub,
and you can see a live demo here vue gallery demo
Most of the logic is in the vue-lighbox component.
<script>
export default {
props: {
thumbnails: {
type: Array,
required: true,
},
images: {
type: Array,
required: true,
},
thumbnailPath: {
type: String,
required: true,
},
imagePath: {
type: String,
required: true,
},
},
data() {
return {
visible: false,
currentImage: 0,
}
},
methods: {
Toggle(index) {
this.currentImage = index
this.visible = !this.visible
},
Next() {
if (this.currentImage < this.images.length - 1) {
this.currentImage++
} else {
this.currentImage = 0
}
},
Prev() {
if (this.currentImage > 0) {
this.currentImage--
} else {
this.currentImage = this.images.length - 1
}
},
},
}
</script>
<template>
<div class="thumb_container">
<div v-for="(thumbnail, index) in thumbnails" :key="thumbnail" class="thumbnail" #click="Toggle(index)">
<img :src="thumbnailPath + thumbnail" />
<div class="plus">
<i class="icon icon-plus" />
</div>
<div class="color-overlay"></div>
</div>
<div v-if="visible" class="lightbox">
<i class="icon-cancel" #click="Toggle()" />
<i class="icon-left" #click="Prev()" />
<i class="icon-right" #click="Next()" />
<img :key="currentImage" :src="imagePath + [currentImage + 1] +'.jpg'" />
</div>
</div>
</template>
A quick break down of my component:
I have small thumbnail images and big images.
The thumbnail images are displayed with for loop. Whenever I click at some of the thumbnails the corresponding big image appears.
The gallery is working fine as intended, however, I have a problem with loading the photos from user experience aspect. So I need to implement a loading spinner while the big image is loading.
I really don't know the right approach to this. Does someone have an example to share or some hint to give me?
How can I check when a fallowing image is loaded?
You can use vue's v-on:load directive to determine whether to show an image or a spinner. In my app I've made this into a custom component:
<template>
<div>
<img :src="src"
:alt="alt"
#load="onLoaded"
#error="onError"
v-show="loaded && !error"
key="image"/>
<spinner-component v-show="loaded == false || error"/>
</div>
</template>
export default {
mounted() {
},
data() {
return {
loaded: false,
error: false
}
},
props: {
src: {
type: String
},
alt: {},
width: {},
height: {}
},
computed: {
style({ width, height }) {
return {
width: width,
height: height,
objectFit: "contain"
}
}
},
methods: {
onLoaded() {
this.loaded = true;
},
onError() {
this.error = true;
}
}
}

React.js and horizontal IScroll 5 with dynamic width

I cannot make IScroll to work with React.js.
var SubHeaderMenu = React.createClass({
getDefaultProps: function () {
return {items: []};
},
componentDidMount: function () {
if (this.props.items.length && this.isMounted()) {
this.scroll = new IScroll(this.getDOMNode(), {
scrollX: true,
scrollY: false,
mouseWheel: true,
});
}
},
render: function () {
var itemNodes = this.props.items.map(function (item) {
return <div key={item.name} className="subheader-item">{item.name}</div>;
}.bind(this));
return (
<div className="bar bar-standard bar-header-secondary subheader">
<div className="scroller" ref="scroller">
<div className="scroller-inner" ref="scrollerInner">{itemNodes}</div>
</div>
</div>
);
}
});
SubHeaderMenu component receive list of items as props. This works fine if I set up width for .scroller in CSS:
.scroller { width: 600px; ... }
But without width in CSS it doesn't scroll..
How to handle dynamic width of every list item?
There is a npm-package for react and IScroll:
https://www.npmjs.com/package/react-iscroll

Categories

Resources