alpinejs image slider first slide repeating twice and last slide not defined - laravel-blade

I image slide on homepage http://steklo.gq/ made using alpine and there are two strange things:
First slide design-5.jpg is repeating twice on the page
It gives me error in console Uncaught ReferenceError: slide is not defined on the last slide. However image exists and last slide defined the same way as all other slides. So I cannot understand what is the problem.
Alpine Error: "ReferenceError: slide is not defined"
Expression: "slide.img"
Element: <img x-bind:src=​"slide.img" class=​"h-148 w-full lg:​h-224 object-cover" src=​"/​storage/​thumbs_xl/​slider/​1912501_1600x1200.jpg">​
handleError # app.js:18
tryCatch # app.js:18
saferEval # app.js:19
evaluateReturnExpression # app.js:187
handleAttributeBindingDirective # app.js:67
(anonymous) # app.js:186
resolveBoundAttributes # app.js:186
initializeElement # app.js:180
(anonymous) # app.js:178
(anonymous) # app.js:177
walk # app.js:16
walk # app.js:16
walk # app.js:16
walk # app.js:16
walk # app.js:16
walkAndSkipNestedComponents # app.js:176
initializeElements # app.js:178
(anonymous) # app.js:192
(anonymous) # app.js:191
attributes (async)
addClass # app.js:926
Slick.init # app.js:2702
Slick # app.js:2646
$.fn.slick # app.js:2798
(anonymous) # app.js:367
<x-slot name="mainslider">
<div class="mainslider_container absolute w-full h-full top-0" id="main_slider"
x-data="{
slides: [
{ id:1, img: '/storage/thumbs_xl/slider/design-5.jpg', text: 'Офисные перегородки <br> в стиле LOFT', textclass: 'top-1/4 text-white', buttonclass: '' },
{ id:2, img: '/storage/thumbs_xl/slider/design-7.jpg', text: 'Межкомнатные раздвижные <br> перегородки', textclass: 'bottom-1/4 text-white', buttonclass: 'text-white' },
{ id:3, img: '/storage/thumbs_xl/slider/img_20171230_191642.jpg', text: 'Лестничные ограждения <br> из закалённого стекла', textclass: 'top-1/3 text-white', buttonclass: 'text-white' },
{ id:4, img: '/storage/thumbs_xl/slider/2018-03-09-20-29-24.jpg', text: 'Цельностеклянные перегородки', textclass: 'bottom-1/4 text-white', buttonclass: 'text-white' },
{ id:5, img: '/storage/thumbs_xl/slider/peregorodka-47.jpg', text: 'Пескоструйные рисунки <br> на стекле', textclass: 'bottom-52 text-white', buttonclass: 'text-white' },
{ id:6, img: '/storage/thumbs_xl/slider/dsc_0003.jpg', text: 'Стеклянные ограждения <br> балконов и террас', textclass: 'top-28', buttonclass: '' },
{ id:7, img: '/storage/thumbs_xl/slider/1912501_1600x1200.jpg', text: 'Стеклянные перегородки для ресторанов', textclass: 'top-28 text-white', buttonclass: '' },
]
}"
x-effect="console.log(slide)"
>
<template x-for="slide in slides" :key="slide.id">
<div class="mainslider_item relative">
<img x-bind:src="slide.img" class="h-148 w-full lg:h-224 object-cover">
<div class="mainslider_item_text absolute w-full flex justify-center py-4 text-3xl font-bold" x-bind:class="slide.textclass" x-html="slide.text">
</div>
<div class="mainslider_item_button absolute top-12 right-0 w-1/2 flex justify-center" x-bind:class="slide.buttonclass">
<x-modules.link-button
link="#" text="Заказать звонок" icon="phone-ringing-outline"
style="black-outline" class="w-48 p-1.5"
#click.prevent="contactForm()"
/>
</div>
</div>
</template>
</div>
</x-slot>
resources/js/app.js
require('./includes/script.js');
resources/js/bootstrap.js
window.carousel = require('slick-carousel');
resources/js/includes/script.js
window.addEventListener('DOMContentLoaded', function(){
/*===== slick carousel modal plugin =====*/
/*============= main slider =============*/
$('#main_slider').slick({
arrows: true,
adaptiveHeight: true,
dots: true,
infinite: true,
autoplay: true,
nextArrow: '<div class="main__arrow arrow-next"></div>',
prevArrow: '<div class="main__arrow arrow-prev"></div>',
responsive: [
{
breakpoint: 768,
settings: {
arrows: false
}
}
]
});
/*===== FINISH slick carousel modal plugin =====*/
});

Related

trigger slide in swiper.js from extern via vuejs

I tried to address a method from an external button that is in swiper.js 8.1.0. goes to the next slide.
I created a refSwiper with the compositon API, no idea I don't see any function that I can call there, even with #onSwiper I get a reference to Swiper, but it doesn't move.
<swiper class="swiper-container" ref="swiperRef"
:pagination="{clickable: true,type: 'fraction' }"
:navigation="{ nextEl: '.arrow', }"
:modules="modules"
:centeredSlides="true"
:loop="false"
:simulate-touch="true"
:allow-touch-move="true"
:allow-slide-next="true"
:allow-slide-prev="true"
:watch-slides-progress="true"
#swiper="onSwiper"
#slideChange="onSlideChange"
:breakpoints="{
'1200': {
slidesPerView: 3,
spaceBetween: 770,
},
}"
>
<swiper-slide v-for="item, index in array" :key="index" >
<div class="kachel" #click="go(index)" ></div>
</swiper-slide>
</swiper>
<div class="arrows" >
<img src="../assets/svgs/rechtslinks.svg" alt="" #click="onSwipeNext()" >
</div>
ok, but how can i call the right function in my swiperRef
const onSwipeNext = () => {
console.log(swiperRef);
swiperRef.value.nextSlide();
}

How to give equal space between the items using tailwind css v3

I am using Tailwind CSS with next.js.
I have 8 images of different sizes and want to keep 4 images in a row for mid and large-size devices and 2 images in a row for small-size devices.
I want to give equal space between the items in a row but I want the first item in a row to be at the leftmost place and the last item in a row to be at the rightmost place.
The rest of the items should maintain equal distance between them.
How can I achieve this using Tailwind CSS? Normally with some conditions, I know how to do it, but is there any way to do it directly with Tailwind?
JSON response from API:
const ourPartners = [
{
id: "partner01",
pic: partner_01
},
{
id: "partner02",
pic: partner_02,
},
{
id: "partner03",
pic: partner_03,
},
{
id: "partner04",
pic: partner_04,
},
{
id: "partner05",
pic: partner_05,
},
{
id: "partner06",
pic: partner_06,
},
{
id: "partner07",
pic: partner_07,
},
{
id: "partner08",
pic: partner_08,
}
]
The code where I'm mapping over the array:
<div className="flex flex-row flex-wrap justify-between items-center">
{
ourPartners.map((item, index) => {
return (
<div className={`md:w-1/4 w-1/2 mb-10 ${(index % 4 !== 0 ? ('flex justify-center') : ('flex justify-start'))}`} key={item.id}>
<div className="w-32 object-contain">
<Image
alt="partner"
width="auto"
height="auto"
src={item.pic}
quality={100}
/>
</div>
</div>
)
})
}
</div>
EDITED:
I actually learned something new here too. You can use nth-child now with Tailwind.
const Partners = () => {
return (
<div className="grid md:grid-cols-4 grid-cols-2 gap-y-10 justify-between">
{ourPartners.map((item, index) => {
return (
<div
key={item.id}
className="odd:justify-self-start even:justify-self-end md:[&:nth-child(4n+2)]:justify-self-center md:[&:nth-child(4n+3)]:justify-self-center"
>
<div className="w-32">
<img alt="partner" width="auto" height="auto" src={item.pic} />
</div>
</div>
);
})}
</div>
);
};
export default Partners;

