webpack-bootstrap-ui-kit/src/js_old/_components/_ui.ajax.js

319 lines
8.0 KiB
JavaScript
Raw Normal View History

2022-05-03 20:50:57 +02:00
'use strict'
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
import $ from 'jquery'
import Events from '../_events'
import Spinner from './_ui.spinner'
2019-06-08 17:20:51 +02:00
const AjaxUI = (($) => {
// Constants
2022-05-03 20:50:57 +02:00
const G = window
const D = document
const $Html = $('html')
const $Body = $('body')
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
const NAME = 'jsAjaxUI'
const DATA_KEY = NAME
2019-06-08 17:20:51 +02:00
class AjaxUI {
// Constructor
2022-05-03 20:50:57 +02:00
constructor (element) {
this._element = element
const $element = $(this._element)
$element.addClass(`${NAME}-active`)
$element.bind('click', function (e) {
e.preventDefault()
const $this = $(this)
$('.ajax').each(function () {
const $this = $(this)
$this.removeClass('active')
$this.parents('.nav-item').removeClass('active')
})
$this.addClass('loading')
AjaxUI.load($this.attr('href'), () => {
$this.removeClass('loading')
$this.parents('.nav-item').addClass('active')
$this.addClass('active')
})
})
2019-06-08 17:20:51 +02:00
}
// Public methods
2022-05-03 20:50:57 +02:00
static load (url, callback) {
2019-06-08 17:20:51 +02:00
// show spinner
Spinner.show(() => {
2022-05-03 20:50:57 +02:00
$Body.removeClass('loaded')
})
2019-06-08 17:20:51 +02:00
// update document location
2022-05-03 20:50:57 +02:00
G.MainUI.updateLocation(url)
2019-06-08 17:20:51 +02:00
const absoluteLocation =
2022-05-03 20:50:57 +02:00
G.URLDetails.base + G.URLDetails.relative.substring(1)
2019-06-08 17:20:51 +02:00
if (absoluteLocation !== G.location.href) {
G.history.pushState(
{
ajax: true,
page: absoluteLocation,
},
document.title,
2021-08-18 20:51:15 +02:00
absoluteLocation
2022-05-03 20:50:57 +02:00
)
2019-06-08 17:20:51 +02:00
}
$.ajax({
sync: false,
async: true,
url,
2022-05-03 20:50:57 +02:00
dataType: 'json',
method: 'GET',
2019-06-08 17:20:51 +02:00
cache: false,
2022-05-03 20:50:57 +02:00
error (jqXHR) {
console.warn(`${NAME}: AJAX request failure: ${jqXHR.statusText}`)
G.location.href = url
2019-06-08 17:20:51 +02:00
// google analytics
2022-05-03 20:50:57 +02:00
if (typeof G.ga === 'function') {
G.ga('send', 'event', 'error', 'AJAX ERROR', jqXHR.statusText)
2019-06-08 17:20:51 +02:00
}
},
2022-05-03 20:50:57 +02:00
success (data, status, jqXHR) {
AjaxUI.process(data, jqXHR, callback)
2019-06-08 17:20:51 +02:00
// google analytics
2022-05-03 20:50:57 +02:00
if (typeof G.ga === 'function') {
G.ga('set', {
page: G.URLDetails.relative + G.URLDetails.hash,
title: jqXHR.getResponseHeader('X-Title'),
})
G.ga('send', 'pageview')
2019-06-08 17:20:51 +02:00
}
},
2022-05-03 20:50:57 +02:00
})
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
static process (data, jqXHR, callback) {
const css = jqXHR.getResponseHeader('X-Include-CSS').split(',') || []
const js = jqXHR.getResponseHeader('X-Include-JS').split(',') || []
2019-06-08 17:20:51 +02:00
// Replace HTML regions
2022-05-03 20:50:57 +02:00
if (typeof data.regions === 'object') {
2019-06-08 17:20:51 +02:00
for (const key in data.regions) {
2022-05-03 20:50:57 +02:00
if (typeof data.regions[key] === 'string') {
AjaxUI.replaceRegion(data.regions[key], key)
2019-06-08 17:20:51 +02:00
}
}
}
// remove already loaded scripts
$('link[type="text/css"]').each(function () {
2022-05-03 20:50:57 +02:00
const i = css.indexOf($(this).attr('href'))
2019-06-08 17:20:51 +02:00
if (i > -1) {
2022-05-03 20:50:57 +02:00
css.splice(i, 1)
} else if (!$Body.data('unload-blocked')) {
console.log(`${NAME}: Unloading | ${$(this).attr('href')}`)
$(this).remove()
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
})
2019-06-08 17:20:51 +02:00
$('script[type="text/javascript"]').each(function () {
2022-05-03 20:50:57 +02:00
const i = js.indexOf($(this).attr('src'))
2019-06-08 17:20:51 +02:00
if (i > -1) {
2022-05-03 20:50:57 +02:00
js.splice(i, 1)
} else if (!$Body.data('unload-blocked')) {
console.log(`${NAME}: Unloading | ${$(this).attr('src')}`)
$(this).remove()
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
})
2019-06-08 17:20:51 +02:00
// preload CSS
this.preload(css).then(() => {
2022-05-03 20:50:57 +02:00
const $head = $('head')
2019-06-08 17:20:51 +02:00
css.forEach((el) => {
$head.append(
2021-08-18 20:51:15 +02:00
`<link rel="stylesheet" type="text/css" href="${el}" />`
2022-05-03 20:50:57 +02:00
)
})
2019-06-08 17:20:51 +02:00
// preload JS
2022-05-03 20:50:57 +02:00
this.preload(js, 'script').then(() => {
2019-06-08 17:20:51 +02:00
js.forEach((el) => {
$Body.append(
2021-08-18 20:51:15 +02:00
`<script type="text/javascript" charset="UTF-8" src="${el}"></script>`
2022-05-03 20:50:57 +02:00
)
})
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
console.log(`${NAME}: New page is loaded!`)
2019-06-08 17:20:51 +02:00
// trigger events
2022-05-03 20:50:57 +02:00
if (typeof data.events === 'object') {
2019-06-08 17:20:51 +02:00
for (const eventName in data.events) {
2022-05-03 20:50:57 +02:00
$(D).trigger(eventName, [data.events[eventName]])
2019-06-08 17:20:51 +02:00
}
}
2022-05-03 20:50:57 +02:00
if (typeof callback !== 'undefined') {
callback()
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
$(G).trigger(Events.AJAX)
})
})
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
static preload (items, type = 'text', cache = true, itemCallback = false) {
2019-06-08 17:20:51 +02:00
if (!items.length) {
2022-05-03 20:50:57 +02:00
return $.Deferred().resolve().promise()
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
const dfds = []
2019-06-08 17:20:51 +02:00
items.forEach((url, i) => {
2022-05-03 20:50:57 +02:00
const dfd = $.Deferred()
2019-06-08 17:20:51 +02:00
$.ajax({
dataType: type,
cache,
url,
}).always(() => {
2022-05-03 20:50:57 +02:00
dfd.resolve()
2019-06-08 17:20:51 +02:00
if (itemCallback) {
2022-05-03 20:50:57 +02:00
itemCallback(i, url)
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
})
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
dfds.push(dfd)
})
2019-06-08 17:20:51 +02:00
// return a master promise object which will resolve when all the deferred objects have resolved
2022-05-03 20:50:57 +02:00
return $.when(...dfds)
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
static replaceRegion (html, key) {
const $region = $(`[data-ajax-region="${key}"]`)
2019-06-08 17:20:51 +02:00
if ($region.length) {
2022-05-03 20:50:57 +02:00
$region.empty().append(html)
2019-06-08 17:20:51 +02:00
} else {
2022-05-03 20:50:57 +02:00
console.warn(`${NAME}: Region returned without class or id!`)
2019-06-08 17:20:51 +02:00
}
}
2022-05-03 20:50:57 +02:00
dispose () {
const $element = $(this._element)
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
$element.removeClass(`${NAME}-active`)
$.removeData(this._element, DATA_KEY)
this._element = null
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
static _jQueryInterface () {
return this.each(function () {
2019-06-08 17:20:51 +02:00
// attach functionality to element
2022-05-03 20:50:57 +02:00
const $element = $(this)
let data = $element.data(DATA_KEY)
2019-06-08 17:20:51 +02:00
if (!data) {
2022-05-03 20:50:57 +02:00
data = new AjaxUI(this)
$element.data(DATA_KEY, data)
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
})
2019-06-08 17:20:51 +02:00
}
}
// jQuery interface
2022-05-03 20:50:57 +02:00
$.fn[NAME] = AjaxUI._jQueryInterface
$.fn[NAME].Constructor = AjaxUI
$.fn[NAME].noConflict = function () {
2022-05-03 20:50:57 +02:00
$.fn[NAME] = JQUERY_NO_CONFLICT
return AjaxUI._jQueryInterface
}
2019-06-08 17:20:51 +02:00
// auto-apply
2022-05-03 20:50:57 +02:00
$('.ajax').ready(() => {
$('.ajax').jsAjaxUI()
})
2019-06-08 17:20:51 +02:00
// AJAX update browser title
2022-05-03 20:50:57 +02:00
$(D).on('layoutRefresh', (e, data) => {
D.title = data.Title
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
$Html.attr('class', '')
2019-06-08 17:20:51 +02:00
if (data.ClassName) {
2022-05-03 20:50:57 +02:00
$Html.addClass(data.ClassName)
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
// data.Link = (data.Link === '/home/') ? '/' : data.Link;
})
2019-06-08 17:20:51 +02:00
// Back/Forward functionality
G.onpopstate = function (event) {
2022-05-03 20:50:57 +02:00
const $existingLink = $(`a[href^="${D.location}"]`)
2019-06-08 17:20:51 +02:00
if (event.state !== null && event.state.ajax) {
2022-05-03 20:50:57 +02:00
console.log(`${NAME}: GOBACK (AJAX state)`)
AjaxUI.load(event.state.page)
} else if ($existingLink.length && $existingLink.hasClass('ajax')) {
console.log(`${NAME}: GOBACK (AJAX link)`)
$existingLink.trigger('click')
2020-11-24 08:01:12 +01:00
} else if (D.location.href !== G.location.href) {
2022-05-03 20:50:57 +02:00
console.log(`${NAME}: GOBACK (HTTP)`)
G.location.href = D.location
2019-06-08 17:20:51 +02:00
}
2022-05-03 20:50:57 +02:00
}
2019-06-08 17:20:51 +02:00
// manage AJAX requests
$.ajaxPrefilter((options, originalOptions, jqXHR) => {
2022-05-03 20:50:57 +02:00
jqXHR.opts = options
$.xhrPool.requests[jqXHR.opts.url] = jqXHR
})
$.xhrPool = {
requests: {},
paused: false,
pauseAll: () => {
2022-05-03 20:50:57 +02:00
$.xhrPool.paused = true
2022-05-03 20:50:57 +02:00
/* for (let url in $.xhrPool.requests) {
const jqXHR = $.xhrPool.requests[url];
jqXHR.abort();
2020-09-09 17:40:58 +02:00
console.log(`${NAME}: AJAX request is paused (${jqXHR.opts.url})`);
2022-05-03 20:50:57 +02:00
} */
},
restoreAll: () => {
2020-08-04 00:19:32 +02:00
for (const url in $.xhrPool.requests) {
2022-05-03 20:50:57 +02:00
const jqXHR = $.xhrPool.requests[url]
$.ajax(jqXHR.opts)
console.log(`${NAME}: AJAX request is restored (${jqXHR.opts.url})`)
}
2022-05-03 20:50:57 +02:00
$.xhrPool.paused = false
},
2022-05-03 20:50:57 +02:00
}
$.ajaxSetup({
beforeSend: (jqXHR) => {}, // and connection to list
complete: (jqXHR) => {
if (!$.xhrPool.paused) {
2022-05-03 20:50:57 +02:00
// console.log(`${NAME}: AJAX request is done (${jqXHR.opts.url})`);
delete $.xhrPool.requests[jqXHR.opts.url]
}
},
2022-05-03 20:50:57 +02:00
})
// attach events
$Body.on(`${Events.OFFLINE}`, () => {
2022-05-03 20:50:57 +02:00
$.xhrPool.pauseAll()
})
2020-09-10 21:48:14 +02:00
$Body.on(`${Events.BACKONLINE}`, () => {
2022-05-03 20:50:57 +02:00
$.xhrPool.restoreAll()
})
2022-05-03 20:50:57 +02:00
return AjaxUI
})($)
2019-06-08 17:20:51 +02:00
2022-05-03 20:50:57 +02:00
export default AjaxUI