Enabled treeview with turbo frames.

This commit is contained in:
Jan Böhmer 2022-03-05 23:09:55 +01:00
parent 7b244d3034
commit 41e0b251a9
5 changed files with 211 additions and 17 deletions

View file

@ -35,6 +35,8 @@ 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'
@ -48,9 +50,14 @@ import "patternfly-bootstrap-treeview/src/css/bootstrap-treeview.css"
import "bootstrap-fileinput/css/fileinput.css"
//import * as Turbo from "@hotwired/turbo"
require('bootstrap');
// Import Bootstrap treeview
import "patternfly-bootstrap-treeview";
import "./sidebar"
/**
//require( 'jszip' );
//#require( 'pdfmake' );
@ -72,7 +79,7 @@ window.Bloodhound = require('corejs-typeahead/dist/bloodhound.js');
//Define jquery globally
window.$ = window.jQuery = require("jquery");
require('patternfly-bootstrap-treeview/src/js/bootstrap-treeview');
require('bootstrap-fileinput');

27
assets/js/events_base.js Normal file
View file

@ -0,0 +1,27 @@
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();
});
})

155
assets/js/sidebar.js Normal file
View file

@ -0,0 +1,155 @@
'use strict';
import * as Turbo from '@hotwired/turbo';
const SidebarHelper = class {
constructor() {
this.BASE = $("body").data("base-url");
//If path doesn't end with slash, add it.
if(this.BASE[this.BASE.length - 1] !== '/') {
this.BASE = this.BASE + '/';
}
console.info("Base path is " + this.BASE);
this.fillTrees();
}
/**
* Fill the trees with the given data.
*/
fillTrees()
{
let categories = localStorage.getItem("tree_datasource_tree-categories");
let devices = localStorage.getItem("tree_datasource_tree-devices");
let tools = localStorage.getItem("tree_datasource_tree-tools");
if(categories == null) {
categories = "categories";
}
if(devices == null) {
devices = "devices";
}
if(tools == null) {
tools = "tools";
}
this.treeLoadDataSource("tree-categories", categories);
this.treeLoadDataSource("tree-devices", devices);
this.treeLoadDataSource("tree-tools", tools);
this.trees_filled = true;
let _this = this;
//Register tree btns to expand all, or to switch datasource.
$(".tree-btns").click(function (event) {
event.preventDefault();
$(this).parents("div.dropdown").removeClass('show');
//$(this).closest(".dropdown-menu").removeClass('show');
$(".dropdown-menu.show").removeClass("show");
let mode = $(this).data("mode");
let target = $(this).data("target");
let text = $(this).text() + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
if (mode==="collapse") {
// @ts-ignore
$('#' + target).treeview('collapseAll', { silent: true });
}
else if(mode==="expand") {
// @ts-ignore
$('#' + target).treeview('expandAll', { silent: true });
} else {
localStorage.setItem("tree_datasource_" + target, mode);
_this.treeLoadDataSource(target, mode);
}
return false;
});
}
/**
* Load the given url into the tree with the given id.
* @param target_id
* @param datasource
*/
treeLoadDataSource(target_id, datasource) {
let text = $(".tree-btns[data-mode='" + datasource + "']").html();
text = text + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
switch(datasource) {
case "categories":
this.initTree("#" + target_id, 'tree/categories');
break;
case "locations":
this.initTree("#" + target_id, 'tree/locations');
break;
case "footprints":
this.initTree("#" + target_id, 'tree/footprints');
break;
case "manufacturers":
this.initTree("#" + target_id, 'tree/manufacturers');
break;
case "suppliers":
this.initTree("#" + target_id, 'tree/suppliers');
break;
case "tools":
this.initTree("#" + target_id, 'tree/tools');
break;
case "devices":
this.initTree("#" + target_id, 'tree/devices');
break;
}
$( "#" + target_id + "-title").html(text);
}
/**
* Fill a treeview with data from the given url.
* @param tree The Jquery selector for the tree (e.g. "#tree-tools")
* @param url The url from where the data should be loaded
*/
initTree(tree, url) {
//let contextmenu_handler = this.onNodeContextmenu;
$.getJSON(this.BASE + url, function (data) {
// @ts-ignore
$(tree).treeview({
data: data,
enableLinks: true,
showIcon: false,
showBorder: true,
searchResultBackColor: '#ffc107',
searchResultColor: '#000',
onNodeSelected: function(event, data) {
if(data.href) {
//Simulate a click so we just change the inner frame
let a = document.createElement('a');
a.setAttribute('href', data.href);
a.innerHTML = "";
$(tree).append(a);
a.click();
a.remove();
//Turbo.visit(data.href)
}
},
//onNodeContextmenu: contextmenu_handler,
expandIcon: "fas fa-plus fa-fw fa-treeview", collapseIcon: "fas fa-minus fa-fw fa-treeview"})
.on('initialized', function() {
$(this).treeview('collapseAll', { silent: true });
//Implement searching if needed.
if($(this).data('treeSearch')) {
let _this = this;
let $search = $($(this).data('treeSearch'));
$search.on( 'input', function() {
$(_this).treeview('collapseAll', { silent: true });
$(_this).treeview('search', [$search.val()]);
});
}
});
});
}
}
export default new SidebarHelper();