How to display preview of the selected image using Angular

I would like to show the preview of the selected image busing Angular, as of now if we click all images are selected, can any one suggest me how to show preview of the selected one and if we select another image previously selected image should be unselect and display new image.
public images: Array<object> = [
{
src: 'https://picsum.photos/250/250/?image=110',
description: 'Notte in hotel di lusso',
price: 250
},
{
src: 'https://picsum.photos/250/250/?image=58',
description: 'Escursione alla scoperta degli animali dell\'isola',
price: 160
}
];
HTML:
<div class="image__container" [ngClass]="{ 'selected': selected }">
<img class="image" [src]="item.src">
<div
class="image__description"
(click)="selected = !selected"
>
<div class="image__description--content">
<div class="image__description--price">
{{ item.price }}
</div>
</div>
</div>
Stackblitz
Thanks for the detailed question, You can check the below stackblitz, I needed to just add a parent property that tracks the currently selected row, then emit an event from the child which updates the latest value from the child. Then if the changes do not show up, we can call this.cdr.detectChanges() to trigger change detection manually. Please check the below code and let me know if any questions.
import {
Component,
ChangeDetectionStrategy,
ChangeDetectorRef,
ViewChildren,
QueryList,
} from '#angular/core';
import { GridItemComponent } from '../grid-item/grid-item.component';
#Component({
selector: 'aer-grid',
templateUrl: './grid.component.html',
styleUrls: ['./grid.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GridComponent {
currentlySelected;
#ViewChildren('gridItem') gridItems: QueryList<GridItemComponent>;
public images: Array<object> = [
{
src: 'https://picsum.photos/250/250/?image=110',
description: 'Notte in hotel di lusso',
price: 250,
},
{
src: 'https://picsum.photos/250/250/?image=58',
description: "Escursione alla scoperta degli animali dell'isola",
price: 160,
},
{
src: 'https://picsum.photos/250/250/?image=76',
description: 'Gita in bicicletta',
price: 50,
},
{
src: 'https://picsum.photos/250/250/?image=61',
description: "Visita di una delle cittadine dell'isola",
price: 25,
},
{
src: 'https://picsum.photos/250/250/?image=64',
description: 'Gita in motoscafo',
price: 85,
},
{
src: 'https://picsum.photos/250/250/?image=71',
description: 'Biglietto aereo',
price: 500,
},
{
src: 'https://picsum.photos/250/250/?image=65',
description: 'Cocktail sulla spiaggia',
price: 5,
},
];
constructor(private cdr: ChangeDetectorRef) {}
updateCurrentlySelected(value: number) {
this.currentlySelected = value;
this.cdr.markForCheck();
// not needed below line
// this.gridItems.forEach((item) => item.detectChanges());
}
}
html
<section class="grid-container">
<ng-container *ngFor="let image of images; let index = index">
<aer-grid-item
#gridItem
[item]="image"
[index]="index"
[currentlySelected]="currentlySelected"
(emitChange)="updateCurrentlySelected($event)"
></aer-grid-item>
</ng-container>
</section>
<!-- Preview of the selected image-->
<br />
<br />
<section>
*ngIf="images && images[currentlySelected] && images[currentlySelected].src"
Preview:
<img [src]="images[currentlySelected].src" />
stackblitz

Headless Ui vue scripts not working on my end

