Replace tooltips and page scrolling, migrate faq filter
This commit is contained in:
Generated
+11
@@ -4819,6 +4819,11 @@
|
||||
"picomatch": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"microtip": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/microtip/-/microtip-0.2.2.tgz",
|
||||
"integrity": "sha512-oah38eH5vSHVFP6yXjbKWOYt92mav++0j3zh844h1vhOscqEg7Rf4agDEIwUTFCcAPPdlhYUQMe6eZfHgD+4oQ=="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
@@ -7004,6 +7009,12 @@
|
||||
"resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
|
||||
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA=="
|
||||
},
|
||||
"smoothscroll-polyfill": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/smoothscroll-polyfill/-/smoothscroll-polyfill-0.4.4.tgz",
|
||||
"integrity": "sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==",
|
||||
"dev": true
|
||||
},
|
||||
"sockjs": {
|
||||
"version": "0.3.21",
|
||||
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
|
||||
|
||||
+3
-1
@@ -23,6 +23,7 @@
|
||||
"jquery": "^1.12.4",
|
||||
"lazysizes": "^4.1.8",
|
||||
"leaflet": "^1.7.1",
|
||||
"microtip": "^0.2.2",
|
||||
"normalize.css": "^7.0.0",
|
||||
"picturefill": "^3.0.3",
|
||||
"sass-mq": "^3.3.2",
|
||||
@@ -39,9 +40,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.14.5",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/preset-env": "^7.14.5",
|
||||
"@symfony/webpack-encore": "^1.5.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"autoprefixer": "^9.4.6",
|
||||
"core-js": "^3.15.0",
|
||||
"file-loader": "^6.2.0",
|
||||
@@ -49,6 +50,7 @@
|
||||
"postcss": "^8.3.5",
|
||||
"postcss-loader": "^5.3.0",
|
||||
"sass-loader": "^9.0.3",
|
||||
"smoothscroll-polyfill": "^0.4.4",
|
||||
"vue-loader": "^15.9.7",
|
||||
"vue-template-compiler": "^2.6.14"
|
||||
},
|
||||
|
||||
@@ -6,6 +6,51 @@ const application = Application.start()
|
||||
const context = require.context('./controllers', true, /\.js$/)
|
||||
application.load(definitionsFromContext(context))
|
||||
|
||||
// Polyfills
|
||||
import smoothscroll from 'smoothscroll-polyfill'
|
||||
smoothscroll.polyfill()
|
||||
|
||||
// Function to parse config values from JSON data in HTML source
|
||||
const parseAppConfig = () => {
|
||||
const configElement = document.getElementById('appconfig');
|
||||
if (null === configElement) {
|
||||
return {}
|
||||
}
|
||||
return JSON.parse(configElement.innerHTML);
|
||||
}
|
||||
|
||||
// Function to append pacode parameter to urls specified in config by domain
|
||||
const appendPaCode = appConfig => {
|
||||
const paCode = appConfig.paCode
|
||||
const externalDomains = appConfig.externalDomains
|
||||
if (!paCode) {
|
||||
return
|
||||
}
|
||||
document.querySelectorAll('a').forEach(element => {
|
||||
if (element.hostname === location.hostname) {
|
||||
return
|
||||
}
|
||||
if (externalDomains.indexOf(element.hostname) === -1) {
|
||||
return
|
||||
}
|
||||
let url = element.href
|
||||
if (!url) {
|
||||
return
|
||||
}
|
||||
if (url.indexOf('agenturcode=') !== -1) {
|
||||
return
|
||||
}
|
||||
const separator = url.indexOf('?') === -1 ? '?' : '&'
|
||||
url += separator + 'agenturcode=' + paCode
|
||||
element.href = url
|
||||
})
|
||||
}
|
||||
|
||||
// Executed on document ready
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const appConfig = parseAppConfig()
|
||||
appendPaCode(appConfig)
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -16,12 +61,10 @@ import $ from 'jquery'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
import '@fancyapps/fancybox'
|
||||
import axios from 'axios'
|
||||
|
||||
global.$ = global.jQuery = $;
|
||||
|
||||
require('cookieconsent');
|
||||
require('slick-carousel');
|
||||
require('lazysizes');
|
||||
require('lazysizes/plugins/unveilhooks/ls.unveilhooks');
|
||||
require('bootstrap-sass/assets/javascripts/bootstrap');
|
||||
@@ -44,9 +87,6 @@ import HotelList from './components/HotelList.vue'
|
||||
|
||||
// Define global constants
|
||||
const $window = $(window);
|
||||
const sliderPrevArrow = '<button class="slider-pagination__arrow slider-pagination__arrow--prev"><i class="fa fa-2x fa-chevron-left"></i></button>';
|
||||
const sliderNextArrow = '<button class="slider-pagination__arrow slider-pagination__arrow--next"><i class="fa fa-2x fa-chevron-right"></i></button>';
|
||||
const sliderDot = '<button class="slider-pagination__dot" data-role="none" role="button" tabindex="0" />';
|
||||
|
||||
// Configure fancybox
|
||||
$.fancybox.defaults.iframe.css.width = '800px';
|
||||
@@ -82,8 +122,6 @@ new Vue({
|
||||
data () {
|
||||
return {
|
||||
maxWindowWidth: 991,
|
||||
lastScrollPosition: 0,
|
||||
scrollTopVisible: false,
|
||||
searchBoxVisible: false,
|
||||
navbarLocked: false,
|
||||
searchbarFixed: false,
|
||||
@@ -105,28 +143,16 @@ new Vue({
|
||||
this.scroll(0);
|
||||
},
|
||||
scrollTo (anchorId) {
|
||||
const top = $(anchorId).offset().top - this.getHeaderOffset();
|
||||
const top = $(anchorId).offset().top;
|
||||
this.scroll(top);
|
||||
},
|
||||
scroll (top) {
|
||||
this.navbarLocked = true;
|
||||
$('html, body').stop().animate(
|
||||
{ scrollTop: top },
|
||||
650,
|
||||
() => {
|
||||
this.navbarLocked = false;
|
||||
}
|
||||
);
|
||||
},
|
||||
getHeaderOffset () {
|
||||
return $('.searchbar').hasClass('affix') ? 260 : 120;
|
||||
window.scrollTo({ top: top, behavior: 'smooth' })
|
||||
},
|
||||
toggleSearchbox () {
|
||||
this.searchBoxVisible = !this.searchBoxVisible;
|
||||
},
|
||||
hideSearchbox () {
|
||||
this.searchBoxVisible = false;
|
||||
},
|
||||
toggleMobileNavigation () {
|
||||
$('[data-mobile-menu]').collapse('toggle');
|
||||
},
|
||||
@@ -145,103 +171,6 @@ new Vue({
|
||||
$(this).css('backgroundImage', 'url(' + imageSource + ')');
|
||||
});
|
||||
},
|
||||
lazyLoadBackgroundImages () {
|
||||
document.addEventListener('lazybeforeunveil', e => {
|
||||
const bg = e.target.getAttribute('data-bg');
|
||||
if (bg) {
|
||||
e.target.style.backgroundImage = 'url(' + bg + ')';
|
||||
}
|
||||
});
|
||||
},
|
||||
initCarousels () {
|
||||
// let $carouselItemWrappers = $('.slider--teasers > .slider__items').not('.slick-initialized');
|
||||
// let initCallback = this.initTeaserSlider;
|
||||
// $.each($carouselItemWrappers, function () {
|
||||
// initCallback($(this));
|
||||
// });
|
||||
// $carouselItemWrappers = $('.slider--thirds > .slider__items').not('.slick-initialized');
|
||||
// $.each($carouselItemWrappers, function () {
|
||||
// let numberOfSlides = $(this).children().length;
|
||||
// $(this).slick({
|
||||
// accessibility: false, // This is a hack to avoid a slick carousel bug. see: https://github.com/kenwheeler/slick/issues/1407#issuecomment-325228683
|
||||
// mobileFirst: true,
|
||||
// infinite: false,
|
||||
// slidesToShow: 1.15,
|
||||
// slidesToScroll: 1,
|
||||
// arrows: false,
|
||||
// dots: false,
|
||||
// responsive: [
|
||||
// {
|
||||
// breakpoint: 1200,
|
||||
// settings: {
|
||||
// slidesToShow: 3,
|
||||
// arrows: numberOfSlides > 3,
|
||||
// prevArrow: sliderPrevArrow,
|
||||
// nextArrow: sliderNextArrow
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// breakpoint: 992,
|
||||
// settings: {
|
||||
// slidesToShow: 2.75,
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// breakpoint: 640,
|
||||
// settings: {
|
||||
// slidesToShow: 2.5,
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// breakpoint: 384,
|
||||
// settings: {
|
||||
// slidesToShow: 1.75,
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// });
|
||||
// });
|
||||
},
|
||||
initTeaserSlider ($element) {
|
||||
let maxNumberOfSlides = $element.parent('.slider').hasClass('in-column') ? 3 : 4;
|
||||
$element.slick({
|
||||
accessibility: false, // This is a hack to avoid a slick carousel bug. see: https://github.com/kenwheeler/slick/issues/1407#issuecomment-325228683
|
||||
mobileFirst: true,
|
||||
infinite: false,
|
||||
slidesToShow: 1.15,
|
||||
slidesToScroll: 1,
|
||||
arrows: false,
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1200,
|
||||
settings: {
|
||||
slidesToShow: maxNumberOfSlides,
|
||||
arrows: true,
|
||||
prevArrow: sliderPrevArrow,
|
||||
nextArrow: sliderNextArrow
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
settings: {
|
||||
slidesToShow: maxNumberOfSlides - 0.5,
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 640,
|
||||
settings: {
|
||||
slidesToShow: 2.5,
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 384,
|
||||
settings: {
|
||||
slidesToShow: 1.75,
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
},
|
||||
initDropdownMenuBehavior () {
|
||||
const $dropdownLinks = $('.navbar-main').find('a.dropdown-toggle');
|
||||
if (this.mobileMode) {
|
||||
@@ -254,11 +183,6 @@ new Vue({
|
||||
});
|
||||
}
|
||||
},
|
||||
initTooltips () {
|
||||
if (!this.mobileMode) {
|
||||
$('.tooltiptoggle').tooltip();
|
||||
}
|
||||
},
|
||||
initFilterpanel () {
|
||||
const $filterPanel = $('#filterpanel');
|
||||
if (this.mobileMode) {
|
||||
@@ -267,33 +191,9 @@ new Vue({
|
||||
$filterPanel.addClass('in');
|
||||
}
|
||||
},
|
||||
initPartnerIdSelect () {
|
||||
$('[data-force-partnerid-select]').on('click', '.booking-link', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
},
|
||||
initFaqFilter () {
|
||||
const $entries = $('[data-faq-entry]');
|
||||
$('[data-faqfilter]').on('keyup', function () {
|
||||
const query = $(this).val();
|
||||
if (query.length < 3) {
|
||||
$entries.fadeIn();
|
||||
} else {
|
||||
const pattern = new RegExp(query, 'i');
|
||||
$entries.each(function () {
|
||||
const question = $(this).children('[data-faq-question]').text();
|
||||
const answer = $(this).children('[data-faq-answer]').text();
|
||||
if (!question.match(pattern) && !answer.match(pattern)) {
|
||||
$(this).fadeOut();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
initListeners () {
|
||||
$window.on('resize', () => {
|
||||
this.setMobileMode();
|
||||
this.initCarousels();
|
||||
this.initDropdownMenuBehavior();
|
||||
let newBackgroundImageMode = this.getBackgroundImageMode();
|
||||
if (this.backgroundImageMode !== newBackgroundImageMode) {
|
||||
@@ -301,12 +201,6 @@ new Vue({
|
||||
this.setResponsiveBackgroundImages();
|
||||
}
|
||||
});
|
||||
$window.on('scroll', () => {
|
||||
this.scrollTopVisible = $window.scrollTop() > $window.height()/3;
|
||||
if ($window.scrollTop() >= 0) {
|
||||
this.lastScrollPosition = $window.scrollTop();
|
||||
}
|
||||
});
|
||||
$(document).on('click', event => {
|
||||
const $clickedElement = $(event.target);
|
||||
const isNavExpanded = $('#ep-navbar-burger-menu').hasClass('collapse in');
|
||||
@@ -322,48 +216,16 @@ new Vue({
|
||||
this.searchbarFixed = false;
|
||||
});
|
||||
},
|
||||
appendPaCode () {
|
||||
const paCode = this.$store.state.config.paCode;
|
||||
const externalDomains = this.$store.state.config.externalDomains;
|
||||
if (!paCode) {
|
||||
return;
|
||||
}
|
||||
$('a').each(function () {
|
||||
if (this.hostname === location.hostname) {
|
||||
return;
|
||||
}
|
||||
if (externalDomains.indexOf(this.hostname) === -1) {
|
||||
return;
|
||||
}
|
||||
let url = $(this).attr('href');
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
if (url.indexOf('agenturcode=') !== -1) {
|
||||
return;
|
||||
}
|
||||
const separator = url.indexOf('?') === -1 ? '?' : '&';
|
||||
url += separator + 'agenturcode=' + paCode;
|
||||
$(this).attr('href', url);
|
||||
});
|
||||
},
|
||||
},
|
||||
created () {
|
||||
this.$store.dispatch('init');
|
||||
EventBus.$on('ajaxContentLoaded', () => {
|
||||
Vue.nextTick(() => {
|
||||
this.initTooltips();
|
||||
this.initFilterpanel();
|
||||
this.appendPaCode();
|
||||
});
|
||||
});
|
||||
EventBus.$on('tableLoaded', () => {
|
||||
Vue.nextTick(() => {
|
||||
this.initTooltips();
|
||||
});
|
||||
});
|
||||
EventBus.$on('scrollTo', (anchorId, offset) => {
|
||||
this.scrollTo(anchorId, offset);
|
||||
document.getElementById(anchorId).scrollIntoView({ behavior: 'smooth' })
|
||||
});
|
||||
},
|
||||
mounted () {
|
||||
@@ -371,15 +233,9 @@ new Vue({
|
||||
this.setMobileMode();
|
||||
this.setBackgroundImageMode();
|
||||
this.setResponsiveBackgroundImages();
|
||||
this.lazyLoadBackgroundImages();
|
||||
this.initListeners();
|
||||
this.initFilterpanel();
|
||||
this.initCarousels();
|
||||
this.initTooltips();
|
||||
this.initDropdownMenuBehavior();
|
||||
this.initPartnerIdSelect();
|
||||
this.initFaqFilter();
|
||||
this.appendPaCode();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -26,17 +26,17 @@
|
||||
<td>{{ row.label }}</td>
|
||||
<td style="white-space: nowrap">ab {{ calculatePrice(row.code) }} €</td>
|
||||
<td>
|
||||
<i v-if="row.skipassIncluded" data-placement="top" title="Skipass inklusive" class="fa fa-tag tooltiptoggle"></i>
|
||||
<i v-if="row.skipassIncluded" aria-label="Skipass inklusive" role="tooltip" data-microtip-position="top" class="fa fa-tag"></i>
|
||||
<a href="#" data-toggle="modal"
|
||||
:data-target="'#services' + index">
|
||||
<i data-placement="top" title="Inklusivleistungen zeigen"
|
||||
class="fa fa-info-circle tooltiptoggle"></i>
|
||||
:data-target="'#services' + index"
|
||||
data-microtip-position="top" aria-label="Inklusivleistungen zeigen" role="tooltip">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
</a>
|
||||
<div class="modal fade" :id="'services' + index" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button button--small" class="close" data-dismiss="modal">
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
<h5 class="modal-title">Inklusivleistungen</h5>
|
||||
|
||||
+14
-8
@@ -27,7 +27,11 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Termin</th>
|
||||
<th><i class="fa fa-bed tooltiptoggle" data-placement="top" title="Nächte"></i></th>
|
||||
<th>
|
||||
<span data-microtip-position="bottom" aria-label="Nächte" role="tooltip">
|
||||
<i class="fa fa-bed"></i>
|
||||
</span>
|
||||
</th>
|
||||
<th>Preis ab</th>
|
||||
<th>inkl.</th>
|
||||
<th class="hidden-xs"></th>
|
||||
@@ -59,14 +63,16 @@
|
||||
</td>
|
||||
<td class="dates-table__cell dates-table__cell--icons">
|
||||
<span class="icon-wrapper hidden-xs hidden-sm">
|
||||
<i v-if="showBusIcon(row)" data-placement="top" title="Busfahrt inklusive"
|
||||
class="fa fa-bus tooltiptoggle"></i>
|
||||
<i v-if="row.dateSkipassIncluded" data-placement="top" :title="row.season === 's' ? 'Bergbahnticket inklusive' : 'Skipass inklusive'"
|
||||
class="fa fa-tag tooltiptoggle"></i>
|
||||
<span v-if="showBusIcon(row)" data-microtip-position="top" aria-label="Busfahrt inklusive" role="tooltip">
|
||||
<i class="fa fa-bus"></i>
|
||||
</span>
|
||||
<span v-if="row.dateSkipassIncluded" data-microtip-position="top" :aria-label="row.season === 's' ? 'Bergbahnticket inklusive' : 'Skipass inklusive'" role="tooltip">
|
||||
<i class="fa fa-tag"></i>
|
||||
</span>
|
||||
</span>
|
||||
<button type="button" class="button button--light button--small hidden-xs tooltiptoggle"
|
||||
data-toggle="modal" data-placement="top" :data-target="'#dateservices' + index"
|
||||
title="Alle Inklusivleistungen anzeigen">Leistungen</button>
|
||||
<button type="button" class="button button--light button--small hidden-xs"
|
||||
data-toggle="modal" :data-target="'#dateservices' + index"
|
||||
data-microtip-position="top" aria-label="Alle Inklusivleistungen anzeigen" role="tooltip">Leistungen</button>
|
||||
<a href="#" data-toggle="modal" :data-target="'#dateservices' + index"
|
||||
class="hidden-sm hidden-md hidden-lg"><i class="fa fa-info-circle"></i></a>
|
||||
</td>
|
||||
|
||||
+10
-6
@@ -53,21 +53,25 @@
|
||||
</td>
|
||||
<td style="white-space: nowrap" :style="{'text-decoration': !row.roomAvailable && !row.isHideBookingButton ? 'line-through' : ''}">{{ calculatePrice(row) }} €</td>
|
||||
<td>
|
||||
<i v-if="showBusIcon(row)" data-placement="top" title="Busfahrt inklusive" class="fa fa-bus tooltiptoggle"></i>
|
||||
<i v-if="row.dateSkipassIncluded" data-placement="top" :title="row.season === 's' ? 'Bergbahnticket inklusive' : 'Skipass inklusive'" class="fa fa-tag tooltiptoggle"></i>
|
||||
<span v-if="showBusIcon(row)" data-microtip-position="top" aria-label="Busfahrt inklusive" role="tooltip">
|
||||
<i class="fa fa-bus"></i>
|
||||
</span>
|
||||
<span v-if="row.dateSkipassIncluded" data-microtip-position="top" :aria-label="row.season === 's' ? 'Bergbahnticket inklusive' : 'Skipass inklusive'" role="tooltip">
|
||||
<i class="fa fa-tag"></i>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button v-if="hasOptionalServices(row) && row.roomAvailable" type="button"
|
||||
class="button button--light button--small hidden-xs tooltiptoggle"
|
||||
data-toggle="modal" data-placement="top" :data-target="'#optservices' + index"
|
||||
title="Alle Zusatzleistungen anzeigen">Optionen</button>
|
||||
class="button button--light button--small hidden-xs"
|
||||
data-toggle="modal" :data-target="'#optservices' + index"
|
||||
data-microtip-position="top" aria-label="Alle Zusatzleistungen anzeigen" role="tooltip">Optionen</button>
|
||||
<a href="#" v-if="hasOptionalServices(row) && row.roomAvailable" class="hidden-sm hidden-md hidden-lg"
|
||||
data-toggle="modal" :data-target="'#optservices' + index"><i class="fa fa-info-circle"></i></a>
|
||||
<div class="modal fade" :id="'optservices' + index" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button button--small" class="close" data-dismiss="modal"><span>×</span></button>
|
||||
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
||||
<h5 class="modal-title">Optionale Zusatzleistungen</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
+3
-3
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<a href="#" @click.prevent="toggleWatchlist()">
|
||||
<i class="fa tooltiptoggle" :class="{ 'fa-minus-circle': onWatchlist, 'fa-plus-circle': !onWatchlist }"
|
||||
data-placement="auto" title="Merkliste +/-"></i>
|
||||
<span data-microtip-position="top" :aria-label="onWatchlist ? 'von der Merkliste löschen' : 'auf die Merkliste setzen'" role="tooltip">
|
||||
<i class="fa" :class="{ 'fa-minus-circle': onWatchlist, 'fa-plus-circle': !onWatchlist }"></i>
|
||||
</span>
|
||||
<span v-if="layout === 'link'">
|
||||
{{ onWatchlist ? 'von der Merkliste entfernen' : 'auf die Merkliste setzen' }}
|
||||
</span>
|
||||
@@ -9,7 +10,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import EventBus from '../_bus'
|
||||
|
||||
export default {
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { Controller } from 'stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
static targets = [ 'entry' ]
|
||||
|
||||
apply(e) {
|
||||
const query = e.target.value
|
||||
if (query.length < 3) {
|
||||
this.entryTargets.forEach(entry => {
|
||||
entry.classList.remove('hidden')
|
||||
})
|
||||
return
|
||||
}
|
||||
const pattern = new RegExp(query, 'i')
|
||||
this.entryTargets.forEach(entry => {
|
||||
const question = entry.childNodes[0].textContent
|
||||
const answer = entry.childNodes[1].textContent
|
||||
if (!question.match(pattern) && !answer.match(pattern)) {
|
||||
entry.classList.add('hidden')
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { Controller } from 'stimulus'
|
||||
import {useDebounce} from '../mixins/useDebounce'
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
static values = { show: Boolean }
|
||||
|
||||
connect() {
|
||||
useDebounce(this)
|
||||
const handler = this.debounce(() => {
|
||||
this.showValue = window.scrollY > window.innerHeight/3
|
||||
}, 250)
|
||||
window.addEventListener('scroll', handler, { passive: true })
|
||||
}
|
||||
|
||||
scroll(e) {
|
||||
e.preventDefault()
|
||||
window.scroll({ top: 0, left: 0, behavior: 'smooth' })
|
||||
}
|
||||
|
||||
showValueChanged() {
|
||||
this.element.classList.toggle('hidden', false === this.showValue)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export const useDebounce = controller => {
|
||||
Object.assign(controller, {
|
||||
debounce: (callback, interval) => {
|
||||
let debounceId
|
||||
return (...args) => {
|
||||
clearTimeout(debounceId)
|
||||
debounceId = setTimeout(() => callback.apply(this, args), interval)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -7,7 +7,7 @@ $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
|
||||
|
||||
// Reset and dependencies
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/normalize";
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/print";
|
||||
//@import "~bootstrap-sass/assets/stylesheets/bootstrap/print";
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/glyphicons";
|
||||
|
||||
// Core CSS
|
||||
@@ -44,7 +44,7 @@ $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
|
||||
|
||||
// Components w/ JavaScript
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/modals";
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/tooltip";
|
||||
//@import "~bootstrap-sass/assets/stylesheets/bootstrap/tooltip";
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/popovers";
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/carousel";
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
[data-rte-content] {
|
||||
@import "rte-content";
|
||||
}
|
||||
|
||||
@import "~microtip/microtip";
|
||||
}
|
||||
|
||||
@layer components {
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
<div class="container-fluid ep-disturber faq">
|
||||
<div>
|
||||
<div>
|
||||
<div class="container">
|
||||
<div class="container" data-controller="faq-filter">
|
||||
<span class="headline headline--3 headline--disturber">Häufig gestellte Fragen</span>
|
||||
<f:if condition="{filter}">
|
||||
<div class="faq-filter">
|
||||
<input type="text" data-faqfilter class="form-control faq-filter__field" placeholder="Suchbegriff">
|
||||
<input type="text" data-action="faq-filter#apply" class="form-control faq-filter__field" placeholder="Suchbegriff">
|
||||
</div>
|
||||
</f:if>
|
||||
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
|
||||
<f:for each="{faqs}" as="faq" iteration="iteration">
|
||||
<div class="panel panel-default" data-faq-entry>
|
||||
<div class="panel panel-default" data-faq-filter-target="entry">
|
||||
<a class="headline headline--4{f:if(condition: iteration.isFirst, else: ' collapsed')}"
|
||||
role="button" data-toggle="collapse" data-parent="#accordion" data-faq-question
|
||||
role="button" data-toggle="collapse" data-parent="#accordion"
|
||||
href="#faq-{faq.uid}" {f:if(condition: iteration.isFirst, then: 'aria-expanded="true" ')}aria-controls="faq-{faq.uid}">{faq.question}</a>
|
||||
<div id="faq-{faq.uid}" class="panel-collapse collapse{f:if(condition: iteration.isFirst, then: ' in')}" role="tabpanel" data-faq-answer>
|
||||
{faq.answer -> f:format.html()}
|
||||
|
||||
@@ -91,6 +91,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a @click.prevent="scrollTop()" v-show="scrollTopVisible" v-cloak href="#" class="arrowtop">
|
||||
<button data-controller="scroll-top" data-action="scroll-top#scroll" class="arrowtop hidden">
|
||||
<i class="fa fa-angle-up"></i>
|
||||
</a>
|
||||
</button>
|
||||
|
||||
@@ -44,8 +44,16 @@
|
||||
</f:if>
|
||||
</td>
|
||||
<td>
|
||||
<f:if condition="{row.dateBusIncluded}"><i class="fa fa-bus tooltiptoggle" data-placement="top" title="Busfahrt inklusive"></i></f:if>
|
||||
<f:if condition="{row.dateSkipassIncluded}"> <i class="fa fa-tag tooltiptoggle" data-placement="top" title="Skipass inklusive"></i></f:if>
|
||||
<f:if condition="{row.dateBusIncluded}">
|
||||
<span data-microtip-position="top" aria-label="Busfahrt inklusive" role="tooltip">
|
||||
<i class="fa fa-bus"></i>
|
||||
</span>
|
||||
</f:if>
|
||||
<f:if condition="{row.dateSkipassIncluded}">
|
||||
<span data-microtip-position="top" aria-label="Skipass inklusive" role="tooltip">
|
||||
<i class="fa fa-tag"></i>
|
||||
</span>
|
||||
</f:if>
|
||||
</td>
|
||||
<td>
|
||||
<f:if condition="{row.roomOptionalServices}">
|
||||
|
||||
Reference in New Issue
Block a user