otsdaq_utilities  v2_05_02_indev
ajax.js
1 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2 
3 /* Tabulator v4.5.3 (c) Oliver Folkerd */
4 
5 var Ajax = function Ajax(table) {
6 
7  this.table = table; //hold Tabulator object
8  this.config = false; //hold config object for ajax request
9  this.url = ""; //request URL
10  this.urlGenerator = false;
11  this.params = false; //request parameters
12 
13  this.loaderElement = this.createLoaderElement(); //loader message div
14  this.msgElement = this.createMsgElement(); //message element
15  this.loadingElement = false;
16  this.errorElement = false;
17  this.loaderPromise = false;
18 
19  this.progressiveLoad = false;
20  this.loading = false;
21 
22  this.requestOrder = 0; //prevent requests comming out of sequence if overridden by another load request
23 };
24 
25 //initialize setup options
26 Ajax.prototype.initialize = function () {
27  var template;
28 
29  this.loaderElement.appendChild(this.msgElement);
30 
31  if (this.table.options.ajaxLoaderLoading) {
32  if (typeof this.table.options.ajaxLoaderLoading == "string") {
33  template = document.createElement('template');
34  template.innerHTML = this.table.options.ajaxLoaderLoading.trim();
35  this.loadingElement = template.content.firstChild;
36  } else {
37  this.loadingElement = this.table.options.ajaxLoaderLoading;
38  }
39  }
40 
41  this.loaderPromise = this.table.options.ajaxRequestFunc || this.defaultLoaderPromise;
42 
43  this.urlGenerator = this.table.options.ajaxURLGenerator || this.defaultURLGenerator;
44 
45  if (this.table.options.ajaxLoaderError) {
46  if (typeof this.table.options.ajaxLoaderError == "string") {
47  template = document.createElement('template');
48  template.innerHTML = this.table.options.ajaxLoaderError.trim();
49  this.errorElement = template.content.firstChild;
50  } else {
51  this.errorElement = this.table.options.ajaxLoaderError;
52  }
53  }
54 
55  if (this.table.options.ajaxParams) {
56  this.setParams(this.table.options.ajaxParams);
57  }
58 
59  if (this.table.options.ajaxConfig) {
60  this.setConfig(this.table.options.ajaxConfig);
61  }
62 
63  if (this.table.options.ajaxURL) {
64  this.setUrl(this.table.options.ajaxURL);
65  }
66 
67  if (this.table.options.ajaxProgressiveLoad) {
68  if (this.table.options.pagination) {
69  this.progressiveLoad = false;
70  console.error("Progressive Load Error - Pagination and progressive load cannot be used at the same time");
71  } else {
72  if (this.table.modExists("page")) {
73  this.progressiveLoad = this.table.options.ajaxProgressiveLoad;
74  this.table.modules.page.initializeProgressive(this.progressiveLoad);
75  } else {
76  console.error("Pagination plugin is required for progressive ajax loading");
77  }
78  }
79  }
80 };
81 
82 Ajax.prototype.createLoaderElement = function () {
83  var el = document.createElement("div");
84  el.classList.add("tabulator-loader");
85  return el;
86 };
87 
88 Ajax.prototype.createMsgElement = function () {
89  var el = document.createElement("div");
90 
91  el.classList.add("tabulator-loader-msg");
92  el.setAttribute("role", "alert");
93 
94  return el;
95 };
96 
97 //set ajax params
98 Ajax.prototype.setParams = function (params, update) {
99  if (update) {
100  this.params = this.params || {};
101 
102  for (var key in params) {
103  this.params[key] = params[key];
104  }
105  } else {
106  this.params = params;
107  }
108 };
109 
110 Ajax.prototype.getParams = function () {
111  return this.params || {};
112 };
113 
114 //load config object
115 Ajax.prototype.setConfig = function (config) {
116  this._loadDefaultConfig();
117 
118  if (typeof config == "string") {
119  this.config.method = config;
120  } else {
121  for (var key in config) {
122  this.config[key] = config[key];
123  }
124  }
125 };
126 
127 //create config object from default
128 Ajax.prototype._loadDefaultConfig = function (force) {
129  var self = this;
130  if (!self.config || force) {
131 
132  self.config = {};
133 
134  //load base config from defaults
135  for (var key in self.defaultConfig) {
136  self.config[key] = self.defaultConfig[key];
137  }
138  }
139 };
140 
141 //set request url
142 Ajax.prototype.setUrl = function (url) {
143  this.url = url;
144 };
145 
146 //get request url
147 Ajax.prototype.getUrl = function () {
148  return this.url;
149 };
150 
151 //lstandard loading function
152 Ajax.prototype.loadData = function (inPosition) {
153  var self = this;
154 
155  if (this.progressiveLoad) {
156  return this._loadDataProgressive();
157  } else {
158  return this._loadDataStandard(inPosition);
159  }
160 };
161 
162 Ajax.prototype.nextPage = function (diff) {
163  var margin;
164 
165  if (!this.loading) {
166 
167  margin = this.table.options.ajaxProgressiveLoadScrollMargin || this.table.rowManager.getElement().clientHeight * 2;
168 
169  if (diff < margin) {
170  this.table.modules.page.nextPage().then(function () {}).catch(function () {});
171  }
172  }
173 };
174 
175 Ajax.prototype.blockActiveRequest = function () {
176  this.requestOrder++;
177 };
178 
179 Ajax.prototype._loadDataProgressive = function () {
180  this.table.rowManager.setData([]);
181  return this.table.modules.page.setPage(1);
182 };
183 
184 Ajax.prototype._loadDataStandard = function (inPosition) {
185  var _this = this;
186 
187  return new Promise(function (resolve, reject) {
188  _this.sendRequest(inPosition).then(function (data) {
189  _this.table.rowManager.setData(data, inPosition).then(function () {
190  resolve();
191  }).catch(function (e) {
192  reject(e);
193  });
194  }).catch(function (e) {
195  reject(e);
196  });
197  });
198 };
199 
200 Ajax.prototype.generateParamsList = function (data, prefix) {
201  var self = this,
202  output = [];
203 
204  prefix = prefix || "";
205 
206  if (Array.isArray(data)) {
207  data.forEach(function (item, i) {
208  output = output.concat(self.generateParamsList(item, prefix ? prefix + "[" + i + "]" : i));
209  });
210  } else if ((typeof data === "undefined" ? "undefined" : _typeof(data)) === "object") {
211  for (var key in data) {
212  output = output.concat(self.generateParamsList(data[key], prefix ? prefix + "[" + key + "]" : key));
213  }
214  } else {
215  output.push({ key: prefix, value: data });
216  }
217 
218  return output;
219 };
220 
221 Ajax.prototype.serializeParams = function (params) {
222  var output = this.generateParamsList(params),
223  encoded = [];
224 
225  output.forEach(function (item) {
226  encoded.push(encodeURIComponent(item.key) + "=" + encodeURIComponent(item.value));
227  });
228 
229  return encoded.join("&");
230 };
231 
232 //send ajax request
233 Ajax.prototype.sendRequest = function (silent) {
234  var _this2 = this;
235 
236  var self = this,
237  url = self.url,
238  requestNo,
239  esc,
240  query;
241 
242  self.requestOrder++;
243  requestNo = self.requestOrder;
244 
245  self._loadDefaultConfig();
246 
247  return new Promise(function (resolve, reject) {
248  if (self.table.options.ajaxRequesting.call(_this2.table, self.url, self.params) !== false) {
249 
250  self.loading = true;
251 
252  if (!silent) {
253  self.showLoader();
254  }
255 
256  _this2.loaderPromise(url, self.config, self.params).then(function (data) {
257  if (requestNo === self.requestOrder) {
258  if (self.table.options.ajaxResponse) {
259  data = self.table.options.ajaxResponse.call(self.table, self.url, self.params, data);
260  }
261  resolve(data);
262  } else {
263  console.warn("Ajax Response Blocked - An active ajax request was blocked by an attempt to change table data while the request was being made");
264  }
265 
266  self.hideLoader();
267 
268  self.loading = false;
269  }).catch(function (error) {
270  console.error("Ajax Load Error: ", error);
271  self.table.options.ajaxError.call(self.table, error);
272 
273  self.showError();
274 
275  setTimeout(function () {
276  self.hideLoader();
277  }, 3000);
278 
279  self.loading = false;
280 
281  reject();
282  });
283  } else {
284  reject();
285  }
286  });
287 };
288 
289 Ajax.prototype.showLoader = function () {
290  var shouldLoad = typeof this.table.options.ajaxLoader === "function" ? this.table.options.ajaxLoader() : this.table.options.ajaxLoader;
291 
292  if (shouldLoad) {
293 
294  this.hideLoader();
295 
296  while (this.msgElement.firstChild) {
297  this.msgElement.removeChild(this.msgElement.firstChild);
298  }this.msgElement.classList.remove("tabulator-error");
299  this.msgElement.classList.add("tabulator-loading");
300 
301  if (this.loadingElement) {
302  this.msgElement.appendChild(this.loadingElement);
303  } else {
304  this.msgElement.innerHTML = this.table.modules.localize.getText("ajax|loading");
305  }
306 
307  this.table.element.appendChild(this.loaderElement);
308  }
309 };
310 
311 Ajax.prototype.showError = function () {
312  this.hideLoader();
313 
314  while (this.msgElement.firstChild) {
315  this.msgElement.removeChild(this.msgElement.firstChild);
316  }this.msgElement.classList.remove("tabulator-loading");
317  this.msgElement.classList.add("tabulator-error");
318 
319  if (this.errorElement) {
320  this.msgElement.appendChild(this.errorElement);
321  } else {
322  this.msgElement.innerHTML = this.table.modules.localize.getText("ajax|error");
323  }
324 
325  this.table.element.appendChild(this.loaderElement);
326 };
327 
328 Ajax.prototype.hideLoader = function () {
329  if (this.loaderElement.parentNode) {
330  this.loaderElement.parentNode.removeChild(this.loaderElement);
331  }
332 };
333 
334 //default ajax config object
335 Ajax.prototype.defaultConfig = {
336  method: "GET"
337 };
338 
339 Ajax.prototype.defaultURLGenerator = function (url, config, params) {
340 
341  if (url) {
342  if (params && Object.keys(params).length) {
343  if (!config.method || config.method.toLowerCase() == "get") {
344  config.method = "get";
345 
346  url += (url.includes("?") ? "&" : "?") + this.serializeParams(params);
347  }
348  }
349  }
350 
351  return url;
352 };
353 
354 Ajax.prototype.defaultLoaderPromise = function (url, config, params) {
355  var self = this,
356  contentType;
357 
358  return new Promise(function (resolve, reject) {
359 
360  //set url
361  url = self.urlGenerator(url, config, params);
362 
363  //set body content if not GET request
364  if (config.method.toUpperCase() != "GET") {
365  contentType = _typeof(self.table.options.ajaxContentType) === "object" ? self.table.options.ajaxContentType : self.contentTypeFormatters[self.table.options.ajaxContentType];
366  if (contentType) {
367 
368  for (var key in contentType.headers) {
369  if (!config.headers) {
370  config.headers = {};
371  }
372 
373  if (typeof config.headers[key] === "undefined") {
374  config.headers[key] = contentType.headers[key];
375  }
376  }
377 
378  config.body = contentType.body.call(self, url, config, params);
379  } else {
380  console.warn("Ajax Error - Invalid ajaxContentType value:", self.table.options.ajaxContentType);
381  }
382  }
383 
384  if (url) {
385 
386  //configure headers
387  if (typeof config.headers === "undefined") {
388  config.headers = {};
389  }
390 
391  if (typeof config.headers.Accept === "undefined") {
392  config.headers.Accept = "application/json";
393  }
394 
395  if (typeof config.headers["X-Requested-With"] === "undefined") {
396  config.headers["X-Requested-With"] = "XMLHttpRequest";
397  }
398 
399  if (typeof config.mode === "undefined") {
400  config.mode = "cors";
401  }
402 
403  if (config.mode == "cors") {
404 
405  if (typeof config.headers["Access-Control-Allow-Origin"] === "undefined") {
406  config.headers["Access-Control-Allow-Origin"] = window.location.origin;
407  }
408 
409  if (typeof config.credentials === "undefined") {
410  config.credentials = 'same-origin';
411  }
412  } else {
413  if (typeof config.credentials === "undefined") {
414  config.credentials = 'include';
415  }
416  }
417 
418  //send request
419  fetch(url, config).then(function (response) {
420  if (response.ok) {
421  response.json().then(function (data) {
422  resolve(data);
423  }).catch(function (error) {
424  reject(error);
425  console.warn("Ajax Load Error - Invalid JSON returned", error);
426  });
427  } else {
428  console.error("Ajax Load Error - Connection Error: " + response.status, response.statusText);
429  reject(response);
430  }
431  }).catch(function (error) {
432  console.error("Ajax Load Error - Connection Error: ", error);
433  reject(error);
434  });
435  } else {
436  console.warn("Ajax Load Error - No URL Set");
437  resolve([]);
438  }
439  });
440 };
441 
442 Ajax.prototype.contentTypeFormatters = {
443  "json": {
444  headers: {
445  'Content-Type': 'application/json'
446  },
447  body: function body(url, config, params) {
448  return JSON.stringify(params);
449  }
450  },
451  "form": {
452  headers: {},
453  body: function body(url, config, params) {
454  var output = this.generateParamsList(params),
455  form = new FormData();
456 
457  output.forEach(function (item) {
458  form.append(item.key, item.value);
459  });
460 
461  return form;
462  }
463  }
464 };
465 
466 Tabulator.prototype.registerModule("ajax", Ajax);