So I stumbled upon headless ui since tailwind ui uses this for their functionality but my code isn't working..I have successfully installed vue 3 which is a requirement for headlessui/vue but I can't get it to work on my end. This is the code I'm talking about
<template>
<div class="w-full max-w-md px-2 py-16 sm:px-0">
<TabGroup>
<TabList class="flex p-1 space-x-1 bg-blue-900/20 rounded-xl">
<Tab
v-for="category in Object.keys(categories)"
as="template"
:key="category"
v-slot="{ selected }"
>
<button
:class="[
'w-full py-2.5 text-sm leading-5 font-medium text-blue-700 rounded-lg',
'focus:outline-none focus:ring-2 ring-offset-2 ring-offset-blue-400 ring-white ring-opacity-60',
selected
? 'bg-white shadow'
: 'text-blue-100 hover:bg-white/[0.12] hover:text-white',
]"
>
{{ category }}
</button>
</Tab>
</TabList>
<TabPanels class="mt-2">
<TabPanel
v-for="(posts, idx) in Object.values(categories)"
:key="idx"
:class="[
'bg-white rounded-xl p-3',
'focus:outline-none focus:ring-2 ring-offset-2 ring-offset-blue-400 ring-white ring-opacity-60',
]"
>
<ul>
<li
v-for="post in posts"
key="post.id"
class="relative p-3 rounded-md hover:bg-coolGray-100"
>
<h3 class="text-sm font-medium leading-5">
{{ post.title }}
</h3>
<ul
class="flex mt-1 space-x-1 text-xs font-normal leading-4 text-coolGray-500"
>
<li>{{ post.date }}</li>
<li>·</li>
<li>{{ post.commentCount }} comments</li>
<li>·</li>
<li>{{ post.shareCount }} shares</li>
</ul>
<a
href="#"
:class="[
'absolute inset-0 rounded-md',
'focus:z-10 focus:outline-none focus:ring-2 ring-blue-400',
]"
/>
</li>
</ul>
</TabPanel>
</TabPanels>
</TabGroup>
</div>
</template>
<script>
import { ref } from 'vue'
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '#headlessui/vue'
export default {
components: {
TabGroup,
TabList,
Tab,
TabPanels,
TabPanel,
},
setup() {
let categories = ref({
Recent: [
{
id: 1,
title: 'Does drinking coffee make you smarter?',
date: '5h ago',
commentCount: 5,
shareCount: 2,
},
{
id: 2,
title: "So you've bought coffee... now what?",
date: '2h ago',
commentCount: 3,
shareCount: 2,
},
],
Popular: [
{
id: 1,
title: 'Is tech making coffee better or worse?',
date: 'Jan 7',
commentCount: 29,
shareCount: 16,
},
{
id: 2,
title: 'The most innovative things happening in coffee',
date: 'Mar 19',
commentCount: 24,
shareCount: 12,
},
],
Trending: [
{
id: 1,
title: 'Ask Me Anything: 10 answers to your questions about coffee',
date: '2d ago',
commentCount: 9,
shareCount: 5,
},
{
id: 2,
title: "The worst advice we've ever heard about coffee",
date: '4d ago',
commentCount: 1,
shareCount: 2,
},
],
})
return { categories }
},
}
</script>
and here's my package.json with the dependencies
"devDependencies": {
"#tailwindcss/ui": "^0.3",
"#vue/compiler-sfc": "^3.2.4",
"autoprefixer": "^9.6",
"axios": "^0.21",
"bootstrap": "^4.6.0",
"jquery": "^3.6",
"laravel-mix": "^6.0.27",
"lodash": "^4.17.19",
"popper.js": "^1.16.1",
"postcss": "^8.1.14",
"postcss-import": "^12.0",
"postcss-nested": "^4.2",
"resolve-url-loader": "^3.1.2",
"sass": "^1.32.11",
"sass-loader": "^11.0.1",
"tailwindcss": "^1.8",
"vue": "^2.6.12",
"vue-loader": "^16.5.0",
"vue-template-compiler": "^2.6.12"
},
"dependencies": {
"#headlessui/vue": "^1.4.0",
"#heroicons/vue": "^1.0.4",
"#popperjs/core": "^2.9.3",
"#tailwindcss/forms": "^0.3.3",
"vue": "^3.2.4"
}
then my app.js where I handle my vue components
require('./bootstrap');
import { createApp } from 'vue'
import example from './components/ExampleComponent.vue'
import test from './components/test.vue'
createApp({
components:{
example,
test,
}
}).mount('#app')
I really hope anyone can help me if I understand how this structure works it would be a great help moving forward on my career
So I reviewed my code and the problem is that I put 2 script tags in the header and footer so I just removed the footer script and it works perfectly

