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

319 lines
8.1 KiB
JavaScript
Raw Normal View History

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