Description
This widget displays a configurable tree structure in the browser using jsTree. When the user clicks on a node in the tree, a selectedNode() script on the server is called. If the selected node contained a link URL then the URL is opened in a separate window.
Prerequisites
The widget comes preloaded with the required JavaScript libraries and css stylesheets.
JavaScript Libraries
- jQuery version 3.2.1
- jsTree version 3.2.1
CSS
- Font Awesome version 4.7.0
- jsTree version 3.2.1 themes using the default style.min.css
The widget was designed using the supplied bootstrap version 4 presentation template which includes jQuery version 3.2.1. If this template is removed then links to jQuery 3.2.1 or later must be provided.
Installation
Drag the widget from the Widgets View onto the page. This will add the UI element of the widget to the page and also create the following directory structure in the Installed Widgets Project:
Installed Widgets
InstalledWidgets
jsTreeView_{version}
{formName}_{widgetPrefix}jsTreeView
Scripts
configure
Configuration
The configure server-side script in the Installed Widgets project contains the following functions:
config : configures all rendering options for the tree
getData : configures the array of JSON objects required to populate the tree
selectedNode: receives the JSON object of the selected node
How it works
The widget uses the jsTree.js library. The tree is activated using a jQuery ready event configured in the HTML Element Properties of the widgets panel. All options that affect the way in which the tree is drawn are configured in the config() function of the server-side configure script. Building the data that constructs the nodes of the tree is defined in the getData() function of the server-side configure script. When a user clicks a node the selectedNode() function of the server-side configure script is called and passed the JSON object of the node. This object contains everything about the selected node. Individual elements in the nodes JSON object can be accessed from the server-side code. If the node clicked contains a URL link then in addition to calling the selectedNode() function the URL link is executed.
Additional Notes
The config(), getData() and selectedNode() functions run in the context of the widget.
To address elements in the form, all script references must be prefixed with "form." e.g.
// selectedNode function
function selectedNode(node)
{
form.fields.nodeId.value = node.id;
form.fields.parentId.value = node.parent;
form.fields.nodeText.value = node.text;
}
To add the same functionality to a buttons click event, add the widget anywhere on the page then open the HTML Element Properties of the widgets panel and copy the code from the ready event to the buttons HTML Element Properties click event. Give the button a unique id. Go back to the widgets panels HTML Element Properties and delete the ready event. The tree will now only be displayed when the button is clicked.
The 3rd party JS Tree library attempts to add inline style to some elements. If CSP is turned on without the unsafe-inline
keyword, the browser will refuse to apply the style and issue an error message to the log. The style that isn't applied doesn't appear to have any major impact on the functionality of this widget.
You can avoid these error messages by turning off CSP or by adding unsafe-inline
to your policy.
Examples
This is the server-side configure script used in the example usage demo.
function config()
{
options = {
core: {
themes: {
dots: form.fields.showLines.value,
responsive: true,
stripes : true
}
},
types : {
docType : { "li_attr" : { "style" : "color:#0066ff" } },
pdfType : { "li_attr" : { "style" : "color:#ff0000" } },
spreadsheetType : { "li_attr" : { "style" : "color:#006600" } }
},
plugins : ["types"]
};
return options;
}
function getData()
{
// define the data array
var data = [];
// push nodes into the array
data.push({
"id": 1,
"parent": '#',
"text": "Human Resources",
"state": {"opened": true},
"icon": "jsTree/widget/sample_images/tree_icon.png"
});
data.push({
"id": 2,
"parent": '#',
"text": "Manufacturing",
"state": {"opened": true},
"icon": "jsTree/widget/sample_images/tree_icon.png"
});
data.push({
"id": 3,
"parent": 1,
"text": "Employees",
"state": {"opened": true, selected : true}
});
data.push({
"id": 4,
"parent": 1,
"text": "General",
"state": {"opened": false}
});
data.push({
"id": 5,
"parent": 2,
"text": "Standard Operating Procedures",
"state": {"opened": false}
});
data.push({
"id": 6,
"parent": 2,
"text": "Schematics",
"state": {"opened": false}
});
data.push({
"id": 7,
"parent": 3,
"text": "Vacation Request",
"state": {"opened": false},
"icon": "fa fa-file-word-o",
"a_attr": {"href": "jsTree/widget/sample_documents/sample_vacation_request_form.docx"},
"type" : "{docType}"
});
data.push({
"id": 8,
"parent": 3,
"text": "New Employee Orientation",
"state": {"opened": false},
"icon": "fa fa-file-pdf-o",
"a_attr": {"href": "jsTree/widget/sample_documents/sample_new_employee_orientation.pdf"},
"type": "{pdfType}"
});
data.push({
"id": 9,
"parent": 3,
"text": "Expenses",
"state": {"opened": false},
"icon": "fa fa-file-excel-o",
"a_attr": {"href": "jsTree/widget/sample_documents/sample_employee_expenses.xlsx"},
"type": "{spreadsheetType}"
});
// sort data by node id
data.sort(function(a, b) {
return parseInt(a.id) - parseInt(b.id);
});
return data;
}
function selectedNode(node)
{
form.fields.nodeId.value = node.id;
form.fields.parentId.value = node.parent_id;
form.fields.nodeText.value = node.text;
}