mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-10-04 19:45:40 +00:00
* build: move frontend assets to Bootstrap 5.3 and Tom Select * feat: migrate templates and scripts to Bootstrap 5, dropping jQuery Templates - Rename Bootstrap 4 classes and data attributes (data-bs-*, ms-/me-/ps-/pe-, text-start/end, form-group -> mb-3, input-group wrappers removed, badges, custom controls -> form-check/form-select, media -> d-flex, btn-close, ...) - Dark mode now uses Bootstrap 5.3 colour modes (data-bs-theme on <html>), set from <head> to avoid a flash of the light theme - Remove the Bootstrap 4 /bootstrap/ demo page - Contextual table classes (table-success etc.) still work as plain backgrounds for the rigboard key JavaScript - Remove jQuery: src.js/interaction.js and every inline template script are rewritten in plain JS on top of small helpers (helpers.js, bundled with Bootstrap into jpop.js so inline scripts can use them) - Replace bootstrap-select/ajax-bootstrap-select with Tom Select. The remote search now sends the `q` parameter and reads `text`, which is what the API actually uses (the old picker sent `term` and read `label`) - HTML fragments are fetched with an X-Requested-With header so views keep rendering their modal variants, and fetched scripts are re-executed - Remove the Bootstrap 4 plugin script includes * fix: stop rigboard header buttons stretching to full width under Bootstrap 5 * fix: restore dark-mode brand colours and contextual table colours under Bootstrap 5 * fix: brighten dark-mode links and make coloured card outlines visible * fix: calendar layout and grid borders, navbar search button width, guard missing modal links * fix: readable text in dark-mode Tom Select inputs and placeholders, restore form-control column widths * build: split the Dockerfile into cached stages with prod and dev targets * deploy: make compose.yml development-only with live reload, and document it * fix: keep badge text colour for links inside badges * fix: restore table-bordered grid lines in dark mode * fix: include Bootstrap's progress styles and keep progress labels readable
139 lines
4.7 KiB
JavaScript
139 lines
4.7 KiB
JavaScript
// Select widgets, built on Tom Select.
|
|
// * <select class="ts-select" data-sourceurl="..."> loads its options remotely as the user types
|
|
// * <select class="ts-select"> without a source URL is a plain (optionally multiple) select
|
|
|
|
var clearSelectionLabel = '(no selection)';
|
|
|
|
function changeSelectedValue(select, pk, text, update_url) { // Pass in the <select> and the new option's parameters
|
|
var ts = select.tomselect;
|
|
if (!ts) {
|
|
return;
|
|
}
|
|
ts.clear(true);
|
|
ts.clearOptions();
|
|
ts.addOption({value: pk, text: text, update_url: update_url || ''});
|
|
ts.setValue(pk, true);
|
|
select.dispatchEvent(new Event('change', {bubbles: true})); // Trigger the change function manually
|
|
}
|
|
|
|
function selectedUpdateUrl(select) {
|
|
var ts = select.tomselect;
|
|
var value = ts.getValue();
|
|
if (!value) {
|
|
return '';
|
|
}
|
|
var option = ts.options[value];
|
|
if (option && option.update_url !== undefined) {
|
|
return option.update_url;
|
|
}
|
|
var domOption = select.querySelector('option[value="' + CSS.escape(value) + '"]');
|
|
return domOption && domOption.dataset.update_url ? domOption.dataset.update_url : null;
|
|
}
|
|
|
|
function refreshUpdateHref(select) {
|
|
var target = document.getElementById(select.id + '-update');
|
|
if (!target) {
|
|
return;
|
|
}
|
|
var update_url = selectedUpdateUrl(select);
|
|
|
|
if (update_url === '') { // Nothing is selected
|
|
target.removeAttribute('href');
|
|
target.classList.add('disabled');
|
|
} else if (update_url !== null) {
|
|
target.setAttribute('href', update_url);
|
|
target.classList.remove('disabled');
|
|
}
|
|
}
|
|
|
|
function initPicker(select) {
|
|
var noClear = 'noclear' in select.dataset;
|
|
var multiple = select.multiple;
|
|
var url = select.dataset.sourceurl;
|
|
var plugins = [];
|
|
if (multiple) {
|
|
plugins.push('remove_button');
|
|
} else if (!noClear) {
|
|
plugins.push('clear_button');
|
|
}
|
|
|
|
var settings = {
|
|
plugins: plugins,
|
|
valueField: 'value',
|
|
labelField: 'text',
|
|
searchField: ['text'],
|
|
allowEmptyOption: false,
|
|
placeholder: select.dataset.noneSelectedText || '',
|
|
maxOptions: null,
|
|
hideSelected: false,
|
|
closeAfterSelect: !multiple
|
|
};
|
|
|
|
if (url) {
|
|
Object.assign(settings, {
|
|
// Results come from the server so don't filter them locally
|
|
score: function () { return function () { return 1; }; },
|
|
shouldLoad: function (query) { return query.length > 0; },
|
|
load: function (query, callback) {
|
|
var separator = url.indexOf('?') === -1 ? '?' : '&';
|
|
fetch(url + separator + 'q=' + encodeURIComponent(query), {credentials: 'same-origin'})
|
|
.then(function (response) { return response.json(); })
|
|
.then(function (data) {
|
|
callback(data.map(function (item) {
|
|
return {value: item.pk, text: item.text, update_url: item.update};
|
|
}));
|
|
})
|
|
.catch(function () { callback(); });
|
|
}
|
|
});
|
|
}
|
|
|
|
var update_urls = {};
|
|
select.querySelectorAll('option[data-update_url]').forEach(function (option) {
|
|
update_urls[option.value] = option.dataset.update_url;
|
|
});
|
|
|
|
var ts = new TomSelect(select, settings);
|
|
Object.keys(update_urls).forEach(function (value) {
|
|
if (ts.options[value]) {
|
|
ts.options[value].update_url = update_urls[value];
|
|
}
|
|
});
|
|
|
|
if (select.id && document.getElementById(select.id + '-update')) {
|
|
select.addEventListener('change', function () { // on change, update the edit button href
|
|
refreshUpdateHref(select);
|
|
});
|
|
refreshUpdateHref(select); // Ensure href is correct at the beginning
|
|
}
|
|
}
|
|
|
|
function initSelects(root) {
|
|
if (typeof TomSelect === 'undefined') {
|
|
return;
|
|
}
|
|
(root || document).querySelectorAll('select.ts-select').forEach(function (select) {
|
|
if (!select.tomselect) {
|
|
initPicker(select);
|
|
}
|
|
});
|
|
}
|
|
|
|
ready(function () {
|
|
initSelects();
|
|
|
|
//When update/edit modal box submitted
|
|
var modal = document.getElementById('modal');
|
|
if (modal) {
|
|
modal.addEventListener('hide.bs.modal', function () {
|
|
if (typeof modaltarget !== 'undefined' && modaltarget && typeof modalobject !== 'undefined' && modalobject !== "") {
|
|
//Update the selector with new values
|
|
var select = document.querySelector(modaltarget);
|
|
if (select) {
|
|
changeSelectedValue(select, modalobject[0]['pk'], modalobject[0]['fields']['name'], modalobject[0]['update_url']);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|