WIP Migrate to stimulus.js
This commit is contained in:
@@ -12,9 +12,7 @@ smoothscroll.polyfill()
|
||||
// Alpine stuff
|
||||
import Alpine from 'alpinejs'
|
||||
import parseAppConfig from './components/appconfig'
|
||||
import initSliders from './components/sliders'
|
||||
import appendPaCode from './components/pacode'
|
||||
import watchlist from './components/watchlist'
|
||||
import productDetail from './components/product-detail'
|
||||
import daytripDateSelect from './components/daytrip-date-select'
|
||||
import searchBar from './components/search-bar'
|
||||
@@ -23,9 +21,7 @@ import contactForm from './components/contact-form'
|
||||
|
||||
const appConfig = parseAppConfig()
|
||||
appendPaCode(appConfig)
|
||||
initSliders()
|
||||
Alpine.store('appconfig', appConfig)
|
||||
Alpine.data('watchlist', watchlist)
|
||||
Alpine.data('productDetail', productDetail)
|
||||
Alpine.data('daytripDateSelect', daytripDateSelect)
|
||||
Alpine.data('searchBar', searchBar)
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
import axios from 'axios'
|
||||
import flatpickr from 'flatpickr';
|
||||
import { German } from 'flatpickr/dist/l10n/de';
|
||||
import defaultFilterSettings from '../_filtersettings'
|
||||
|
||||
export default props => ({
|
||||
loading: false,
|
||||
show: null,
|
||||
picker: null,
|
||||
uri: props.uri,
|
||||
datePresets: props.datePresets,
|
||||
filterSettings: props.initialFilterSettings,
|
||||
defaultFilterSettings,
|
||||
filterCount: 0,
|
||||
dateRangeSelected: { from: null, to: null },
|
||||
dateRangeLabel: null,
|
||||
contentWrapper: null,
|
||||
init() {
|
||||
this.$watch('dateRangeSelected', () => {
|
||||
this.updateDateRangeLabel()
|
||||
})
|
||||
this.contentWrapper = this.$refs.container
|
||||
this.updateFilterCount()
|
||||
this.load()
|
||||
},
|
||||
refresh() {
|
||||
this.updateFilterCount()
|
||||
this.load()
|
||||
},
|
||||
load() {
|
||||
this.loading = true
|
||||
let data = new URLSearchParams({
|
||||
'tx_epproducts_ajax[filterSettings]': JSON.stringify(this.filterSettings)
|
||||
})
|
||||
axios.post(this.uri, data)
|
||||
.then(response => {
|
||||
this.contentWrapper.innerHTML = response.data
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
if (null !== this.filterSettings.dateFrom && null !== this.filterSettings.dateTo) {
|
||||
this.picker.setDate([ this.filterSettings.dateFrom, this.filterSettings.dateTo ])
|
||||
this.dateRangeSelected = { from: new Date(this.filterSettings.dateFrom), to: new Date(this.filterSettings.dateTo) }
|
||||
}
|
||||
this.$el.scrollIntoView({behavior: 'smooth'})
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.filterSettings = {...this.defaultFilterSettings}
|
||||
this.dateRangeSelected = { from: null, to: null }
|
||||
this.dateRangeLabel = null
|
||||
this.refresh()
|
||||
},
|
||||
initDatePicker(minDate, maxDate) {
|
||||
this.picker = flatpickr(this.$refs.picker, {
|
||||
mode: 'range',
|
||||
locale: German,
|
||||
inline: true,
|
||||
minDate: minDate,
|
||||
maxDate: maxDate,
|
||||
onChange: selectedDates => {
|
||||
if (selectedDates.length === 2) {
|
||||
this.dateRangeSelected = { from: selectedDates[0], to: selectedDates[1] }
|
||||
this.updateFilterSettings({
|
||||
dateFrom: flatpickr.formatDate(selectedDates[0], 'Y-m-d'),
|
||||
dateTo: flatpickr.formatDate(selectedDates[1], 'Y-m-d'),
|
||||
})
|
||||
this.show = null
|
||||
this.refresh()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
updateFilterSettings(values) {
|
||||
let filterSettings = {...this.filterSettings}
|
||||
this.filterSettings = {...filterSettings, ...values}
|
||||
},
|
||||
selectDateRangePreset(preset) {
|
||||
let dateFrom = new Date(preset.dateFrom)
|
||||
let dateTo = new Date(preset.dateTo)
|
||||
this.picker.setDate([ dateFrom, dateTo ])
|
||||
this.dateRangeSelected = { from: dateFrom, to: dateTo }
|
||||
this.updateFilterSettings({
|
||||
dateFrom: flatpickr.formatDate(dateFrom, 'Y-m-d'),
|
||||
dateTo: flatpickr.formatDate(dateTo, 'Y-m-d'),
|
||||
})
|
||||
this.show = null
|
||||
this.refresh()
|
||||
},
|
||||
resetDateRange() {
|
||||
this.dateRangeSelected = { from: null, to: null }
|
||||
this.updateFilterSettings({
|
||||
dateFrom: null,
|
||||
dateTo: null,
|
||||
})
|
||||
this.picker.clear()
|
||||
this.picker.jumpToDate()
|
||||
this.show = null
|
||||
this.refresh()
|
||||
},
|
||||
updateDateRangeLabel() {
|
||||
let dateRangeLabel = ''
|
||||
if (null !== this.dateRangeSelected.from && null !== this.dateRangeSelected.to) {
|
||||
let dateFrom = this.dateRangeSelected.from
|
||||
let dateTo = this.dateRangeSelected.to
|
||||
dateRangeLabel = `${flatpickr.formatDate(dateFrom, 'd.m.Y')} - ${flatpickr.formatDate(dateTo, 'd.m.Y')}`
|
||||
}
|
||||
this.dateRangeLabel = dateRangeLabel
|
||||
},
|
||||
updateFilterCount() {
|
||||
let count = 0
|
||||
if (this.filterSettings.dateFrom !== null) count++
|
||||
if (this.filterSettings.dateTo !== null) count++
|
||||
if (this.filterSettings.countryUids.length > 0) count++
|
||||
if (this.filterSettings.regionUids.length > 0) count++
|
||||
if (this.filterSettings.cityUids.length > 0) count++
|
||||
if (this.filterSettings.conceptUids.length > 0) count++
|
||||
if (this.filterSettings.hotelTypes.length > 0) count++
|
||||
if (this.filterSettings.boardTypes.length > 0) count++
|
||||
if (this.filterSettings.roomTypes.length > 0) count++
|
||||
if (this.filterSettings.priceRanges.length > 0) count++
|
||||
if (this.filterSettings.bus) count++
|
||||
if (this.filterSettings.pax > 2) count++
|
||||
this.filterCount = count
|
||||
},
|
||||
})
|
||||
@@ -1,22 +0,0 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export default uri => ({
|
||||
loading: false,
|
||||
uri,
|
||||
init() {
|
||||
this.load()
|
||||
},
|
||||
load() {
|
||||
this.loading = true
|
||||
let data = new URLSearchParams({
|
||||
'tx_epproducts_ajax[watchlistUids]': JSON.stringify(this.$store.watchlist),
|
||||
})
|
||||
axios.post(this.uri, data)
|
||||
.then(response => {
|
||||
this.$refs.watchlist.innerHTML = response.data
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
+9
-5
@@ -1,3 +1,4 @@
|
||||
import { Controller } from 'stimulus'
|
||||
import Splide from '@splidejs/splide'
|
||||
|
||||
const defaultOptions = {
|
||||
@@ -90,13 +91,16 @@ const presets = {
|
||||
},
|
||||
}
|
||||
|
||||
export default () => {
|
||||
document.querySelectorAll( '[data-slider]').forEach(element => {
|
||||
export default class extends Controller {
|
||||
|
||||
static values = { preset: String }
|
||||
|
||||
connect() {
|
||||
let options = {}
|
||||
const preset = element.dataset.slider
|
||||
let preset = this.presetValue
|
||||
if (preset in presets) {
|
||||
options = presets[preset]
|
||||
}
|
||||
new Splide(element, options).mount()
|
||||
})
|
||||
new Splide(this.element, options).mount()
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import { Controller } from 'stimulus'
|
||||
import { useFetch } from '../mixins/use_fetch'
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
static targets = [ 'container', 'loadingIndicator' ]
|
||||
|
||||
static values = {
|
||||
uri: String,
|
||||
loading: Boolean,
|
||||
}
|
||||
|
||||
initialize() {
|
||||
useFetch(this)
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.load()
|
||||
}
|
||||
|
||||
load() {
|
||||
this.loadingValue = true
|
||||
let data = new URLSearchParams({
|
||||
'tx_epproducts_ajax[watchlistUids]': sessionStorage.getItem('myep-watchlist'),
|
||||
})
|
||||
fetch(this.uriValue, { method: 'POST', body: data })
|
||||
.then(this.checkStatus)
|
||||
.then(this.parseHTML)
|
||||
.then(html => {
|
||||
this.containerTarget.innerHTML = html
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingValue = false
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<div class="lg:-mt-8">
|
||||
<div class="splide" data-slider="header">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="header">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{slides}" as="slide" iteration="iteration">
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
<f:if condition="{teasers}">
|
||||
<f:then>
|
||||
<a id="teasers" class="anchor"></a>
|
||||
<div class="splide" data-slider="teasers">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasers">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="teaser">
|
||||
|
||||
+3
-1
@@ -4,7 +4,9 @@
|
||||
|
||||
<f:alias map="{images: '{media -> v:iterator.filter(propertyName: \'showinpreview\', filter: 0)}'}">
|
||||
<f:if condition="{images}">
|
||||
<div data-slider="content" class="splide">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="content">
|
||||
<div id="carousel-{id}" class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{images}" as="image" iteration="iteration">
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
<div class="bg-cover bg-center bg-header-season-{product.region.season} mb-8">
|
||||
<div class="md:container">
|
||||
<div class="md:flex md:flex-row-reverse md:items-stretch">
|
||||
<div class="md:w-5/12 md:py-4 splide" data-slider="content">
|
||||
<div class="md:w-5/12 md:py-4 splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="content">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{product.images}" as="image" iteration="iteration">
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
{region.skiArea -> f:format.html()}
|
||||
<f:if condition="{teasers}">
|
||||
<a id="teasers" class="anchor"></a>
|
||||
<div class="splide" data-slider="teasersEmbedded">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasersEmbedded">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="teaser">
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
<f:render partial="Header/Standalone" arguments="{_all}"/>
|
||||
<div>
|
||||
<ep:container data="{data}">
|
||||
<div class="splide" data-slider="teasers">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasers">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="city">
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
<div class="col-span-3 lg:col-span-2" data-rte-content>
|
||||
{concept.description -> f:format.html()}
|
||||
<f:if condition="{teasers}">
|
||||
<div class="splide mb-4" data-slider="teasersEmbedded">
|
||||
<div class="splide mb-4"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasersEmbedded">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="teaser">
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<f:section name="Main">
|
||||
<div>
|
||||
<ep:container data="{data}">
|
||||
<div class="splide" data-slider="teasers">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasers">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="concept">
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
<div class="col-span-3 lg:col-span-2" id="teasers">
|
||||
{country.description -> f:format.html()}
|
||||
<f:if condition="{teasers}">
|
||||
<div class="splide mb-4" data-slider="teasersEmbedded">
|
||||
<div class="splide mb-4"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasersEmbedded">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="teaser">
|
||||
|
||||
+3
-1
@@ -7,7 +7,9 @@
|
||||
<f:section name="Main">
|
||||
<div>
|
||||
<ep:container data="{data}">
|
||||
<div class="splide" data-slider="teasers">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasers">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="hotel">
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
<f:section name="Main">
|
||||
<div>
|
||||
<ep:container data="{data}">
|
||||
<div class="splide" data-slider="teasers">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasers">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{bookable}" as="hotel">
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
<ep:container data="{data}">
|
||||
<f:if condition="{data.flexForm.settings.layout} == 'cols'">
|
||||
<f:then>
|
||||
<div class="w-full mb-4 splide" data-slider="teasers">
|
||||
<div class="w-full mb-4 splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasers">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:render section="Teasers" arguments="{_all}"/>
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
<f:section name="Main">
|
||||
<div>
|
||||
<ep:container data="{data}">
|
||||
<div class="splide" data-slider="teasers">
|
||||
<div class="splide"
|
||||
data-controller="slider"
|
||||
data-slider-preset-value="teasers">
|
||||
<div class="splide__track">
|
||||
<ul class="splide__list">
|
||||
<f:for each="{teasers}" as="region">
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
<f:section name="Main">
|
||||
<ep:container data="{data}">
|
||||
<div class="relative"
|
||||
x-data='watchlist("<ep:uri.ajax action="list" controller="AjaxWatchlist" pageUid="{settings.defaultAjaxUid}"/>")'>
|
||||
<div x-ref="watchlist"></div>
|
||||
<div x-show="loading" class="absolute top-0 left-0 inset-0 bg-overlay-white">
|
||||
data-controller="watchlist"
|
||||
data-watchlist-uri-value="{ep:uri.ajax(action: 'list', controller: 'AjaxWatchlist', pageUid: '{settings.defaultAjaxUid}')}">
|
||||
<div data-watchlist-target="container"></div>
|
||||
<div class="absolute top-0 left-0 inset-0 bg-overlay-white hidden"
|
||||
data-watchlist-target="loadingIndicator">
|
||||
<f:image class="absolute top-1/2 left-1/2 transform -translate-xy-1/2"
|
||||
src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif"
|
||||
alt="Loading"/>
|
||||
|
||||
Reference in New Issue
Block a user