mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-07-31 16:24:54 +02:00
Init datatables even after ajax requests.
This commit is contained in:
parent
6c96d8efad
commit
c0f44b76f3
5 changed files with 53 additions and 42 deletions
|
@ -45,6 +45,8 @@ require('jquery-form');
|
|||
window.$ = window.jQuery = require("jquery");
|
||||
|
||||
require('bootstrap-treeview/src/js/bootstrap-treeview');
|
||||
require('./datatables.js');
|
||||
|
||||
|
||||
require('../ts_src/ajax_ui');
|
||||
import {ajaxUI} from "../ts_src/ajax_ui";
|
||||
|
|
184
assets/js/datatables.js
Normal file
184
assets/js/datatables.js
Normal file
|
@ -0,0 +1,184 @@
|
|||
/**
|
||||
* Symfony DataTables Bundle
|
||||
* (c) Omines Internetbureau B.V. - https://omines.nl/
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*
|
||||
* @author Niels Keurentjes <niels.keurentjes@omines.com>
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
/**
|
||||
* Initializes the datatable dynamically.
|
||||
*/
|
||||
$.fn.initDataTables = function(config, options) {
|
||||
|
||||
//Update default used url, so it reflects the current location (useful on single side apps)
|
||||
$.fn.initDataTables.defaults.url = window.location.origin + window.location.pathname;
|
||||
|
||||
var root = this,
|
||||
config = $.extend({}, $.fn.initDataTables.defaults, config),
|
||||
state = ''
|
||||
;
|
||||
|
||||
// Load page state if needed
|
||||
switch (config.state) {
|
||||
case 'fragment':
|
||||
state = window.location.hash;
|
||||
break;
|
||||
case 'query':
|
||||
state = window.location.search;
|
||||
break;
|
||||
}
|
||||
state = (state.length > 1 ? deparam(state.substr(1)) : {});
|
||||
var persistOptions = config.state === 'none' ? {} : {
|
||||
stateSave: true,
|
||||
stateLoadCallback: function(s, cb) {
|
||||
// Only need stateSave to expose state() function as loading lazily is not possible otherwise
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return new Promise((fulfill, reject) => {
|
||||
// Perform initial load
|
||||
$.ajax(config.url, {
|
||||
method: config.method,
|
||||
data: {
|
||||
_dt: config.name,
|
||||
_init: true
|
||||
}
|
||||
}).done(function(data) {
|
||||
var baseState;
|
||||
|
||||
// Merge all options from different sources together and add the Ajax loader
|
||||
var dtOpts = $.extend({}, data.options, config.options, options, persistOptions, {
|
||||
ajax: function (request, drawCallback, settings) {
|
||||
if (data) {
|
||||
data.draw = request.draw;
|
||||
drawCallback(data);
|
||||
data = null;
|
||||
if (Object.keys(state).length && dt.state != null) {
|
||||
var merged = $.extend(true, {}, dt.state(), state);
|
||||
dt
|
||||
.order(merged.order)
|
||||
.search(merged.search.search)
|
||||
.page.len(merged.length)
|
||||
.page(merged.start / merged.length)
|
||||
.draw(false);
|
||||
}
|
||||
} else {
|
||||
request._dt = config.name;
|
||||
$.ajax(config.url, {
|
||||
method: config.method,
|
||||
data: request
|
||||
}).done(function(data) {
|
||||
drawCallback(data);
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
root.html(data.template);
|
||||
dt = $('table', root).DataTable(dtOpts);
|
||||
if (config.state !== 'none') {
|
||||
dt.on('draw.dt', function(e) {
|
||||
var data = $.param(dt.state()).split('&');
|
||||
|
||||
// First draw establishes state, subsequent draws run diff on the first
|
||||
if (!baseState) {
|
||||
baseState = data;
|
||||
} else {
|
||||
var diff = data.filter(el => { return baseState.indexOf(el) === -1 && el.indexOf('time=') !== 0; });
|
||||
switch (config.state) {
|
||||
case 'fragment':
|
||||
history.replaceState(null, null, window.location.origin + window.location.pathname + window.location.search
|
||||
+ '#' + decodeURIComponent(diff.join('&')));
|
||||
break;
|
||||
case 'query':
|
||||
history.replaceState(null, null, window.location.origin + window.location.pathname
|
||||
+ '?' + decodeURIComponent(diff.join('&') + window.location.hash));
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fulfill(dt);
|
||||
}).fail(function(xhr, cause, msg) {
|
||||
console.error('DataTables request failed: ' + msg);
|
||||
reject(cause);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide global component defaults.
|
||||
*/
|
||||
$.fn.initDataTables.defaults = {
|
||||
method: 'POST',
|
||||
state: 'fragment',
|
||||
url: window.location.origin + window.location.pathname
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a querystring to a proper array - reverses $.param
|
||||
*/
|
||||
function deparam(params, coerce) {
|
||||
var obj = {},
|
||||
coerce_types = {'true': !0, 'false': !1, 'null': null};
|
||||
$.each(params.replace(/\+/g, ' ').split('&'), function (j, v) {
|
||||
var param = v.split('='),
|
||||
key = decodeURIComponent(param[0]),
|
||||
val,
|
||||
cur = obj,
|
||||
i = 0,
|
||||
keys = key.split(']['),
|
||||
keys_last = keys.length - 1;
|
||||
|
||||
if (/\[/.test(keys[0]) && /\]$/.test(keys[keys_last])) {
|
||||
keys[keys_last] = keys[keys_last].replace(/\]$/, '');
|
||||
keys = keys.shift().split('[').concat(keys);
|
||||
keys_last = keys.length - 1;
|
||||
} else {
|
||||
keys_last = 0;
|
||||
}
|
||||
|
||||
if (param.length === 2) {
|
||||
val = decodeURIComponent(param[1]);
|
||||
|
||||
if (coerce) {
|
||||
val = val && !isNaN(val) ? +val // number
|
||||
: val === 'undefined' ? undefined // undefined
|
||||
: coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
|
||||
: val; // string
|
||||
}
|
||||
|
||||
if (keys_last) {
|
||||
for (; i <= keys_last; i++) {
|
||||
key = keys[i] === '' ? cur.length : keys[i];
|
||||
cur = cur[key] = i < keys_last
|
||||
? cur[key] || (keys[i + 1] && isNaN(keys[i + 1]) ? {} : [])
|
||||
: val;
|
||||
}
|
||||
|
||||
} else {
|
||||
if ($.isArray(obj[key])) {
|
||||
obj[key].push(val);
|
||||
} else if (obj[key] !== undefined) {
|
||||
obj[key] = [obj[key], val];
|
||||
} else {
|
||||
obj[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (key) {
|
||||
obj[key] = coerce
|
||||
? undefined
|
||||
: '';
|
||||
}
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
}($));
|
|
@ -75,9 +75,16 @@ class AjaxUI {
|
|||
this.BASE = $("body").data("base-url") + "/";
|
||||
console.info("Base path is " + this.BASE);
|
||||
|
||||
//Show flash messages
|
||||
$(".toast").toast('show');
|
||||
|
||||
this.registerLinks();
|
||||
this.registerForm();
|
||||
this.fillTrees();
|
||||
|
||||
|
||||
this.initDataTables();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +205,8 @@ class AjaxUI {
|
|||
*/
|
||||
public registerLinks()
|
||||
{
|
||||
$('a').not(".link-external, [data-no-ajax]").click(function (event) {
|
||||
// Unbind all old handlers, so the things are not executed multiple times.
|
||||
$('a').not(".link-external, [data-no-ajax]").unbind('click').click(function (event) {
|
||||
let a = $(this);
|
||||
let href = $.trim(a.attr("href"));
|
||||
//Ignore links without href attr and nav links ('they only have a #)
|
||||
|
@ -232,6 +240,9 @@ class AjaxUI {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the progressbar
|
||||
*/
|
||||
public showProgressBar()
|
||||
{
|
||||
//Blur content background
|
||||
|
@ -245,6 +256,9 @@ class AjaxUI {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the progressbar.
|
||||
*/
|
||||
public hideProgressBar()
|
||||
{
|
||||
// @ts-ignore
|
||||
|
@ -322,7 +336,7 @@ class AjaxUI {
|
|||
ajaxUI.hideProgressBar();
|
||||
|
||||
//Parse response to DOM structure
|
||||
let dom = $.parseHTML(responseText);
|
||||
let dom = $.parseHTML(responseText, document, true);
|
||||
//And replace the content container
|
||||
$("#content").replaceWith($("#content", dom));
|
||||
//Replace login menu too (so everything is up to date)
|
||||
|
@ -332,6 +346,10 @@ class AjaxUI {
|
|||
$("#message-container").replaceWith($('#message-container', dom));
|
||||
$(".toast").toast('show');
|
||||
|
||||
//Inject the local scripts
|
||||
$("#script-reloading").replaceWith($('#script-reloading', dom));
|
||||
|
||||
|
||||
//Set new title
|
||||
let title = extractTitle(responseText);
|
||||
document.title = title;
|
||||
|
@ -342,14 +360,38 @@ class AjaxUI {
|
|||
history.pushState(null, title, this.url);
|
||||
} else {
|
||||
//Clear pop state
|
||||
ajaxUI.statePopped;
|
||||
ajaxUI.statePopped = true;
|
||||
}
|
||||
|
||||
//Do things on the new dom
|
||||
ajaxUI.registerLinks();
|
||||
ajaxUI.registerForm();
|
||||
ajaxUI.initDataTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init all datatables marked with data-datatable based on their data-settings attribute.
|
||||
*/
|
||||
protected initDataTables()
|
||||
{
|
||||
//Find all datatables and init it.
|
||||
let $tables = $('[data-datatable]');
|
||||
$.each($tables, function(index, table) {
|
||||
let $table = $(table);
|
||||
let settings = $table.data('settings');
|
||||
|
||||
//@ts-ignore
|
||||
var promise = $('#part_list').initDataTables(settings,
|
||||
{
|
||||
"fixedHeader": { header: $(window).width() >= 768, //Only enable fixedHeaders on devices with big screen. Fixes scrolling issues on smartphones.
|
||||
headerOffset: $("#navbar").height()}
|
||||
});
|
||||
|
||||
//Register links.
|
||||
promise.then(ajaxUI.registerLinks);
|
||||
});
|
||||
|
||||
console.debug('Datatables inited.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue