diff --git a/assets/js/app.js b/assets/js/app.js
index 93069fd8..f10c9f2d 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -35,29 +35,14 @@ import '../bootstrap';
// Need jQuery? Install it with "yarn add jquery", then uncomment to require it.
const $ = require('jquery');
-import './events_base'
-
//Only include javascript
import '@fortawesome/fontawesome-free/css/all.css'
-import 'datatables.net-bs4/css/dataTables.bootstrap4.css'
-import 'datatables.net-buttons-bs4/css/buttons.bootstrap4.css'
-import 'datatables.net-fixedheader-bs4/css/fixedHeader.bootstrap4.css'
-import 'datatables.net-select-bs4/css/select.bootstrap4.css'
-import 'bootstrap-select/dist/css/bootstrap-select.css'
-
-import "patternfly-bootstrap-treeview/src/css/bootstrap-treeview.css"
-
-import "bootstrap-fileinput/css/fileinput.css"
-
-
require('bootstrap');
-// Import Bootstrap treeview
-import "patternfly-bootstrap-treeview";
-
import "./sidebar"
import "./datatables";
+//import "./tab_remember";
import "./register_events";
/**
diff --git a/assets/js/datatables.js b/assets/js/datatables.js
index 30053f6c..e2ded416 100644
--- a/assets/js/datatables.js
+++ b/assets/js/datatables.js
@@ -1,15 +1,19 @@
"use strict";
+//Styles
+import 'datatables.net-bs4/css/dataTables.bootstrap4.css'
+import 'datatables.net-buttons-bs4/css/buttons.bootstrap4.css'
+import 'datatables.net-fixedheader-bs4/css/fixedHeader.bootstrap4.css'
+import 'datatables.net-select-bs4/css/select.bootstrap4.css'
+import 'datatables.net-responsive-bs4/css/responsive.bootstrap4.css';
+//JS
import 'datatables.net-bs4';
import 'datatables.net-buttons-bs4';
import 'datatables.net-buttons/js/buttons.colVis.js';
-//require( 'datatables.net-buttons/js/buttons.html5.js' );
-//require( 'datatables.net-buttons/js/buttons.print.js' );
import 'datatables.net-fixedheader-bs4';
import 'datatables.net-select-bs4';
import 'datatables.net-colreorder-bs4';
import 'datatables.net-responsive-bs4';
-import 'datatables.net-responsive-bs4/css/responsive.bootstrap4.css';
import './lib/datatables';
diff --git a/assets/js/events_base.js b/assets/js/events_base.js
deleted file mode 100644
index 97e210b7..00000000
--- a/assets/js/events_base.js
+++ /dev/null
@@ -1,27 +0,0 @@
-function registerLoadHandler(fn) {
- document.documentElement.addEventListener('turbo:load', fn);
-}
-
-
-registerLoadHandler(function() {
- /**
- * Register the button, to jump to the top of the page.
- */
- $(document).on("ajaxUI:start", function registerJumpToTop() {
- $(window).scroll(function () {
- if ($(this).scrollTop() > 50) {
- $('#back-to-top').fadeIn();
- } else {
- $('#back-to-top').fadeOut();
- }
- });
- // scroll body to 0px on click
- $('#back-to-top').click(function () {
- $('#back-to-top').tooltip('hide');
- $('body,html').animate({
- scrollTop: 0
- }, 800);
- return false;
- }).tooltip();
- });
-})
\ No newline at end of file
diff --git a/assets/js/jquery.tristate.js b/assets/js/lib/jquery.tristate.js
similarity index 100%
rename from assets/js/jquery.tristate.js
rename to assets/js/lib/jquery.tristate.js
diff --git a/assets/js/tagsinput.js b/assets/js/lib/tagsinput.js
similarity index 100%
rename from assets/js/tagsinput.js
rename to assets/js/lib/tagsinput.js
diff --git a/assets/js/register_events.js b/assets/js/register_events.js
index 8c9e11a6..83335123 100644
--- a/assets/js/register_events.js
+++ b/assets/js/register_events.js
@@ -1,8 +1,35 @@
'use strict';
+//CSS
+import 'bootstrap-select/dist/css/bootstrap-select.css'
+import "bootstrap-fileinput/css/fileinput.css"
+
+//JS
+import "bootstrap-select";
+import "./lib/jquery.tristate"
+import "bootstrap-fileinput";
+
+import 'corejs-typeahead';
+const Bloodhound = require('corejs-typeahead/dist/bloodhound.js');
+import './lib/tagsinput';
+
+
+
const RegisterEventHelper = class {
constructor() {
this.registerToasts();
+ this.registerTooltips();
+ this.registerFileInput();
+ this.registerJumpToTopBtn();
+
+ this.registerTriStateCheckboxes();
+
+ this.registerBootstrapSelectPicker();
+
+ this.registerSpecialCharInput();
+ this.registerHoverPics();
+
+ this.registerAutocompleteTagsinput();
}
registerLoadHandler(fn) {
@@ -12,6 +39,189 @@ const RegisterEventHelper = class {
registerToasts() {
this.registerLoadHandler(() => $(".toast").toast('show'));
}
+
+ registerTooltips() {
+ this.registerLoadHandler(() => {
+ $(".tooltip").remove();
+ $('a[title], button[title], span[title], h6[title], h3[title], i.fas[title]')
+ //@ts-ignore
+ .tooltip("hide").tooltip({container: "body", placement: "auto", boundary: 'window'});
+ });
+ }
+
+ registerHoverPics() {
+
+ }
+
+ registerFileInput() {
+ this.registerLoadHandler(() => {
+ $(".file").fileinput();
+ });
+ }
+
+ registerJumpToTopBtn() {
+ this.registerLoadHandler(() => {
+ $(window).scroll(function () {
+ if ($(this).scrollTop() > 50) {
+ $('#back-to-top').fadeIn();
+ } else {
+ $('#back-to-top').fadeOut();
+ }
+ });
+ // scroll body to 0px on click
+ $('#back-to-top').click(function () {
+ $('#back-to-top').tooltip('hide');
+ $('body,html').animate({
+ scrollTop: 0
+ }, 800);
+ return false;
+ }).tooltip();
+ });
+ }
+
+ registerTriStateCheckboxes() {
+ this.registerLoadHandler(() => {
+ $(".tristate").tristate( {
+ checked: "true",
+ unchecked: "false",
+ indeterminate: "indeterminate",
+ });
+
+ $('.permission_multicheckbox:checkbox').change(function() {
+ //Find the other checkboxes in this row, and change their value
+ var $row = $(this).parents('tr');
+
+ //@ts-ignore
+ var new_state = $(this).tristate('state');
+
+ //@ts-ignore
+ $('.tristate:checkbox', $row).tristate('state', new_state);
+ });
+ })
+ }
+
+ registerBootstrapSelectPicker() {
+ this.registerLoadHandler(() => {
+ $(".selectpicker").selectpicker({
+ dropdownAlignRight: 'auto',
+ container: '#content',
+ });
+ });
+ }
+
+ registerAutocompleteTagsinput() {
+ this.registerLoadHandler(() => {
+ $('input.tagsinput').each(function() {
+
+ //Use typeahead if an autocomplete url was specified.
+ if($(this).data('autocomplete')) {
+
+ //@ts-ignore
+ var engine = new Bloodhound({
+ //@ts-ignore
+ datumTokenizer: Bloodhound.tokenizers.obj.whitespace(''),
+ //@ts-ignore
+ queryTokenizer: Bloodhound.tokenizers.obj.whitespace(''),
+ remote: {
+ url: $(this).data('autocomplete'),
+ wildcard: 'QUERY'
+ }
+ });
+
+ //@ts-ignore
+ $(this).tagsinput({
+ typeaheadjs: {
+ name: 'tags',
+ source: engine.ttAdapter()
+ }
+ });
+
+
+ } else { //Init tagsinput without typeahead
+ //@ts-ignore
+ $(this).tagsinput();
+ }
+ })
+ });
+ }
+
+ registerSpecialCharInput() {
+ this.registerLoadHandler(() => {
+ //@ts-ignore
+ $("input[type=text], textarea, input[type=search]").unbind("keydown").keydown(function (event) {
+ let greek = event.altKey;
+
+ let greek_char = "";
+ if (greek){
+ switch(event.key) {
+ case "w": //Omega
+ greek_char = '\u2126';
+ break;
+ case "u":
+ case "m": //Micro
+ greek_char = "\u00B5";
+ break;
+ case "p": //Phi
+ greek_char = "\u03C6";
+ break;
+ case "a": //Alpha
+ greek_char = "\u03B1";
+ break;
+ case "b": //Beta
+ greek_char = "\u03B2";
+ break;
+ case "c": //Gamma
+ greek_char = "\u03B3";
+ break;
+ case "d": //Delta
+ greek_char = "\u03B4";
+ break;
+ case "l": //Pound
+ greek_char = "\u00A3";
+ break;
+ case "y": //Yen
+ greek_char = "\u00A5";
+ break;
+ case "o": //Yen
+ greek_char = "\u00A4";
+ break;
+ case "1": //Sum symbol
+ greek_char = "\u2211";
+ break;
+ case "2": //Integral
+ greek_char = "\u222B";
+ break;
+ case "3": //Less-than or equal
+ greek_char = "\u2264";
+ break;
+ case "4": //Greater than or equal
+ greek_char = "\u2265";
+ break;
+ case "5": //PI
+ greek_char = "\u03c0";
+ break;
+ case "q": //Copyright
+ greek_char = "\u00A9";
+ break;
+ case "e": //Euro
+ greek_char = "\u20AC";
+ break;
+ }
+
+ if(greek_char=="") return;
+
+ let $txt = $(this);
+ //@ts-ignore
+ let caretPos = $txt[0].selectionStart;
+ let textAreaTxt = $txt.val().toString();
+ $txt.val(textAreaTxt.substring(0, caretPos) + greek_char + textAreaTxt.substring(caretPos) );
+
+ }
+ });
+ //@ts-ignore
+ this.greek_once = true;
+ })
+ }
}
export default new RegisterEventHelper();
\ No newline at end of file
diff --git a/assets/js/sidebar.js b/assets/js/sidebar.js
index 92f16985..5a0db639 100644
--- a/assets/js/sidebar.js
+++ b/assets/js/sidebar.js
@@ -1,5 +1,8 @@
'use strict';
+import "patternfly-bootstrap-treeview/src/css/bootstrap-treeview.css"
+import "patternfly-bootstrap-treeview";
+
const SidebarHelper = class {
constructor() {
this.BASE = $("body").data("base-url");
@@ -9,9 +12,50 @@ const SidebarHelper = class {
}
console.info("Base path is " + this.BASE);
+ this.registerSidebarHideButton();
this.fillTrees();
}
+ registerSidebarHideButton()
+ {
+ let $sidebar = $("#fixed-sidebar");
+ let $container = $("#main");
+ let $toggler = $('#sidebar-toggle-button');
+
+ function sidebarHide() {
+ $sidebar.hide();
+ $container.removeClass('col-md-9 col-lg-10 offset-md-3 offset-lg-2');
+ $container.addClass('col-12');
+ $toggler.html('');
+ $toggler.data('hidden', true);
+ localStorage.setItem('sidebarHidden', 'true');
+ }
+ function sidebarShow() {
+ let $sidebar = $("#fixed-sidebar");
+ $sidebar.show();
+ let $container = $("#main");
+ $container.removeClass('col-12');
+ $container.addClass('col-md-9 col-lg-10 offset-md-3 offset-lg-2');
+ $toggler.html('');
+ $toggler.data('hidden', false);
+ localStorage.setItem('sidebarHidden', 'false');
+ }
+
+ //Make the state persistent over reloads
+ if(localStorage.getItem('sidebarHidden') === 'true') {
+ sidebarHide();
+ }
+
+ //Register handler
+ $toggler.click(function() {
+ if($(this).data('hidden')) {
+ sidebarShow();
+ } else {
+ sidebarHide();
+ }
+ });
+ }
+
/**
* Fill the trees with the given data.
*/
diff --git a/assets/js/tab_remember.js b/assets/js/tab_remember.js
new file mode 100644
index 00000000..e302a08d
--- /dev/null
+++ b/assets/js/tab_remember.js
@@ -0,0 +1,46 @@
+"use strict";
+
+/**
+ * This listener keeps track of which tab is currently selected (using hash and localstorage) and will try to open
+ * that tab on reload. That means that if the user changes something, he does not have to switch back to the tab
+ * where he was before submit.
+ */
+let TabRememberHelper = new class {
+ constructor() {
+ document.addEventListener("turbo:load", () => {
+ //Determine which tab should be shown (use hash if specified, otherwise use localstorage)
+ var $activeTab = null;
+ if (location.hash) {
+ $activeTab = $('a[href=\'' + location.hash + '\']');
+ } else if (localStorage.getItem('activeTab')) {
+ $activeTab = $('a[href="' + localStorage.getItem('activeTab') + '"]');
+ }
+
+ if ($activeTab) {
+ //Findout if the tab has any parent tab we have to show before
+ var parents = $($activeTab).parents('.tab-pane');
+ parents.each(function (n) {
+ $('a[href="#' + $(this).attr('id') + '"]').tab('show');
+ });
+ //Finally show the active tab itself
+ $activeTab.tab('show');
+ }
+
+ $('body').on('click', 'a[data-toggle=\'tab\']', function (e) {
+ e.preventDefault()
+ var tab_name = this.getAttribute('href')
+ if (history.replaceState) {
+ history.replaceState(null, null, tab_name)
+ } else {
+ location.hash = tab_name
+ }
+ localStorage.setItem('activeTab', tab_name)
+
+ $(this).tab('show');
+ return false;
+ });
+ });
+ }
+}
+
+//export default new TabRememberHelper();
\ No newline at end of file