Responsive and dynamic background images in Vue.js

I'm trying to build a vue.js front-end and the design is calling for 100% width tiles with a dynamic background image that will be passed along the rest of the content to the page. I already have the payload passing to the component that renders each tile, but I need to render the background image for each of the tiles. I also need to mention that the images are actually 3 images for each tile that need to render for each of our 3 breakpoints. So far I was able to pass one image by using :style="'background-image: url(' + backgroundImage + ')'" but this only serves one image per tile. My question is, what would be the best way to pass all 3 images per tile and render them correctly?
I have heard online that I should just use srcset and pass all 3 to an <img> tag, and make that image the background by using CSS, but that just seems unorthodox.
Is there a more elegant way to deal with responsive background images in reusable components in vue.js?
Home Page
<template>
<div class="Home">
<HomePageTile v-for="tile in tiles" :key="tile.title" :tile-title="tile.title" :tile-desc="tile.description" :tile-type="tile.position" :background-image="tile.backgroundImage"/>
</div>
</template>
<script>
import HomePageTile from '#/components/HomePageTile'
import tileImage1 from '#/assets/optimized/image1.jpg'
import tileImage2 from '#/assets/optimized/image2.jpg'
import tileImage3 from '#/assets/optimized/image3.jpg'
import tileImage4 from '#/assets/optimized/image4.jpg'
export default {
name: 'Home',
components: {
HomePageTile: HomePageTile
},
data () {
return {
tiles: [
{
title: 'Title 1',
description: 'Content 1',
position: 'right',
backgroundImage: tileImage1
}, {
title: 'Title 2',
description: 'Content 2',
position: 'right',
backgroundImage: tileImage2
}, {
title: 'Title 3',
description: 'Content 3',
position: 'right',
backgroundImage: tileImage3
}, {
title: 'Title 4',
description: 'Content 4',
position: 'right',
backgroundImage: tileImage4
}
]
}
}
}
</script>
Tile Component
<template>
<div :class="tilePosition(tileType)" :style="'background-image: url(' + backgroundImage + ')'">
<template v-if="tileType">
<div class="home-page-tile--container home-page-tile--container__with-desc">
<h2 class="home-page-tile--container--title">{{ tileTitle }}</h2>
<p class="home-page-tile--container--description">{{ tileDesc }}</p>
</div>
<div class="home-page-tile--call-to-action" v-if="callToAction">
<p class="home-page-tile--call-to-action--text">{{ callToAction.text }}</p>
<Button class="home-page-tile--call-to-action--button" :button-route="callToAction.buttonPath" :button-text="callToAction.buttonText" :button-style="callToAction.buttonStyle" />
</div>
</template>
<template v-else>
<div class="home-page-tile--container">
<h2 class="home-page-tile--container--title">{{ tileTitle }}</h2>
<Button :button-route="buttonPath" :button-text="buttonText" button-style="pill"/>
</div>
</template>
</div>
</template>
<script>
import Button from './Button'
export default {
name: 'HomePageTile',
props: {
tileType: String,
tileTitle: String,
tileDesc: String,
backgroundImage: String,
buttonText: String,
buttonPath: String,
callToAction: Object
},
components: {
Button: Button
},
data () {
return {
tilePosition: function (el) {
if (el) {
return 'home-page-tile home-page-tile__' + el
} else {
return 'home-page-tile'
}
}
}
}
}
</script>

Resources