Migrate ajax content component

This commit is contained in:
Björn Fromme
2021-07-27 14:06:11 +02:00
parent 5b2a008eda
commit 9a003dec65
6 changed files with 71 additions and 73 deletions
@@ -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>
@@ -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,
},
@@ -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>