Migrate ajax content component
This commit is contained in:
@@ -77,7 +77,6 @@ import EventBus from './_bus'
|
||||
import SearchBar from './components/SearchBar.vue'
|
||||
import SearchBox from './components/SearchBox.vue'
|
||||
import ProductDetail from './components/ProductDetail.vue'
|
||||
import AjaxContent from './components/AjaxContent.vue'
|
||||
import OsmMap from './components/OsmMap.vue'
|
||||
import Calendar from './components/Calendar.vue'
|
||||
import EventPricetable from './components/EventPriceTable.vue'
|
||||
@@ -108,7 +107,6 @@ new Vue({
|
||||
SearchBox,
|
||||
SearchResult: () => import('./components/SearchResult.vue'),
|
||||
ProductDetail,
|
||||
AjaxContent,
|
||||
OsmMap,
|
||||
Calendar,
|
||||
EventPricetable,
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div class="ajax-content-wrapper">
|
||||
<div class="ajax-content" v-html="html"></div>
|
||||
<div :class="{ 'loading': loading }" v-cloak ref="trigger">
|
||||
<img :src="loaderUri" alt="Loading" title="Loading" v-show="loading" v-if="loaderUri">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import $ from 'jquery'
|
||||
import axios from 'axios'
|
||||
import EventBus from '../_bus'
|
||||
const $window = $(window);
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
loading: true,
|
||||
loaded: false,
|
||||
html: ''
|
||||
}
|
||||
},
|
||||
props: [ 'uri', 'loaderUri' ],
|
||||
methods: {
|
||||
loadContent () {
|
||||
axios({
|
||||
url: this.uri,
|
||||
responseType: 'text'
|
||||
}).then((response) => {
|
||||
this.loading = false;
|
||||
this.html = response.data;
|
||||
$(this.$refs.trigger).remove();
|
||||
EventBus.$emit('ajaxContentLoaded');
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
isInViewport ($triggerElement) {
|
||||
let elementTop = $triggerElement.offset().top;
|
||||
let elementBottom = elementTop + $triggerElement.outerHeight();
|
||||
let viewportTop = $window.scrollTop();
|
||||
let viewportBottom = viewportTop + $window.height();
|
||||
return elementBottom > viewportTop && elementTop < viewportBottom;
|
||||
},
|
||||
initContent ($triggerElement) {
|
||||
if (!this.loaded && this.isInViewport($triggerElement)) {
|
||||
this.loaded = true;
|
||||
this.loadContent();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
const $triggerElement = $(this.$refs.trigger);
|
||||
this.initContent($triggerElement);
|
||||
$window.on('scroll', () => {
|
||||
this.initContent($triggerElement);
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+6
-5
@@ -16,7 +16,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div ref="table">
|
||||
<ajax-content :uri="uri" :loader-uri="loaderUri"></ajax-content>
|
||||
<div class="ajax-content-wrapper" data-controller="ajax-content" :data-ajax-content-uri-value="uri">
|
||||
<div class="ajax-content" data-ajax-content-target="container"></div>
|
||||
<div data-ajax-content-target="trigger">
|
||||
<img :src="loaderUri" alt="Loading" title="Loading">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,13 +29,9 @@
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import $ from 'jquery'
|
||||
import AjaxContent from './AjaxContent.vue'
|
||||
import EventBus from '../_bus'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AjaxContent
|
||||
},
|
||||
props: {
|
||||
uri: {
|
||||
type: String,
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
import ServicesOptional from './ServicesListOptional.vue'
|
||||
import DateSelect from './DateSelect.vue'
|
||||
import DaterangeSelect from './DaterangeSelect.vue'
|
||||
import AjaxContent from './AjaxContent.vue'
|
||||
import Calendar from './Calendar.vue'
|
||||
import OsmMap from './OsmMap.vue'
|
||||
import dayjs from 'dayjs'
|
||||
@@ -23,7 +22,6 @@
|
||||
ServicesOptional,
|
||||
DateSelect,
|
||||
DaterangeSelect,
|
||||
AjaxContent,
|
||||
Calendar,
|
||||
OsmMap,
|
||||
},
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
import { Controller } from 'stimulus'
|
||||
import { useDebounce } from '../mixins/useDebounce'
|
||||
import axios from 'axios'
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
static targets = [ 'trigger', 'container' ]
|
||||
static values = {
|
||||
uri: String,
|
||||
loaded: Boolean,
|
||||
loading: Boolean
|
||||
}
|
||||
|
||||
connect() {
|
||||
useDebounce(this)
|
||||
window.addEventListener('scroll', this.debounce(() => {
|
||||
this.loadContent()
|
||||
}, 250))
|
||||
}
|
||||
|
||||
loadContent () {
|
||||
if (true === this.loadedValue || false === this.isInViewport()) {
|
||||
return
|
||||
}
|
||||
|
||||
this.loadingValue = true
|
||||
axios({
|
||||
url: this.uriValue,
|
||||
responseType: 'text'
|
||||
}).then((response) => {
|
||||
this.loadingValue = false
|
||||
this.loadedValue = true
|
||||
this.containerTarget.innerHTML = response.data
|
||||
this.triggerTarget.remove()
|
||||
}).catch(() => {
|
||||
this.loadingValue = false
|
||||
this.loadedValue = false
|
||||
})
|
||||
}
|
||||
|
||||
isInViewport () {
|
||||
const rect = this.triggerTarget.getBoundingClientRect()
|
||||
|
||||
return (
|
||||
rect.top >= 0 &&
|
||||
rect.left >= 0 &&
|
||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
||||
);
|
||||
}
|
||||
|
||||
loadingValueChanged () {
|
||||
if (false === this.loadedValue) {
|
||||
this.triggerTarget.classList.toggle('loading', this.loadingValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,14 @@
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h2>Buchungsoptionen</h2>
|
||||
<ajax-content
|
||||
uri="{ep:uri.ajax(action: 'pricetableHtml', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: product, hotel: hotel}', format: 'html')}"
|
||||
loader-uri="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}"
|
||||
></ajax-content>
|
||||
<div class="ajax-content-wrapper"
|
||||
data-controller="ajax-content"
|
||||
data-ajax-content-uri-value="{ep:uri.ajax(action: 'pricetableHtml', controller: 'AjaxTable', pageUid: settings.defaultAjaxUid, arguments: '{product: product, hotel: hotel}', format: 'html')}">
|
||||
<div class="ajax-content" data-ajax-content-target="container"></div>
|
||||
<div data-ajax-content-target="trigger">
|
||||
<img src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/ajax-loader-white.gif')}" alt="Loading" title="Loading">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
Reference in New Issue
Block a user