{
"id": "costCenterTree",
"controlType": "htmlTemplate",
"refersToConfigSource": "",
"htmlTemplateContent": "<style>\r\n .bbjsTree{\r\n \r\n }\r\n</style>\r\n<input type=\"text\" value=\"\" class=\"input ccTreeSearch\" style=\"margin:0em auto 1em auto; display:block; padding:4px; border-radius:4px; border:1px solid silver;\" />\r\n<div class=\"bbjsTree\" id=\"tree\"></div>",
"events": [
{
"name": "onSubDataRequest",
"code": "debugger;\r\n//Lib laden, wenn noch nicht passiert\r\nif (!window.jsTree) {\r\n $('head').append(`<link href=\"https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css\" rel=\"stylesheet\">`);\r\n await jQuery.getScript(\"https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js\");\r\n window.jsTree = true;\r\n}\r\n//Daten und HTML Elemente besorgen\r\nlet ccResult = app.sqlRead(\"getAllCostcentersForTree\");\r\nlet treeElement = $(app.getHtmlElement(\"costCenterTree\")).find(\".bbjsTree\");\r\nlet searchInput = $(app.getHtmlElement(\"costCenterTree\")).find(\".ccTreeSearch\");\r\n\r\n//Daten transformieren, könnte auch schon in sql passieren.\r\nlet ccTreeData = ccResult.map(x => {\r\n return {\r\n id: x.id,\r\n text: x.ccName,\r\n parent: x.ccParentId ? x.ccParentId : \"#\"\r\n };\r\n});\r\n\r\n//Alten tree zerstören\r\ntreeElement.jstree(\"destroy\");\r\n\r\n//Events verknüpfen und tree Erzeugen\r\ntreeElement\r\n .on('create_node.jstree', async function (e, newNode, position) {//wenn Context Menu Create geklickt wurde\r\n let createApp = app.startBrixxbox({\r\n appName: \"costCenter\",\r\n additionalValues: {\r\n ccParentId: newNode.parent,\r\n ccName: newNode.node.text\r\n },\r\n });\r\n await createApp.addEventListener(\"onRecordSaved\", function (brixxApi, eventArgs) {\r\n app.refresh(\"costCenterTree\");\r\n })\r\n })\r\n .on('changed.jstree', function (e, data) {\r\n for (let i = 0; i < data.selected.length; i++) {\r\n console.log(\"Selected: \" + data.instance.get_node(data.selected[i]).text)\r\n }\r\n })\r\n .jstree({\r\n 'core': {\r\n \"check_callback\": true,\r\n \"data\": ccTreeData,\r\n \"themes\": {\r\n \"variant\": \"large\"\r\n }\r\n },\r\n \"checkbox\": {\r\n \"keep_selected_style\": false\r\n },\r\n \"plugins\": [\"wholerow\", \"dnd\", \"search\", \"contextmenu\"]\r\n //\"checkbox\",\r\n });\r\n\r\n//Suchfeld Events verknüpfen\r\nlet to = false;\r\nsearchInput.keyup(function () {\r\n debugger;\r\n if (to) { clearTimeout(to); }\r\n to = setTimeout(function () {\r\n var v = searchInput.val();\r\n treeElement.jstree(true).search(v);\r\n }, 250);\r\n});"
}
],
"index": 14
}
Copy the code below as a Control in your App Config. Make adjustments to the onSubDataRequest event for your specific usecase and render the control with app.refresh("myTree") at any point.
Take a look at https://www.jstree.com/ for further configuration details and options.
// Alternative format of the node (id & parent are required)
{
id : "string" // required
parent : "string" // required
text : "string" // node text
icon : "string" // string for custom
state : {
opened : boolean // is the node open
disabled : boolean // is the node disabled
selected : boolean // is the node selected
},
li_attr : {} // attributes for the generated LI node
a_attr : {} // attributes for the generated A node
}