Remove obsolete js
This commit is contained in:
@@ -56,7 +56,7 @@ class AjaxCalendarController extends ActionController
|
||||
* @param string $month
|
||||
* @param int $months
|
||||
*/
|
||||
public function rangeAction(Hotel $hotel, $year = null, $month = null, $months = 6)
|
||||
public function rangeAction(Hotel $hotel, $year = null, $month = null, $months = 1)
|
||||
{
|
||||
[ $begin, $end ] = DateUtility::getDateRange($year, $month, $months);
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ import productDetail from './components/product-detail'
|
||||
import daytripDateSelect from './components/daytrip-date-select'
|
||||
import searchBar from './components/search-bar'
|
||||
import search from './components/search'
|
||||
import calendar from './components/calendar'
|
||||
import contactForm from './components/contact-form'
|
||||
|
||||
import defaultFilterSettings from './_filtersettings'
|
||||
import defaultFilterOptions from './_filteroptions'
|
||||
@@ -63,6 +65,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
Alpine.data('daytripDateSelect', daytripDateSelect)
|
||||
Alpine.data('searchBar', searchBar)
|
||||
Alpine.data('search', search)
|
||||
Alpine.data('calendar', calendar)
|
||||
Alpine.data('contactForm', contactForm)
|
||||
Alpine.start()
|
||||
|
||||
Glightbox({
|
||||
@@ -70,64 +74,3 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
slideEffect: 'fade',
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
/// LEGACY CODE FROM HERE ///
|
||||
|
||||
// Import dependencies
|
||||
// import Vue from 'vue'
|
||||
// import $ from 'jquery'
|
||||
// import dayjs from 'dayjs'
|
||||
// import 'dayjs/locale/de'
|
||||
|
||||
// global.$ = global.jQuery = $;
|
||||
|
||||
// require('bootstrap-sass/assets/javascripts/bootstrap/dropdown')
|
||||
// require('bootstrap-sass/assets/javascripts/bootstrap/modal')
|
||||
// require('bootstrap-sass/assets/javascripts/bootstrap/transition')
|
||||
|
||||
// Import components
|
||||
// import SearchBar from './components/SearchBar.vue'
|
||||
// import SearchBox from './components/SearchBox.vue'
|
||||
//import ProductDetail from './components/ProductDetail.vue'
|
||||
// import Calendar from './components/Calendar.vue'
|
||||
// import EventPricetable from './components/EventPriceTable.vue'
|
||||
// import ContactForm from './components/ContactForm.vue'
|
||||
// import Watchlist from './components/Watchlist.vue'
|
||||
// import HotelList from './components/HotelList.vue'
|
||||
|
||||
// Define date filter for vue templates
|
||||
// Vue.filter('date', (value) => {
|
||||
// return dayjs(value).format('DD.MM.YY');
|
||||
// });
|
||||
|
||||
// Store
|
||||
// import store from './store';
|
||||
|
||||
// Initialize vue app
|
||||
// new Vue({
|
||||
// el: '#app',
|
||||
// store,
|
||||
// components: {
|
||||
// SearchBar,
|
||||
// //SearchBox,
|
||||
// //SearchResult: () => import('./components/SearchResult.vue'),
|
||||
// //ProductDetail,
|
||||
// //Calendar,
|
||||
// //EventPricetable,
|
||||
// //ContactForm,
|
||||
// //Watchlist,
|
||||
// //HotelList,
|
||||
// //MyEp: () => import('./myep/App.vue'),
|
||||
// //GroupsPriceCalculator: () => import('./components/GroupsPriceCalculator.vue'),
|
||||
// },
|
||||
// data () {
|
||||
// return {
|
||||
// maxWindowWidth: 991,
|
||||
// mobileMode: false,
|
||||
// }
|
||||
// },
|
||||
// created () {
|
||||
// this.$store.dispatch('init');
|
||||
// },
|
||||
// });
|
||||
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<div class="boardtypeselect">
|
||||
<div class="checkbox" v-for="boardType of boardTypesOptions">
|
||||
<label>
|
||||
<input type="checkbox" v-model.number="boardTypesSelected" :value="boardType.uid" @change="notifySelected">
|
||||
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
|
||||
{{ boardType.label }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
boardTypesSelected: this.boardTypes
|
||||
}
|
||||
},
|
||||
props: {
|
||||
boardTypesOptions: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
boardTypes: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
notifySelected () {
|
||||
this.$emit('selected', this.boardTypesSelected);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
boardTypes (value) {
|
||||
this.boardTypesSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,46 +0,0 @@
|
||||
<template>
|
||||
<div class="busselect">
|
||||
<template v-if="busAvailable">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" v-model="busSelected" @change="notifySelected">
|
||||
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
|
||||
Busanreise
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
nicht verfügbar
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
busSelected: this.bus
|
||||
}
|
||||
},
|
||||
props: {
|
||||
bus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
busAvailable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
notifySelected () {
|
||||
this.$emit('selected', this.busSelected);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
bus (value) {
|
||||
this.busSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,115 +0,0 @@
|
||||
<template>
|
||||
<div class="row calendar" :class="{ 'calendar--single': isSingleCalendar }">
|
||||
<div class="col-xs-12" v-if="showHeader">
|
||||
<h2>Belegungskalender {{ hotelName }}</h2>
|
||||
</div>
|
||||
<div class="calendar__loading" v-show="loading">
|
||||
<img :src="loaderUri" alt="Loading" title="Loading">
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<select class="form-control calendar__select" v-model="selectedMonth" @change="loadCalendar">
|
||||
<option v-for="option in selectableMonths" :value="option" :key="option.format('YYYY')+option.format('M')">
|
||||
{{ option.format('MMMM YYYY') }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="calendar__inner" v-cloak v-html="calendarHtml"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import axios from 'axios'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
dayjs.locale('de');
|
||||
|
||||
export default {
|
||||
props: {
|
||||
uri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
loaderUri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
argumentPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
hotelName: {
|
||||
type: String
|
||||
},
|
||||
hotelUid: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
months: {
|
||||
type: Number,
|
||||
default: 6
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
startDate: dayjs().startOf('month'),
|
||||
selectedMonth: dayjs().startOf('month'),
|
||||
calendarHtml: '',
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isSingleCalendar () {
|
||||
return parseInt(this.months) === 1;
|
||||
},
|
||||
selectableMonths() {
|
||||
const months = [];
|
||||
let month = this.startDate.month();
|
||||
let year = this.startDate.year();
|
||||
for (let i = 1; i <= 20; i++) {
|
||||
months.push(dayjs().set('year', year).set('month', month));
|
||||
if (month < 12) {
|
||||
month++;
|
||||
} else {
|
||||
month = 1;
|
||||
year++;
|
||||
}
|
||||
}
|
||||
return months;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadCalendar () {
|
||||
let query = {};
|
||||
query[this.argumentPrefix + '[hotel]'] = this.hotelUid;
|
||||
query[this.argumentPrefix + '[month]'] = this.selectedMonth.month() + 1;
|
||||
query[this.argumentPrefix + '[year]'] = this.selectedMonth.year();
|
||||
query[this.argumentPrefix + '[months]'] = this.months;
|
||||
this.loading = true;
|
||||
axios({
|
||||
url: this.uri,
|
||||
responseType: 'text',
|
||||
params: query
|
||||
}).then((response) => {
|
||||
this.calendarHtml = response.data;
|
||||
}).catch(() => {
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
Vue.nextTick(() => {
|
||||
this.loadCalendar();
|
||||
this.selectedMonth = this.selectableMonths[0];
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
<template functional>
|
||||
<div v-if="Object.keys(props.concepts).length > 1" class="hidden-xs conceptbtns">
|
||||
<a v-for="concept of props.concepts"
|
||||
:href="'#concept-' + concept.uid"
|
||||
:class="'btn btn-warning ep-sidebar concept-' + concept.code"
|
||||
:title="concept.name">{{ concept.name }}</a>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: [ 'concepts' ],
|
||||
}
|
||||
</script>
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
<template>
|
||||
<div class="conceptselect">
|
||||
<div class="checkbox" v-for="concept of conceptOptions">
|
||||
<label>
|
||||
<input type="checkbox" v-model="conceptsSelected" :value="concept.uid" @change="notifySelected">
|
||||
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
|
||||
nur {{ concept.name }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
conceptsSelected: this.concepts
|
||||
}
|
||||
},
|
||||
props: {
|
||||
conceptOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
concepts: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
notifySelected () {
|
||||
this.$emit('selected', this.conceptsSelected);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
concepts (value) {
|
||||
this.conceptsSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,47 +0,0 @@
|
||||
<script>
|
||||
import $ from 'jquery'
|
||||
import EventBus from '../_bus'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
formErrors: {},
|
||||
processing: false,
|
||||
success: false,
|
||||
error: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitForm () {
|
||||
let $form = $('#contactform');
|
||||
this.processing = true;
|
||||
$.ajax({
|
||||
url: $form.attr('action'),
|
||||
type: 'POST',
|
||||
data: $form.serialize(),
|
||||
dataType: 'json',
|
||||
success: (response) => {
|
||||
this.processing = false;
|
||||
if (response.status === 'validation') {
|
||||
this.formErrors = response.errors;
|
||||
} else {
|
||||
this.success = true;
|
||||
}
|
||||
EventBus.$emit('scrollTo', '#contactform');
|
||||
},
|
||||
error: () => {
|
||||
this.processing = false;
|
||||
this.error = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
resetForm () {
|
||||
this.formErrors = {};
|
||||
this.processing = false;
|
||||
this.success = false;
|
||||
this.error = false;
|
||||
$('#contactform').trigger('reset');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<label v-if="showLabel">Zeitraum</label>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown" ref="dropdown">
|
||||
<input type="text" class="form-control" placeholder="von... bis"
|
||||
:value="selectedRange" @click="togglePanel"/>
|
||||
<ul class="dropdown-menu daterange">
|
||||
<li v-if="presets">
|
||||
<div class="daterange__presets">
|
||||
<template v-for="preset of presets">
|
||||
<a class="daterange__preset" href="#"
|
||||
@click.prevent="selectPreset(preset)">
|
||||
<i class="fa fa-calendar"></i> <span>{{ preset.label }}</span>
|
||||
</a>
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="daterange__panel">
|
||||
<input ref="field" type="hidden">
|
||||
</div>
|
||||
</li>
|
||||
<li class="daterange__buttons">
|
||||
<button class="daterange__button" @click.prevent="togglePanel">
|
||||
<i class="fa fa-times"></i> schließen
|
||||
</button>
|
||||
<button class="daterange__button" @click.prevent="reset()">
|
||||
<i class="fa fa-trash-o"></i> zurücksetzen
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import $ from 'jquery'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
import flatpickr from 'flatpickr'
|
||||
import { German } from 'flatpickr/dist/l10n/de'
|
||||
import EventBus from '../_bus'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
picker: null,
|
||||
selectedFrom: this.from,
|
||||
selectedTo: this.to
|
||||
}
|
||||
},
|
||||
props: {
|
||||
from: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
to: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
minDate: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
maxDate: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
showLabel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
presets: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
minDate (date) {
|
||||
this.picker.set('minDate', new Date(date))
|
||||
},
|
||||
maxDate (date) {
|
||||
this.picker.set('maxDate', new Date(date))
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
Vue.nextTick(() => {
|
||||
this.picker = $(this.$refs.field).flatpickr({
|
||||
mode: 'range',
|
||||
dateFormat: 'd.m.Y',
|
||||
locale: German,
|
||||
inline: true,
|
||||
onChange: (selectedDates) => {
|
||||
if (selectedDates.length === 2) {
|
||||
this.selectedFrom = selectedDates[0];
|
||||
this.selectedTo = selectedDates[1];
|
||||
this.togglePanel();
|
||||
this.$emit('selected', { from: this.selectedFrom, to: this.selectedTo });
|
||||
}
|
||||
}
|
||||
});
|
||||
if (this.from && this.to) {
|
||||
this.picker.setDate([ new Date(this.from), new Date(this.to) ]);
|
||||
}
|
||||
if (this.minDate && this.maxDate) {
|
||||
this.picker.set('minDate', new Date(this.minDate));
|
||||
this.picker.set('maxDate', new Date(this.maxDate));
|
||||
}
|
||||
});
|
||||
EventBus.$on('filterSettingsReset', () => {
|
||||
this.reset();
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
selectedRange () {
|
||||
if (this.selectedFrom == null && this.selectedTo == null) {
|
||||
return '';
|
||||
}
|
||||
return dayjs(this.selectedFrom).format('DD.MM.YYYY')
|
||||
+ '-' + dayjs(this.selectedTo).format('DD.MM.YYYY');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
togglePanel () {
|
||||
$(this.$refs.dropdown).toggleClass('open');
|
||||
},
|
||||
selectPreset (preset) {
|
||||
this.selectedFrom = new Date(preset.dateFrom);
|
||||
this.selectedTo = new Date(preset.dateTo);
|
||||
this.picker.setDate([ this.selectedFrom, this.selectedTo ]);
|
||||
this.togglePanel();
|
||||
this.$emit('selected', { from: this.selectedFrom, to: this.selectedTo });
|
||||
},
|
||||
reset () {
|
||||
this.selectedFrom = null;
|
||||
this.selectedTo = null;
|
||||
this.picker.clear();
|
||||
this.picker.jumpToDate();
|
||||
this.togglePanel();
|
||||
this.$emit('selected', { from: this.selectedFrom, to: this.selectedTo });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
<template>
|
||||
<div class="destinationselect" :class="{ 'loading': loading }">
|
||||
<label v-if="showLabel" for="destination" class="destinationselect__label">Finde</label>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown" :class="{ open: opened }">
|
||||
<input type="text" id="destination" class="form-control destinationselect__input"
|
||||
v-model="destination"
|
||||
@keyup="autocomplete"
|
||||
@click="toggleOptions"
|
||||
placeholder="Ort, Gebiet, Land...">
|
||||
<ul ref="itemlist" class="dropdown-menu" aria-labelledby="destination" v-show="showAutocompleteOptions">
|
||||
<template v-for="(section, type) of autocompleteOptions">
|
||||
<template v-if="section.options.length">
|
||||
<li class="dropdown-header destinationselect__group" :class="type">{{ section.label }}</li>
|
||||
<li class="destinationselect__item" v-for="option of section.options">
|
||||
<a href="#" @click.prevent="optionSelect(option, type)">{{ option.name }}</a>
|
||||
</li>
|
||||
<li role="separator" class="divider destinationselect__divider"></li>
|
||||
</template>
|
||||
</template>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import $ from 'jquery'
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
ajaxUri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
argumentPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
initialFilterSettings: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
showLabel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filterSettings: this.initialFilterSettings,
|
||||
destination: '',
|
||||
destinationUid: 0,
|
||||
destinationType: '',
|
||||
autocompleteOptions: {},
|
||||
opened: false,
|
||||
loading: false,
|
||||
showAutocompleteOptions: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
autocomplete () {
|
||||
if (this.destination.length === 0) {
|
||||
this.showAutocompleteOptions = false;
|
||||
this.autocompleteOptions = {};
|
||||
this.$emit('reset');
|
||||
return;
|
||||
}
|
||||
if (this.destination.length < 3) {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
this.filterSettings.destinationName = this.destination;
|
||||
let query = {};
|
||||
query[this.argumentPrefix + '[filterSettings]'] = this.filterSettings;
|
||||
query[this.argumentPrefix + '[search]'] = this.destination;
|
||||
axios({
|
||||
url: this.ajaxUri,
|
||||
method: 'post',
|
||||
data: $.param(query)
|
||||
}).then((response) => {
|
||||
this.autocompleteOptions = response.data;
|
||||
this.showAutocompleteOptions = this.hasOptions();
|
||||
if (this.showAutocompleteOptions) {
|
||||
this.openDropdown();
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
toggleOptions () {
|
||||
if (!this.hasOptions()) {
|
||||
this.showAutocompleteOptions = false;
|
||||
return;
|
||||
}
|
||||
this.opened = !this.opened;
|
||||
},
|
||||
hasOptions () {
|
||||
let hasOptions = false;
|
||||
$.each(this.autocompleteOptions, (type, data) => {
|
||||
if (data.options.length > 0) {
|
||||
hasOptions = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return hasOptions;
|
||||
},
|
||||
openDropdown () {
|
||||
this.opened = true;
|
||||
},
|
||||
closeDropdown () {
|
||||
this.opened = false;
|
||||
},
|
||||
optionSelect (option, type) {
|
||||
this.destination = option.name;
|
||||
this.filterSettings.destinationName = this.destination;
|
||||
this.$emit('selected', { uid: option.uid, type: type, name: option.name });
|
||||
this.closeDropdown();
|
||||
},
|
||||
onFilterSettingsChange (filterSettings) {
|
||||
this.destination = filterSettings.destinationName;
|
||||
this.autocompleteOptions = {};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'initialFilterSettings': {
|
||||
deep: true,
|
||||
handler: 'onFilterSettingsChange'
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.initialFilterSettings.destinationName) {
|
||||
this.destination = this.initialFilterSettings.destinationName;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-76
@@ -1,76 +0,0 @@
|
||||
<template>
|
||||
<div class="destinationselect">
|
||||
<div class="destinationselect__section" v-for="(destination, uid) of selectableDestinations">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" v-model.number="countryUidsSelected" :value="uid" @change="notifySelected">
|
||||
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
|
||||
<strong>{{ destination.country.label }}</strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox" v-for="region of destination.regions">
|
||||
<label>
|
||||
<input type="checkbox" v-model.number="regionUidsSelected" :value="region.uid" @change="notifySelected">
|
||||
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
|
||||
<span class="small">{{ region.label }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
showRegions () {
|
||||
return this.selectableRegions !== null;
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
countryUidsSelected: this.countryUids,
|
||||
regionUidsSelected: this.regionUids
|
||||
}
|
||||
},
|
||||
props: {
|
||||
selectableDestinations: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
countryUids: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
regionUids: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
notifySelected () {
|
||||
this.$emit('selected', {
|
||||
countryUids: this.countryUidsSelected,
|
||||
regionUids: this.regionUidsSelected
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
countryUids (value) {
|
||||
this.countryUidsSelected = value;
|
||||
},
|
||||
regionUids (value) {
|
||||
this.regionUidsSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.destinationselect__section {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<div class="destinationselect">
|
||||
<label v-if="showLabel" class="destinationselect__label">Reiseziel</label>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
|
||||
aria-haspopup="true" aria-expanded="false">{{ destinationName }} <span class="glyphicon glyphicon-menu-down"></span></a>
|
||||
<ul class="dropdown-menu destination-pulldown">
|
||||
<li class="destination-pulldown__section"
|
||||
v-if="destinationOptions && !conceptSelected"
|
||||
v-for="destination of destinationOptions">
|
||||
<div class="destination-pulldown__column">
|
||||
<a href="#" @click.prevent="optionSelect(destination.country.uid, destination.country.label, 'country')">
|
||||
<img class="destination-pulldown__flag" :src="destination.country.flag" alt="">
|
||||
<strong>{{ destination.country.label }}</strong>
|
||||
</a>
|
||||
</div>
|
||||
<div class="destination-pulldown__column">
|
||||
<ul class="plain-list">
|
||||
<li v-for="region of destination.regions">
|
||||
<a href="#" @click.prevent="optionSelect(region.uid, region.label, 'region')">{{ region.label }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="destination-pulldown__section" v-if="conceptOptions && !destinationSelected">
|
||||
<div class="destination-pulldown__column"><strong>Konzept</strong></div>
|
||||
<div class="destination-pulldown__column">
|
||||
<ul class="plain-list">
|
||||
<li v-for="concept of conceptOptions">
|
||||
<a href="#" @click.prevent="conceptSelect(concept.uid, concept.name)">{{ concept.name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class="destination-pulldown__section" v-if="destinationSelected || conceptSelected">
|
||||
<button class="destination-pulldown__reset"
|
||||
@click.prevent="optionReset">
|
||||
<i class="fa fa-trash-o"></i>
|
||||
zurücksetzen
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
showLabel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
destinationOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
conceptOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
destinationName: 'beliebig',
|
||||
destinationSelected: false,
|
||||
conceptSelected: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
optionReset () {
|
||||
this.destinationName = 'beliebig';
|
||||
this.destinationSelected = false;
|
||||
this.conceptSelected = false;
|
||||
this.$emit('reset');
|
||||
},
|
||||
optionSelect (uid, name, type) {
|
||||
this.destinationName = name;
|
||||
this.destinationSelected = true;
|
||||
this.conceptSelected = false;
|
||||
this.$emit('selected', { uid: uid, type: type, name: name });
|
||||
},
|
||||
conceptSelect (uid, name) {
|
||||
this.destinationName = name;
|
||||
this.destinationSelected = false;
|
||||
this.conceptSelected = true;
|
||||
this.$emit('selected', { uid: uid, type: 'concept', name: name });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h2>Buchungsoptionen</h2>
|
||||
<div id="partnerselect" v-if="forcePartneridSelect" class="alert alert-info" :class="{ 'alert-danger': showAlert }">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<p>{{ label }}</p>
|
||||
<select v-model="partnerId" @change="onPartnerSelect">
|
||||
<option value="">Bitte auswählen...</option>
|
||||
<template v-for="partner in partnerIds">
|
||||
<option :value="partner.id">{{ partner.label }}</option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="table">
|
||||
<div class="ajax-content-wrapper" x-data="ajaxContent(uri)">
|
||||
<div class="ajax-content" x-ref="container"></div>
|
||||
<div x-ref="trigger">
|
||||
<img :src="loaderUri" alt="Loading" title="Loading">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import $ from 'jquery'
|
||||
import EventBus from '../_bus'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
uri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
loaderUri: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
forcePartneridSelect: {
|
||||
required: true
|
||||
},
|
||||
partnerIds: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
partnerId: '',
|
||||
showAlert: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onPartnerSelect () {
|
||||
if (this.partnerId) {
|
||||
this.showAlert = false;
|
||||
}
|
||||
},
|
||||
onBookingLinkClick (e) {
|
||||
e.preventDefault();
|
||||
if (!this.partnerId) {
|
||||
this.showAlert = true;
|
||||
EventBus.$emit('scrollTo', '#partnerselect');
|
||||
} else {
|
||||
this.showAlert = false;
|
||||
let $link = $(e.target);
|
||||
window.open($link.attr('href') + '&agenturcode=' + this.partnerId, '_blank');
|
||||
}
|
||||
},
|
||||
registerClickHandler () {
|
||||
const handleClickEvent = this.onBookingLinkClick;
|
||||
$(this.$refs.table).on('click', '.booking-link', function (e) {
|
||||
handleClickEvent(e);
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.forcePartneridSelect) {
|
||||
Vue.nextTick(() => {
|
||||
this.registerClickHandler();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+28
-32
@@ -114,7 +114,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import $ from 'jquery';
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
import 'flatpickr';
|
||||
@@ -172,16 +171,16 @@
|
||||
},
|
||||
formatOptionPriceType (option) {
|
||||
if (2 === option.type) {
|
||||
return ' ('+this.formatCurrency(option.price)+' pro Person)';
|
||||
return ` (${this.formatCurrency(option.price)} pro Person)`
|
||||
}
|
||||
if (3 === option.type) {
|
||||
return ' ('+this.formatCurrency(option.price)+' pro Nacht)';
|
||||
return ` (${this.formatCurrency(option.price)} pro Nacht)`
|
||||
}
|
||||
if (4 === option.type) {
|
||||
return ' ('+this.formatCurrency(option.price)+' pro Person und Nacht)';
|
||||
return ` (${this.formatCurrency(option.price)} pro Person und Nacht)`
|
||||
}
|
||||
|
||||
return ' ('+this.formatCurrency(option.price)+')';
|
||||
return ` (${this.formatCurrency(option.price)})`
|
||||
},
|
||||
initSelectableRanges () {
|
||||
let enabledDates = [];
|
||||
@@ -218,34 +217,31 @@
|
||||
for (let option of this.selectedOptions) {
|
||||
options.push(option.uid);
|
||||
}
|
||||
let formData = {
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][name]': this.name,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][email]': this.email,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][phone]': this.phone,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][remarks]': this.remarks,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][dateFrom]': this.selectedFrom.format('DD.MM.YYYY'),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][dateTo]': this.selectedTo.format('DD.MM.YYYY'),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][pax]': this.selectedPax,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][board]': this.selectedBoard ? this.selectedBoard.uid : null,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][options]': options,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary]': this.priceSummary
|
||||
};
|
||||
let formData = new FormData()
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][name]', this.name)
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][email]', this.email)
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][phone]', this.phone)
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][remarks]', this.remarks)
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][dateFrom]', this.selectedFrom.format('DD.MM.YYYY'))
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][dateTo]', this.selectedTo.format('DD.MM.YYYY'))
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][pax]', this.selectedPax)
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][board]', this.selectedBoard ? this.selectedBoard.uid : null)
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][options]', options)
|
||||
formData.set('tx_epproducts_ajax[groupsPriceInquiry][summary]', this.priceSummary)
|
||||
this.processing = true;
|
||||
this.submitted = false;
|
||||
axios({
|
||||
url: this.endpoint,
|
||||
method: 'POST',
|
||||
data: $.param(formData)
|
||||
}).then(response => {
|
||||
if ('validation' === response.data.status) {
|
||||
this.formErrors = response.data.errors;
|
||||
} else {
|
||||
this.submitted = true;
|
||||
}
|
||||
}).catch(error => {
|
||||
}).finally(() => {
|
||||
this.processing = false;
|
||||
});
|
||||
axios.post(this.endpoint, formData)
|
||||
.then(response => {
|
||||
if ('validation' === response.data.status) {
|
||||
this.formErrors = response.data.errors;
|
||||
} else {
|
||||
this.submitted = true;
|
||||
}
|
||||
})
|
||||
.catch(error => {})
|
||||
.finally(() => {
|
||||
this.processing = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -334,7 +330,7 @@
|
||||
},
|
||||
mounted () {
|
||||
Vue.nextTick(() => {
|
||||
this.picker = $(this.$refs.picker).flatpickr({
|
||||
this.picker = flatpickr(this.$refs.picker, {
|
||||
mode: 'range',
|
||||
dateFormat: 'd.m.Y',
|
||||
locale: German,
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<script>
|
||||
import defaultFilterSettings from '../_filtersettings'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
referringPageUrl: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
referringPage: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filterSettings: defaultFilterSettings
|
||||
}
|
||||
},
|
||||
created () {
|
||||
if (sessionStorage.getItem('filterSettings')) {
|
||||
this.filterSettings = JSON.parse(sessionStorage.getItem('filterSettings'));
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
<template>
|
||||
<div class="hoteltypeselect">
|
||||
<div class="checkbox" v-for="hotelTypesOption of hotelTypesOptions">
|
||||
<label>
|
||||
<input type="checkbox" v-model.number="hotelTypesSelected" :value="hotelTypesOption" @change="notifySelected">
|
||||
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
|
||||
{{ hotelTypesLabels[hotelTypesOption] }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
hotelTypesLabels: {
|
||||
1: 'Ferienwohnung',
|
||||
2: 'Sportclub',
|
||||
3: 'Appartment',
|
||||
4: 'Gästehaus',
|
||||
5: 'Pension'
|
||||
},
|
||||
hotelTypesSelected: this.hotelTypes
|
||||
}
|
||||
},
|
||||
props: {
|
||||
hotelTypesOptions: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
hotelTypes: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
notifySelected () {
|
||||
this.$emit('selected', this.hotelTypesSelected);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
hotelTypes (value) {
|
||||
this.hotelTypesSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<div class="form-group">
|
||||
<label v-if="showLabel">Dauer</label>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
{{ selectedOption }} <span class="glyphicon glyphicon-menu-down"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu nights">
|
||||
<li><a href="#" @click.prevent="optionReset">beliebig</a></li>
|
||||
<li v-for="nightsOption of nightsOptions">
|
||||
<a href="#" @click.prevent="optionSelect(nightsOption)">
|
||||
{{ durationTypes[nightsOption] }} Übernachtungen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
durationTypes: {
|
||||
4: '1 - 4',
|
||||
5: '5 oder mehr'
|
||||
},
|
||||
nightsSelected: this.nights
|
||||
}
|
||||
},
|
||||
props: {
|
||||
nightsOptions: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
nights: {
|
||||
default: 0
|
||||
},
|
||||
showLabel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectedOption () {
|
||||
if (this.nightsSelected == 0) {
|
||||
return 'beliebig';
|
||||
}
|
||||
return this.durationTypes[this.nightsSelected] + ' ÜN';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
optionReset () {
|
||||
this.nightsSelected = 0;
|
||||
this.$emit('selected', 0);
|
||||
},
|
||||
optionSelect (value) {
|
||||
this.nightsSelected = value;
|
||||
this.$emit('selected', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
nights (value) {
|
||||
this.nightsSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,56 +0,0 @@
|
||||
<template>
|
||||
<div class="form-group">
|
||||
<label v-if="showLabel">Personen</label>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
{{ pax }} <span class="glyphicon glyphicon-menu-down"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu pax">
|
||||
<li v-for="paxOption of paxOptions">
|
||||
<a href="#" @click.prevent="optionSelect(paxOption)">{{ paxOption }}</a>
|
||||
</li>
|
||||
<li v-if="groupsUri"><a :href="groupsUri">> 20</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
paxSelected: this.pax
|
||||
}
|
||||
},
|
||||
props: {
|
||||
paxOptions: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
pax: {
|
||||
default: 1
|
||||
},
|
||||
showLabel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
groupsUri: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
optionSelect (value) {
|
||||
this.paxSelected = value;
|
||||
this.$emit('selected', value);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pax (value) {
|
||||
this.paxSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
<template>
|
||||
<div class="form-group">
|
||||
<label v-if="showLabel">Preis</label>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
{{ rangeLabel }} <span class="glyphicon glyphicon-menu-down"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu price-range">
|
||||
<li><a href="#" @click.prevent="optionReset()">beliebig</a></li>
|
||||
<li v-for="(range, index) in rangeOptions">
|
||||
<a href="#" @click.prevent="optionSelect(index)">{{ formatRange(range) }} €</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
rangeSelected: this.range
|
||||
}
|
||||
},
|
||||
props: {
|
||||
rangeOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
range: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
showLabel: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rangeLabel () {
|
||||
if (this.rangeSelected === 0 || $.isEmptyObject(this.rangeOptions)) {
|
||||
return 'beliebig';
|
||||
}
|
||||
let range = this.rangeOptions[this.rangeSelected];
|
||||
return this.formatRange(range);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatRange (range) {
|
||||
let min = range[0];
|
||||
let max = range[1];
|
||||
if (min === 1) {
|
||||
return 'bis ' + max;
|
||||
}
|
||||
if (max === 999) {
|
||||
return 'ab ' + min;
|
||||
}
|
||||
return min + ' - ' + max;
|
||||
},
|
||||
optionReset () {
|
||||
this.rangeSelected = 0;
|
||||
this.$emit('selected', 0);
|
||||
},
|
||||
optionSelect (value) {
|
||||
this.rangeSelected = parseInt(value);
|
||||
this.$emit('selected', parseInt(value));
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
range (value) {
|
||||
this.rangeSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<div class="roomtypeselect">
|
||||
<div class="checkbox" v-for="roomTypesOption of roomTypesOptions">
|
||||
<label>
|
||||
<input type="checkbox" v-model.number="roomTypesSelected" :value="roomTypesOption" @change="notifySelected">
|
||||
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
|
||||
{{ roomTypesLabels[roomTypesOption] }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
roomTypesLabels: {
|
||||
1: 'EZ',
|
||||
2: 'DZ / 2er',
|
||||
3: '3er',
|
||||
4: '4er',
|
||||
5: 'ab 5 Pers.',
|
||||
6: 'mit anderen'
|
||||
},
|
||||
roomTypesSelected: this.roomTypes
|
||||
}
|
||||
},
|
||||
props: {
|
||||
roomTypesOptions: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
roomTypes: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
notifySelected () {
|
||||
this.$emit('selected', this.roomTypesSelected);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
roomTypes (value) {
|
||||
this.roomTypesSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,82 +0,0 @@
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import DaterangeSelect from './DaterangeSelect.vue'
|
||||
import DestinationSelect from './DestinationSelect.vue'
|
||||
import PaxSelect from './PaxSelect.vue'
|
||||
import PriceRangeSelect from './PriceRangeSelect.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DaterangeSelect,
|
||||
DestinationSelect,
|
||||
PaxSelect,
|
||||
PriceRangeSelect
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
searchParams: this.initialSearchParams,
|
||||
filterOptions: this.initialFilterOptions
|
||||
}
|
||||
},
|
||||
props: [ 'initialFilterOptions', 'initialSearchParams', 'optionsUri', 'resetUri', 'argumentPrefix', 'datePresets' ],
|
||||
methods: {
|
||||
loadOptions () {
|
||||
const query = {};
|
||||
query[this.argumentPrefix + '[searchParams]'] = this.searchParams;
|
||||
axios({
|
||||
url: this.optionsUri,
|
||||
method: 'post',
|
||||
data: $.param(query)
|
||||
}).then((response) => {
|
||||
this.applyOptions(response.data);
|
||||
});
|
||||
},
|
||||
applyOptions (json) {
|
||||
this.filterOptions.totalResults = json.totalResults;
|
||||
const filterOptions = json.filterOptions;
|
||||
this.filterOptions.priceRanges = filterOptions.priceRanges;
|
||||
this.filterOptions.pax = filterOptions.pax;
|
||||
this.filterOptions.destinations = filterOptions.destinations;
|
||||
if (filterOptions.dateFrom !== null) {
|
||||
this.filterOptions.selectableRangeFrom = filterOptions.dateFrom;
|
||||
}
|
||||
if (filterOptions.dateTo !== null) {
|
||||
this.filterOptions.selectableRangeTo = filterOptions.dateTo;
|
||||
}
|
||||
},
|
||||
updateDateRange (range) {
|
||||
this.searchParams.dateFrom = range.from ? dayjs(range.from).format('YYYY-MM-DD') : null;
|
||||
this.searchParams.dateTo = range.to ? dayjs(range.to).format('YYYY-MM-DD') : null;
|
||||
this.loadOptions();
|
||||
},
|
||||
updatePax (pax) {
|
||||
this.searchParams.pax = pax;
|
||||
this.loadOptions();
|
||||
},
|
||||
updatePriceRange (range) {
|
||||
this.searchParams.priceRange = range;
|
||||
this.loadOptions();
|
||||
},
|
||||
updateDestination (destination) {
|
||||
if (destination.type === 'concept') {
|
||||
this.searchParams.conceptUid = destination.uid;
|
||||
} else {
|
||||
this.searchParams.destinationUid = destination.uid;
|
||||
this.searchParams.destinationType = destination.type;
|
||||
}
|
||||
this.loadOptions();
|
||||
},
|
||||
resetDestination () {
|
||||
axios({
|
||||
url: this.resetUri,
|
||||
method: 'post'
|
||||
}).then((response) => {
|
||||
this.applyOptions(response.data);
|
||||
this.searchParams = response.data.searchParams;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,70 +0,0 @@
|
||||
<script>
|
||||
import $ from 'jquery'
|
||||
import axios from 'axios'
|
||||
import DestinationSelect from './DestinationSelect.vue'
|
||||
import PriceRangeSelect from './PriceRangeSelect.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DestinationSelect,
|
||||
PriceRangeSelect
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
searchParams: this.initialSearchParams,
|
||||
filterOptions: this.initialFilterOptions
|
||||
}
|
||||
},
|
||||
props: [ 'initialFilterOptions', 'initialSearchParams', 'optionsUri', 'resetUri', 'argumentPrefix', 'datePresets' ],
|
||||
methods: {
|
||||
loadOptions () {
|
||||
const query = {};
|
||||
query[this.argumentPrefix + '[searchParams]'] = this.searchParams;
|
||||
axios({
|
||||
url: this.optionsUri,
|
||||
method: 'post',
|
||||
data: $.param(query)
|
||||
}).then((response) => {
|
||||
this.applyOptions(response.data);
|
||||
});
|
||||
},
|
||||
applyOptions (json) {
|
||||
this.filterOptions.totalResults = json.totalResults;
|
||||
const filterOptions = json.filterOptions;
|
||||
this.filterOptions.nights = filterOptions.nights;
|
||||
this.filterOptions.destinations = filterOptions.destinations;
|
||||
if (filterOptions.dateFrom !== null) {
|
||||
this.filterOptions.selectableRangeFrom = filterOptions.dateFrom;
|
||||
}
|
||||
if (filterOptions.dateTo !== null) {
|
||||
this.filterOptions.selectableRangeTo = filterOptions.dateTo;
|
||||
}
|
||||
},
|
||||
updateOptions () {
|
||||
this.loadOptions();
|
||||
},
|
||||
updatePriceRange (range) {
|
||||
this.searchParams.priceRange = range;
|
||||
this.loadOptions();
|
||||
},
|
||||
updateDestination (destination) {
|
||||
if (destination.type === 'concept') {
|
||||
this.searchParams.conceptUid = destination.uid;
|
||||
} else {
|
||||
this.searchParams.destinationUid = destination.uid;
|
||||
this.searchParams.destinationType = destination.type;
|
||||
}
|
||||
this.loadOptions();
|
||||
},
|
||||
resetDestination () {
|
||||
axios({
|
||||
url: this.resetUri,
|
||||
method: 'post'
|
||||
}).then((response) => {
|
||||
this.applyOptions(response.data);
|
||||
this.searchParams = response.data.searchParams;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
-214
@@ -1,214 +0,0 @@
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
import $ from 'jquery'
|
||||
import axios from 'axios'
|
||||
import EventBus from '../_bus'
|
||||
import DaterangeSelect from './DaterangeSelect.vue'
|
||||
import DestinationCheckboxes from './DestinationCheckboxes.vue'
|
||||
import DestinationAutocomplete from './DestinationAutocomplete.vue'
|
||||
import ConceptSelect from './ConceptSelect.vue'
|
||||
import ConceptButtons from './ConceptButtons.vue'
|
||||
import PaxSelect from './PaxSelect.vue'
|
||||
import PriceRangeSelect from './PriceRangeSelect.vue'
|
||||
import HotelTypesSelect from './HotelTypesSelect.vue'
|
||||
import BoardTypesSelect from './BoardTypesSelect.vue'
|
||||
import RoomTypesSelect from './RoomTypesSelect.vue'
|
||||
import BusSelect from './BusSelect.vue'
|
||||
import SearchResultItem from './SearchResultItem.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
|
||||
import defaultFilterSettings from '../_filtersettings'
|
||||
import defaultFilterOptions from '../_filteroptions'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DaterangeSelect,
|
||||
DestinationCheckboxes,
|
||||
DestinationAutocomplete,
|
||||
ConceptSelect,
|
||||
ConceptButtons,
|
||||
PaxSelect,
|
||||
PriceRangeSelect,
|
||||
HotelTypesSelect,
|
||||
BoardTypesSelect,
|
||||
RoomTypesSelect,
|
||||
BusSelect,
|
||||
SearchResultItem
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
resultData: {},
|
||||
resultMeta: null,
|
||||
filterSettings: defaultFilterSettings,
|
||||
referringPageUri: null,
|
||||
filterOptions: defaultFilterOptions
|
||||
}
|
||||
},
|
||||
props: {
|
||||
resultsUri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
initialFilterSettings: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
argumentPrefix: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
datePresets: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showRegions () {
|
||||
return this.filterOptions.regions.length > 0;
|
||||
},
|
||||
resultInfo () {
|
||||
let info = '';
|
||||
if (this.loading) {
|
||||
info = 'Suchergebnis wird geladen...';
|
||||
}
|
||||
if (this.resultMeta) {
|
||||
info = 'Deine Suche ';
|
||||
if (!this.resultMeta.organic) {
|
||||
info += 'ergab leider keine genauen Treffer. Bitte benutze die Filter.';
|
||||
return info;
|
||||
}
|
||||
if (this.resultMeta.destinationName) {
|
||||
info += 'nach <b>' + this.resultMeta.destinationName + '</b> ';
|
||||
}
|
||||
if (this.resultMeta.dateRange) {
|
||||
info += '<b>' + this.resultMeta.dateRange + '</b> ';
|
||||
}
|
||||
info += 'ergab ' + this.resultMeta.total + ' Treffer';
|
||||
}
|
||||
return info;
|
||||
},
|
||||
filterCount () {
|
||||
let count = 0;
|
||||
if (this.filterSettings.destinationUid) count++;
|
||||
if (this.filterSettings.destinationName) 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.dateFrom !== null) count++;
|
||||
if (this.filterSettings.dateTo !== null) count++;
|
||||
if (this.filterSettings.priceRange > 0) count++;
|
||||
if (this.filterSettings.bus) count++;
|
||||
if (this.filterSettings.pax > 2) count++;
|
||||
return count;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadResults () {
|
||||
let query = {};
|
||||
query[this.argumentPrefix + '[filterSettings]'] = this.filterSettings;
|
||||
this.loading = true;
|
||||
this.resultMeta = null;
|
||||
axios({
|
||||
url: this.resultsUri,
|
||||
method: 'post',
|
||||
data: $.param(query)
|
||||
}).then(response => {
|
||||
this.resultData = response.data.data;
|
||||
this.filterOptions = response.data.filterOptions;
|
||||
this.referringPageUri = response.data.referringPageUri;
|
||||
this.resultMeta = response.data.meta;
|
||||
this.loading = false;
|
||||
EventBus.$emit('ajaxContentLoaded');
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
resetFilterSettings () {
|
||||
this.updateFilterSettings(defaultFilterSettings);
|
||||
EventBus.$emit('filterSettingsReset');
|
||||
},
|
||||
updateDestination (destination) {
|
||||
this.updateFilterSettings({
|
||||
destinationUid: destination.uid,
|
||||
destinationType: destination.type,
|
||||
destinationName: destination.name
|
||||
});
|
||||
this.loadResults();
|
||||
},
|
||||
updateDestinations (destinations) {
|
||||
this.updateFilterSettings({
|
||||
countryUids: destinations.countryUids,
|
||||
regionUids: destinations.regionUids
|
||||
});
|
||||
this.loadResults();
|
||||
},
|
||||
updateConcepts (conceptUids) {
|
||||
this.updateFilterSettings({ conceptUids: conceptUids });
|
||||
this.loadResults();
|
||||
},
|
||||
updateDateRange (range) {
|
||||
const dateFrom = (range.from !== null) ? dayjs(range.from).format('YYYY-MM-DD') : null;
|
||||
const dateTo = (range.to !== null) ? dayjs(range.to).format('YYYY-MM-DD') : null;
|
||||
this.updateFilterSettings({ dateFrom: dateFrom, dateTo: dateTo });
|
||||
this.loadResults();
|
||||
},
|
||||
updateDateSelectMobile () {
|
||||
let dateFrom = this.filterSettings.dateFrom;
|
||||
let dateTo = this.filterSettings.dateTo;
|
||||
if (dateFrom === '') {
|
||||
dateFrom = null;
|
||||
}
|
||||
if (dateTo === '') {
|
||||
dateTo = null;
|
||||
}
|
||||
this.updateFilterSettings({ dateFrom: dateFrom, dateTo: dateTo });
|
||||
this.loadResults();
|
||||
},
|
||||
updatePriceRange (range) {
|
||||
this.updateFilterSettings({ priceRange: range });
|
||||
this.loadResults();
|
||||
},
|
||||
updatePax (pax) {
|
||||
this.updateFilterSettings({ pax: pax });
|
||||
this.loadResults();
|
||||
},
|
||||
updateHotelTypes (hotelTypes) {
|
||||
this.updateFilterSettings({ hotelTypes: hotelTypes });
|
||||
this.loadResults();
|
||||
},
|
||||
updateBoardTypes (boardTypes) {
|
||||
this.updateFilterSettings({ boardTypes: boardTypes });
|
||||
this.loadResults();
|
||||
},
|
||||
updateRoomTypes (roomTypes) {
|
||||
this.updateFilterSettings({ roomTypes: roomTypes });
|
||||
this.loadResults();
|
||||
},
|
||||
updateBus (bus) {
|
||||
this.updateFilterSettings({ bus: bus });
|
||||
this.loadResults();
|
||||
},
|
||||
updateFilterSettings (settings) {
|
||||
this.filterSettings = { ...this.filterSettings, ...settings };
|
||||
}
|
||||
},
|
||||
created () {
|
||||
if (!$.isEmptyObject(this.initialFilterSettings)) {
|
||||
this.updateFilterSettings(this.initialFilterSettings)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
Vue.nextTick(() => {
|
||||
this.loadResults();
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
<template>
|
||||
<div class="teaserbox teaserbox--landscape teaserbox--searchresult searchresult-item">
|
||||
<div class="teaserbox__image">
|
||||
<img class="teaserbox__flag" :src="item.country.flag" :alt="item.country.name"/>
|
||||
<a :href="url" rel="nofollow" title="Details & Buchen">
|
||||
<picture class="searchresult-item__image">
|
||||
<source media="(min-width: 1201px)" :data-srcset="item.hotel.images.resized.m[0].url + ' 260w'"/>
|
||||
<source media="(max-width: 1200px)" :data-srcset="item.hotel.images.resized.l[0].url + ' 280w'"/>
|
||||
<source media="(max-width: 768px)" :data-srcset="item.hotel.images.resized.s[0].url + ' 220w'"/>
|
||||
<img class="scale lazyload" :data-src="item.hotel.images.resized.s[0].url"
|
||||
:title="item.hotel.images.resized.s[0].title"
|
||||
:alt="item.hotel.images.resized.s[0].alt">
|
||||
</picture>
|
||||
</a>
|
||||
<div class="concept-badge" :id="section.concept.code"
|
||||
:class=" 'concept-badge--' + section.concept.code">{{ section.concept.name }}</div>
|
||||
</div>
|
||||
<div class="teaserbox__main">
|
||||
<div class="teaserbox__header">
|
||||
<span class="searchresult-item__headline">
|
||||
{{ item.region.name }}
|
||||
<strong v-if="section.concept.code === 'evt'"><br>{{ item.product.name }}</strong>
|
||||
</span>
|
||||
<span class="searchresult-item__subline">{{ item.hotel.name }}</span>
|
||||
<span class="searchresult-item__category" v-if="item.hotel.category">Kategorie {{ item.hotel.category }}</span>
|
||||
</div>
|
||||
<ul class="check-list searchresult-item__checklist">
|
||||
<li v-if="item.hotel.fact">{{ item.hotel.fact }}</li>
|
||||
<li v-if="item.product.fact">{{ item.product.fact }}</li>
|
||||
<template v-if="item.region.feature">
|
||||
<li>{{ item.region.feature }}</li>
|
||||
</template>
|
||||
<template v-else>
|
||||
<li v-if="item.region.fact">{{ item.region.fact }}</li>
|
||||
</template>
|
||||
</ul>
|
||||
<ul class="check-list check-list--inverted searchresult-item__featurelist">
|
||||
<li>Skipass</li>
|
||||
<li v-if="item.board">{{ item.board }}</li>
|
||||
<li v-if="item.product.feature">{{ item.product.feature }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="teaserbox__aside">
|
||||
<div class="teaserbox__aside__top">
|
||||
<span class="searchresult-item__label">{{ item.dates.length > 1 ? 'Zeitraum' : 'Termin' }}</span>
|
||||
<span class="searchresult-item__daterange">{{ dateRange }}</span>
|
||||
<a :href="url" rel="nofollow" title="Details & Buchen"
|
||||
v-if="item.dates.length && !item.daytrip">
|
||||
<span class="searchresult-item__daterange">
|
||||
<i class="fa fa-arrow-circle-right"></i> {{ item.dates.length }} Termin{{ item.dates.length > 1 ? 'e' : '' }}
|
||||
</span>
|
||||
</a>
|
||||
<hr>
|
||||
<span class="searchresult-item__label">{{ item.daytrip ? 'Tageweise buchbar' : nightsOptions }}</span>
|
||||
</div>
|
||||
<div class="teaserbox__aside__bottom">
|
||||
<span class="searchresult-item__price">ab {{ item.minPrice }} €</span>
|
||||
<a :href="url" class="button button--full searchresult-item__button"
|
||||
rel="nofollow" title="Details">
|
||||
Details<template v-if="!item.hideBookingButton"> & Buchen</template>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" x-data="watchlistToggle(item.key))" x-bind="trigger">
|
||||
<span data-microtip-position="top" x-bind:aria-label="label" role="tooltip">
|
||||
<i class="fa fa-plus-circle" x-bind:class="icon"></i>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
section: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
referringPageUri: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
url () {
|
||||
let url = this.item.detailPageUri;
|
||||
if (this.referringPageUri) {
|
||||
url += '?ref=' + this.referringPageUri;
|
||||
}
|
||||
return url;
|
||||
},
|
||||
nightsOptions () {
|
||||
const nights = this.item.nights;
|
||||
if (nights === null) {
|
||||
return '';
|
||||
}
|
||||
nights.sort();
|
||||
const optionsCount = nights.length;
|
||||
const lastOption = nights.pop();
|
||||
let output = '';
|
||||
if (optionsCount > 2) {
|
||||
output += nights.join(',') + ' oder ' + lastOption;
|
||||
} else if (optionsCount === 2) {
|
||||
output += nights.shift() + ' oder ' + lastOption;
|
||||
} else {
|
||||
output = lastOption;
|
||||
}
|
||||
output += lastOption > 1 ? ' Nächte' : ' Nacht';
|
||||
return output;
|
||||
},
|
||||
dateRange () {
|
||||
const dateFrom = this.item.minDateStart;
|
||||
const dateTo = this.item.maxDateEnd;
|
||||
if (dateFrom === null && dateTo === null) {
|
||||
return '';
|
||||
}
|
||||
if (dateFrom !== null && dateTo === null) {
|
||||
return 'ab ' + dayjs(dateFrom).format('DD.MM.YYYY');
|
||||
}
|
||||
if (dateFrom === null && dateTo !== null) {
|
||||
return '- ' + dayjs(dateTo).format('DD.MM.YYYY');
|
||||
}
|
||||
return dayjs(dateFrom).format('DD.MM.YYYY') + ' - ' + dayjs(dateTo).format('DD.MM.YYYY');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,102 +0,0 @@
|
||||
<template>
|
||||
<div class="watchlist">
|
||||
<template v-for="section in teasers">
|
||||
<h2 class="headline headline--secondary headline--underlined">{{ section.concept.name }}</h2>
|
||||
<div class="searchresult-section" :class="'searchresult-section--' + section.concept.code">
|
||||
<search-result-item
|
||||
v-for="item in section.items"
|
||||
:key="item.key"
|
||||
:item="item"
|
||||
:section="section"
|
||||
:referring-page="referringPage"></search-result-item>
|
||||
</div>
|
||||
</template>
|
||||
<div class="alert alert-info" v-if="total === 0">
|
||||
Deine Merkliste ist aktuell leer...
|
||||
</div>
|
||||
<div v-show="loading" class="loader">
|
||||
<img :src="loaderUri" alt="Loading...">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import axios from 'axios'
|
||||
import EventBus from '../_bus'
|
||||
import SearchResultItem from './SearchResultItem.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SearchResultItem
|
||||
},
|
||||
props: {
|
||||
watchlistUri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
loaderUri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
referringPageUrl: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
teasers: {},
|
||||
total: 0,
|
||||
loading: false,
|
||||
referringPage: {
|
||||
url: this.referringPageUrl,
|
||||
label: 'zurück zur Merkliste'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadList () {
|
||||
if (this.watchlist.length === 0) {
|
||||
this.teasers = {};
|
||||
this.total = 0;
|
||||
return;
|
||||
}
|
||||
let query = {};
|
||||
query['tx_epproducts_ajax[watchlistUids]'] = this.watchlist;
|
||||
this.loading = true;
|
||||
axios({
|
||||
url: this.watchlistUri,
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
data: $.param(query),
|
||||
method: 'post'
|
||||
}).then((response) => {
|
||||
this.teasers = response.data.data;
|
||||
this.total = response.data.total;
|
||||
this.loading = false;
|
||||
EventBus.$emit('ajaxContentLoaded');
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
watchlist() {
|
||||
const initialList = JSON.parse(sessionStorage.getItem('myep-watchlist'))
|
||||
return initialList ? initialList : []
|
||||
},
|
||||
},
|
||||
created () {
|
||||
EventBus.$on('oggle', () => {
|
||||
this.loadList();
|
||||
});
|
||||
},
|
||||
mounted () {
|
||||
Vue.nextTick(() => {
|
||||
this.loadList();
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+3
-3
@@ -7,13 +7,13 @@ export default uri => ({
|
||||
loading: false,
|
||||
init() {
|
||||
window.addEventListener('scroll', debounce(() => {
|
||||
if (true === this.loaded) {
|
||||
return
|
||||
}
|
||||
this.load()
|
||||
}, 250))
|
||||
},
|
||||
load() {
|
||||
if (true === this.loaded) {
|
||||
return
|
||||
}
|
||||
if (false === this.inViewport()) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export default uri => ({
|
||||
loading: false,
|
||||
selectedIndex: null,
|
||||
selectableMonths: [],
|
||||
calendarWrapper: null,
|
||||
init() {
|
||||
this.calendarWrapper = this.$refs.calendarWrapper
|
||||
let months = []
|
||||
let today = new Date()
|
||||
let year = today.getFullYear()
|
||||
let month = today.getMonth()
|
||||
for (let i = 0; i < 20; i++) {
|
||||
months.push(new Date(year, month, 1))
|
||||
if (month < 12) {
|
||||
month++
|
||||
} else {
|
||||
month = 1
|
||||
year++
|
||||
}
|
||||
}
|
||||
this.selectableMonths = months
|
||||
this.selectedIndex = 0
|
||||
this.load()
|
||||
},
|
||||
load() {
|
||||
this.loading = true
|
||||
let selectedMonth = this.selectableMonths[this.selectedIndex]
|
||||
let data = new URLSearchParams({
|
||||
'tx_epproducts_ajax[month]': selectedMonth.getMonth(),
|
||||
'tx_epproducts_ajax[year]': selectedMonth.getYear(),
|
||||
})
|
||||
axios.post(uri, data)
|
||||
.then(response => (
|
||||
this.calendarWrapper.innerHTML = response.data
|
||||
))
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,35 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export default () => ({
|
||||
formErrors: {},
|
||||
processing: false,
|
||||
success: false,
|
||||
error: false,
|
||||
submit() {
|
||||
this.processing = true
|
||||
const form = this.$refs.form
|
||||
const data = new FormData(form)
|
||||
axios.post(form.action, data)
|
||||
.then(response => {
|
||||
if (response.data.status === 'validation') {
|
||||
this.formErrors = response.data.errors
|
||||
} else {
|
||||
this.success = true
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
this.error = true
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
this.$el.scrollIntoView({behavior: 'smooth'})
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.formErrors = {}
|
||||
this.processing = false
|
||||
this.success = false
|
||||
this.error = false
|
||||
this.$refs.form.reset()
|
||||
}
|
||||
})
|
||||
+18
-9
@@ -1,20 +1,29 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
|
||||
|
||||
<f:layout name="Default"/>
|
||||
|
||||
<f:section name="Main">
|
||||
<div class="container">
|
||||
<calendar
|
||||
uri="{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: data.tx_eptheme_context_hotel}', format: 'html')}"
|
||||
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
||||
hotel-uid="{hotel.0.data.uid}"
|
||||
hotel-name="{hotel.0.data.name}"
|
||||
argument-prefix="{ep:argumentPrefix(pluginName: 'ajax', extensionName: 'epproducts')}"
|
||||
></calendar>
|
||||
<div class="row calendar calandar--single"
|
||||
x-data='calendar("<f:format.raw>{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: data.tx_eptheme_context_hotel}', format: 'html')}</f:format.raw>")'>
|
||||
<div class="col-xs-12">
|
||||
<h2>Belegungskalender {hotel.0.data.name}</h2>
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<select class="form-control calendar__select" x-model="selectedIndex" x-on:change="load">
|
||||
<template x-for="(month, index) in selectableMonths">
|
||||
<option x-bind:value="index" x-text="month.toLocaleDateString('de-DE', {year: 'numeric', month: 'long'})"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div class="calendar__inner" x-cloak x-ref="calendarWrapper"></div>
|
||||
<div class="absolute top-0 left-0 inset-0 w-full h-full bg-overlay-white" x-show="loading">
|
||||
<f:image class="absolute top-1/2 left-1/2 -translate-xy-1/2" src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</f:section>
|
||||
|
||||
|
||||
@@ -5,104 +5,102 @@
|
||||
<f:layout name="Form/Default"/>
|
||||
|
||||
<f:section name="Main">
|
||||
<contact-form inline-template>
|
||||
<div class="relative">
|
||||
<f:form id="contactform" object="{contactForm}" name="contactForm"
|
||||
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
|
||||
pageUid="{settings.defaultAjaxUid}"
|
||||
additionalAttributes="{'v-show': '!success', '@submit.prevent': 'submitForm()'}">
|
||||
<f:form.hidden property="pageUrl"/>
|
||||
<label class="block mb-4 hidden">
|
||||
<span class="text-gray-700">Betreff*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.name }">
|
||||
<span :class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.name" v-html="formErrors.name"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.firstName }">
|
||||
<span :class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.firstName" v-html="formErrors.firstName"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.gender }">
|
||||
<span :class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
|
||||
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.gender" v-html="formErrors.gender"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.company }">
|
||||
<span :class="formErrors.company ? 'text-red-500' : 'text-gray-700'">Firma/Verein*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="company"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.company" v-html="formErrors.company"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.email }">
|
||||
<span :class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.email" v-html="formErrors.email"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.phone }">
|
||||
<span :class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.phone" v-html="formErrors.phone"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.period }">
|
||||
<span :class="formErrors.period ? 'text-red-500' : 'text-gray-700'">Zeitraum</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="period" placeholder="tt.mm.jjjj - tt.mm.jjjj"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.period" v-html="formErrors.period"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.duration }">
|
||||
<span :class="formErrors.duration ? 'text-red-500' : 'text-gray-700'">Aufenthaltsdauer</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="duration" placeholder="Tage inkl. An- & Abreisetag"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.duration" v-html="formErrors.duration"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.pax }">
|
||||
<span :class="formErrors.pax ? 'text-red-500' : 'text-gray-700'">Anzahl der Personen</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="pax" placeholder="ab 25 Personen"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.pax" v-html="formErrors.pax"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.age }">
|
||||
<span :class="formErrors.age ? 'text-red-500' : 'text-gray-700'">Durchschnittsalter</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="age"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.age" v-html="formErrors.age"></div>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
<label class="inline-flex items-center">
|
||||
<f:form.checkbox class="form-checkbox" property="children" value="Ja"/>
|
||||
<span class="ml-2">Kinder (ja/nein)</span>
|
||||
</label>
|
||||
</div>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.inquiry }">
|
||||
<span :class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
|
||||
<f:form.textarea class="form-textarea mt-1 block w-full"
|
||||
property="inquiry"
|
||||
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
|
||||
cols="30" rows="5"/>
|
||||
<div class="text-red-500 mt-2" v-show="formErrors.inquiry" v-html="formErrors.inquiry"></div>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
|
||||
title="Datenschutzerklärung"
|
||||
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<button type="submit" class="button button-warning">Jetzt anfragen</button>
|
||||
</div>
|
||||
</f:form>
|
||||
<div class="form__overlay" v-show="processing">
|
||||
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
|
||||
</div>
|
||||
<div class="form__success" v-show="success">
|
||||
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
|
||||
setzen.</p>
|
||||
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
|
||||
</div>
|
||||
<div class="form__overlay" v-show="error">
|
||||
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
|
||||
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
|
||||
</div>
|
||||
<div class="relative" x-data="contactForm">
|
||||
<f:form id="contactform" object="{contactForm}" name="contactForm"
|
||||
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
|
||||
pageUid="{settings.defaultAjaxUid}"
|
||||
additionalAttributes="{'x-ref': 'form', 'x-show': '!success', 'x-on:submit.prevent': 'submit'}">
|
||||
<f:form.hidden property="pageUrl"/>
|
||||
<label class="block mb-4 hidden">
|
||||
<span class="text-gray-700">Betreff*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.name">
|
||||
<span x-bind:class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.name" x-html="formErrors.name"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.firstName">
|
||||
<span x-bind:class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.firstName" x-html="formErrors.firstName"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.gender">
|
||||
<span x-bind:class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
|
||||
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.gender" x-html="formErrors.gender"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.company">
|
||||
<span x-bind:class="formErrors.company ? 'text-red-500' : 'text-gray-700'">Firma/Verein*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="company"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.company" x-html="formErrors.company"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.email">
|
||||
<span x-bind:class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.email" x-html="formErrors.email"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.phone">
|
||||
<span x-bind:class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.phone" x-html="formErrors.phone"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.period">
|
||||
<span x-bind:class="formErrors.period ? 'text-red-500' : 'text-gray-700'">Zeitraum</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="period" placeholder="tt.mm.jjjj - tt.mm.jjjj"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.period" x-html="formErrors.period"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.duration">
|
||||
<span x-bind:class="formErrors.duration ? 'text-red-500' : 'text-gray-700'">Aufenthaltsdauer</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="duration" placeholder="Tage inkl. An- & Abreisetag"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.duration" x-html="formErrors.duration"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.pax">
|
||||
<span x-bind:class="formErrors.pax ? 'text-red-500' : 'text-gray-700'">Anzahl der Personen</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="pax" placeholder="ab 25 Personen"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.pax" x-html="formErrors.pax"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.age">
|
||||
<span x-bind:class="formErrors.age ? 'text-red-500' : 'text-gray-700'">Durchschnittsalter</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="age"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.age" x-html="formErrors.age"></div>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
<label class="inline-flex items-center">
|
||||
<f:form.checkbox class="form-checkbox" property="children" value="Ja"/>
|
||||
<span class="ml-2">Kinder (ja/nein)</span>
|
||||
</label>
|
||||
</div>
|
||||
</contact-form>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.inquiry">
|
||||
<span x-bind:class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
|
||||
<f:form.textarea class="form-textarea mt-1 block w-full"
|
||||
property="inquiry"
|
||||
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
|
||||
cols="30" rows="5"/>
|
||||
<div class="text-red-500 mt-2" x-show="formErrors.inquiry" x-html="formErrors.inquiry"></div>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
|
||||
title="Datenschutzerklärung"
|
||||
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<button type="submit" class="button button-warning">Jetzt anfragen</button>
|
||||
</div>
|
||||
</f:form>
|
||||
<div class="form__overlay" x-show="processing">
|
||||
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
|
||||
</div>
|
||||
<div class="form__success" x-show="success">
|
||||
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
|
||||
setzen.</p>
|
||||
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
|
||||
</div>
|
||||
<div class="form__overlay" x-show="error">
|
||||
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
|
||||
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
|
||||
</div>
|
||||
</div>
|
||||
</f:section>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -5,73 +5,71 @@
|
||||
<f:layout name="Form/Default"/>
|
||||
|
||||
<f:section name="Main">
|
||||
<contact-form inline-template>
|
||||
<div class="form form--border">
|
||||
<f:form id="contactform" object="{contactForm}" name="contactForm"
|
||||
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
|
||||
pageUid="{settings.defaultAjaxUid}"
|
||||
additionalAttributes="{'v-show': '!success', '@submit.prevent': 'submitForm()'}">
|
||||
<f:form.hidden property="pageUrl"/>
|
||||
<label class="block mb-4 hidden">
|
||||
<span class="text-gray-700">Betreff*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.gender }">
|
||||
<span :class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
|
||||
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
|
||||
<div class="text-red-500" v-show="formErrors.gender" v-html="formErrors.gender"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.name }">
|
||||
<span :class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
|
||||
<div class="text-red-500" v-show="formErrors.name" v-html="formErrors.name"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.firstName }">
|
||||
<span :class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
|
||||
<div class="text-red-500" v-show="formErrors.firstName" v-html="formErrors.firstName"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.email }">
|
||||
<span :class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
|
||||
<div class="text-red-500" v-show="formErrors.email" v-html="formErrors.email"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.phone }">
|
||||
<span :class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
|
||||
<div class="text-red-500" v-show="formErrors.phone" v-html="formErrors.phone"></div>
|
||||
</label>
|
||||
<label class="block mb-4" :class="{ 'has-validation-error': formErrors.inquiry }">
|
||||
<span :class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
|
||||
<f:form.textarea class="form-textarea mt-1 block w-full"
|
||||
property="inquiry"
|
||||
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
|
||||
cols="30" rows="5"/>
|
||||
<div class="text-red-500" v-show="formErrors.inquiry" v-html="formErrors.inquiry"></div>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
|
||||
title="Datenschutzerklärung"
|
||||
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<button type="submit" class="button button-warning">Jetzt anfragen</button>
|
||||
</div>
|
||||
</f:form>
|
||||
<div class="form__overlay" v-show="processing">
|
||||
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
|
||||
</div>
|
||||
<div class="form__success" v-show="success">
|
||||
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
|
||||
setzen.</p>
|
||||
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
|
||||
</div>
|
||||
<div class="form__success" v-show="error">
|
||||
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
|
||||
<p><button class="button button-warning button-small" @click.prevent="resetForm()">Neue Anfrage</button></p>
|
||||
</div>
|
||||
<div class="form form--border" x-data="contactForm">
|
||||
<f:form id="contactform" object="{contactForm}" name="contactForm"
|
||||
action="processForm" controller="AjaxForm" pluginName="Ajax" pageType="1803"
|
||||
pageUid="{settings.defaultAjaxUid}"
|
||||
additionalAttributes="{'x-ref': 'form', 'x-show': '!success', 'x-on:submit.prevent': 'submit'}">
|
||||
<f:form.hidden property="pageUrl"/>
|
||||
<label class="block mb-4 hidden">
|
||||
<span class="text-gray-700">Betreff*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="subject"/>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.gender">
|
||||
<span x-bind:class="formErrors.gender ? 'text-red-500' : 'text-gray-700'">Gender*</span>
|
||||
<f:form.select class="form-select mt-1 block w-full" property="gender" options="{M: 'M', W: 'W', D: 'D'}"/>
|
||||
<div class="text-red-500" x-show="formErrors.gender" x-html="formErrors.gender"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.name">
|
||||
<span x-bind:class="formErrors.name ? 'text-red-500' : 'text-gray-700'">Name*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="name"/>
|
||||
<div class="text-red-500" x-show="formErrors.name" x-html="formErrors.name"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.firstName">
|
||||
<span x-bind:class="formErrors.firstName ? 'text-red-500' : 'text-gray-700'">Vorname*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="firstName"/>
|
||||
<div class="text-red-500" x-show="formErrors.firstName" x-html="formErrors.firstName"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.email">
|
||||
<span x-bind:class="formErrors.email ? 'text-red-500' : 'text-gray-700'">E-Mail*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="email"/>
|
||||
<div class="text-red-500" x-show="formErrors.email" x-html="formErrors.email"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.phone">
|
||||
<span x-bind:class="formErrors.phone ? 'text-red-500' : 'text-gray-700'">Telefon/Fax*</span>
|
||||
<f:form.textfield class="form-input mt-1 block w-full" property="phone"/>
|
||||
<div class="text-red-500" x-show="formErrors.phone" x-html="formErrors.phone"></div>
|
||||
</label>
|
||||
<label class="block mb-4" x-bind:class="'has-validation-error' && formErrors.inquiry">
|
||||
<span x-bind:class="formErrors.inquiry ? 'text-red-500' : 'text-gray-700'">(Zusatz-) Wünsche</span>
|
||||
<f:form.textarea class="form-textarea mt-1 block w-full"
|
||||
property="inquiry"
|
||||
placeholder="z. B. Reiseleiter, Halbpension, Bus Anreise, Programm"
|
||||
cols="30" rows="5"/>
|
||||
<div class="text-red-500" x-show="formErrors.inquiry" x-html="formErrors.inquiry"></div>
|
||||
</label>
|
||||
<div class="mb-4">
|
||||
Ich habe die <f:link.typolink parameter="{settings.dataProtectionPageUid}"
|
||||
title="Datenschutzerklärung"
|
||||
target="_blank">Datenschutzbestimmungen</f:link.typolink> gelesen und akzeptiert.
|
||||
</div>
|
||||
</contact-form>
|
||||
<div class="mb-4">
|
||||
<button type="submit" class="button button-warning">Jetzt anfragen</button>
|
||||
</div>
|
||||
</f:form>
|
||||
<div class="form__overlay" x-show="processing">
|
||||
<img src="{f:uri.resource(path: 'images/ajax-loader-white.gif', extensionName: 'ep_theme')}" alt="Processing...">
|
||||
</div>
|
||||
<div class="form__success" x-show="success">
|
||||
<p>Vielen Dank für Eure Anfrage. Wir werden uns schnellstmöglich mit Euch in Verbindung
|
||||
setzen.</p>
|
||||
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
|
||||
</div>
|
||||
<div class="form__success" x-show="error">
|
||||
<p>Es ist ein Problem aufgetreten. Bitte versucht es noch einmal.</p>
|
||||
<p><button class="button button-warning button-small" x-on:click.prevent="reset">Neue Anfrage</button></p>
|
||||
</div>
|
||||
</div>
|
||||
</f:section>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
<f:layout name="Default"/>
|
||||
|
||||
<f:section name="Main">
|
||||
<event-pricetable
|
||||
uri="{ep:uri.ajax(extensionName: 'epproducts', action: 'eventPricetable', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: productUid}', format: 'html')}"
|
||||
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
||||
:force-partnerid-select="{settings.forcePartnerIdSelect}"
|
||||
:partner-ids='{settings.partnerIds -> v:format.json.encode()}'
|
||||
label="{settings.partnerIdSelectLabel}"
|
||||
></event-pricetable>
|
||||
<div class="ajax-content-wrapper"
|
||||
x-data="ajaxContent('{ep:uri.ajax(extensionName: 'epproducts', action: 'eventPricetable', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: productUid}', format: 'html')}')">
|
||||
<div class="ajax-content" x-ref="container"></div>
|
||||
<div x-ref="trigger">
|
||||
<img src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}" alt="Loading" title="Loading">
|
||||
</div>
|
||||
</div>
|
||||
</f:section>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -581,24 +581,27 @@
|
||||
<f:if condition="{hotel.groupsPriceConfigs}">
|
||||
<a class="button button--full"
|
||||
data-glightbox
|
||||
data-gallery="groups-calculator"
|
||||
href="{f:uri.action(action: 'index', controller: 'GroupsPrice', arguments: '{hotel: hotel}', pageUid: settings.groupsPricePopupPageUid)}">
|
||||
Preisberechnung
|
||||
</a>
|
||||
</f:if>
|
||||
<div class="ep-sidebar ep-facts">
|
||||
<div class="ep-sidebar ep-facts relative">
|
||||
<p><strong>Belegungskalender</strong></p>
|
||||
<f:comment><!--
|
||||
<calendar
|
||||
uri="{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: product.calendarHotel}', format: 'html')}"
|
||||
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
||||
hotel-uid="{product.calendarHotel.uid}"
|
||||
hotel-name="{product.calendarHotel.name}"
|
||||
:months="1"
|
||||
:show-header="false"
|
||||
:step="1"
|
||||
argument-prefix="{ep:argumentPrefix(pluginName: 'ajax', extensionName: 'epproducts')}"
|
||||
></calendar>
|
||||
--></f:comment>
|
||||
<div class="row calendar calandar--single"
|
||||
x-data='calendar("<f:format.raw>{ep:uri.ajax(action: 'range', controller: 'AjaxCalendar', extensionName: 'epproducts', pageUid: settings.defaultAjaxUid, arguments: '{hotel: hotel}', format: 'html')}</f:format.raw>")'>
|
||||
<div class="col-xs-12">
|
||||
<select class="form-control calendar__select" x-model="selectedIndex" x-on:change="load">
|
||||
<template x-for="(month, index) in selectableMonths">
|
||||
<option x-bind:value="index" x-text="month.toLocaleDateString('de-DE', {year: 'numeric', month: 'long'})"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div class="calendar__inner" x-cloak x-ref="calendarWrapper"></div>
|
||||
<div class="absolute top-0 left-0 inset-0 w-full h-full bg-overlay-white" x-show="loading">
|
||||
<f:image class="absolute top-1/2 left-1/2 -translate-xy-1/2" src="EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif" alt="Loading"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<f:if condition="{hotel.groupsPriceConfigs}">
|
||||
<f:else>
|
||||
|
||||
+3
-1
@@ -9,11 +9,13 @@ Encore
|
||||
.addEntry('snowzone', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/snowzone.js')
|
||||
.addEntry('unichamp', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/unichamp.js')
|
||||
.addStyleEntry('rte', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/rte.scss')
|
||||
.addExternals({
|
||||
jquery: 'jQuery',
|
||||
})
|
||||
.splitEntryChunks()
|
||||
.enableSingleRuntimeChunk()
|
||||
.enableSassLoader()
|
||||
.enableVueLoader()
|
||||
.autoProvidejQuery()
|
||||
.enableVersioning()
|
||||
.enableSourceMaps(!Encore.isProduction())
|
||||
.cleanupOutputBeforeBuild()
|
||||
|
||||
Reference in New Issue
Block a user