View file

@ -1,16 +1,17 @@
{% macro sidebar_dropdown(target) %}
<li class="dropdown-header">{% trans %}actions{% endtrans %}</li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="expand" data-target="{{ target }}">{% trans %}expandAll{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="collapse" data-target="{{ target }}">{% trans %}reduceAll{% endtrans %}</a></li>
<li role="separator" class="dropdown-divider"></li>
<li class="dropdown-header">{% trans %}datasource{% endtrans %}</li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="categories" data-target="{{ target }}">{% trans %}category.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="locations" data-target="{{ target }}">{% trans %}storelocation.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="footprints" data-target="{{ target }}">{% trans %}footprint.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="manufacturers" data-target="{{ target }}">{% trans %}manufacturer.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="suppliers" data-target="{{ target }}">{% trans %}supplier.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="devices" data-target="{{ target }}">{% trans %}device.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="tools" data-target="{{ target }}">{% trans %}tools.label{% endtrans %}</a></li>
<li class="dropdown-header">{% trans %}actions{% endtrans %}</li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="expand" data-target="{{ target }}">{% trans %}expandAll{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="collapse" data-target="{{ target }}">{% trans %}reduceAll{% endtrans %}</a></li>
<li role="separator" class="dropdown-divider"></li>
<li class="dropdown-header">{% trans %}datasource{% endtrans %}</li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="categories" data-target="{{ target }}">{% trans %}category.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="locations" data-target="{{ target }}">{% trans %}storelocation.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="footprints" data-target="{{ target }}">{% trans %}footprint.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="manufacturers" data-target="{{ target }}">{% trans %}manufacturer.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="suppliers" data-target="{{ target }}">{% trans %}supplier.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="devices" data-target="{{ target }}">{% trans %}device.labelp{% endtrans %}</a></li>
<li><a href="#" class="tree-btns dropdown-item" data-mode="tools" data-target="{{ target }}">{% trans %}tools.label{% endtrans %}</a></li>
{% endmacro %}
<ul class="nav flex-column">

View file

@ -58,7 +58,9 @@
<header>
<turbo-frame id="navbar-frame" target="content" data-turbo-action="advance">
{% include "_navbar.html.twig" %}
</turbo-frame>
{% include "_flash.html.twig" %}
@ -69,7 +71,9 @@
<div class="row">
<div class="collapse d-md-block bg-light" id="sidebar-container">
<nav class="fixed-sidebar col-md-3 col-lg-2 " id="fixed-sidebar">
<turbo-frame id="sidebar" target="content" data-turbo-action="advance">
{% include "_sidebar.html.twig" %}
</turbo-frame>
<noscript><b>{% trans %}vendor.base.javascript_hint{% endtrans %}</b></noscript>
</nav>
</div>
@ -79,7 +83,7 @@
<i class="fas fa-angle-left"></i>
</button>
<div class="container-fluid mr-0 pr-0" id="content-container">
<turbo-frame id="content">
<turbo-frame id="content" data-turbo-action="advance">
{# Here will be the real content be injected#}
{% block content %}