I am using JSTree in my application with following code.
this.CreateTreeView = function () {
$('#jstree_demo_div').jstree({
'core': {
'multiple': false,
'data': [
{ "id": "ajson1", "parent": "#", "text": "Simple root node" },
{ "id": "ajson2", "parent": "#", "text": "Root node 2" },
{ "id": "ajson3", "parent": "ajson2", "text": "Child 1" },
{ "id": "ajson4", "parent": "ajson2", "text": "Child 2" },
]
}
});
}
As shown in my code i am trying to disable multiple selection.
Now when i use following code to select node.
$("#jstree_demo_div").jstree().select_node("ajson3");
$("#jstree_demo_div").jstree().select_node("ajson4");
Still it select both node. So it becomes like multiple selection from Javascript.
I am putting this question just to confirm that is it correct working of JSTree?
I know that i can deselect all node before selecting any node using deselect_all function.
But according to me if multiple selection is set to false then selecting node from javascript also should select only one node.
Please correct me if i am wrong.
select_node will select a node regardless of the multiple setting.
The setting only limits user interaction, select_node is a lower level method and will not be limited, so you (the developer) can modify the selection programmatically without limitation.
If you want to use the same function that is triggered by user interaction (and is therefore limited by multiple) use activate_node.
just use this configuration
this.CreateTreeView = function () {
**"plugins" : [
"checkbox",
],**
$('#jstree_demo_div').jstree({
'core': {
**'multiple': false,**
'data': [
{ "id": "ajson1", "parent": "#", "text": "Simple root node" },
{ "id": "ajson2", "parent": "#", "text": "Root node 2" },
{ "id": "ajson3", "parent": "ajson2", "text": "Child 1" },
{ "id": "ajson4", "parent": "ajson2", "text": "Child 2" },
]
},
**'checkbox' : {
'deselect_all': true,
'three_state' : false,
}**
}); }
'checkbox' : {
'deselect_all': true,
'three_state' : false,
}
works fine!
To Disable checkbox multi-select in JStree this code also work perfectly :
var tmp=null; /// to prevent recursion
treeobj.on("check_node.jstree uncheck_node.jstree", function(e, data) {
if(tmp!=data.node.id){
tmp=data.node.id;
treeobj.jstree("uncheck_all", null);
treeobj.jstree("check_node",data.node.id);
}
})
Related
I have Analysis Paralysis and need some input. I can modify the SQL query, the JavaScript, AND/or the CFML controller (all code has been posted below).
All I'm looking to do is to populate a select box with options and optgroups. The optgroup is what is tripping me up here.
The sql is pretty basic and looks like this:
SELECT
g.groupID,
g.groupLabel,
u.unitLabel,
u.unitID
FROM
group g
LEFT JOIN unit u ON g.groupID = u.groupID
And the CFML loop(s) is as follows (this is also where I believe the adjustment should be made with some logic such as if thisGroupLabel matches the preGroupLabel, stay within loop and keep adding unitLabel and unitIDs) but is there a more efficient way?:
local.data.unitLabels = [];
for(local.row in local.__unitLabels){
local.unit = {};
local.unit.groupLabel = local.row.groupLabel;
local.unit.unitLabel = local.row.unitLabel;
local.unit.unitID = local.row.unitID;
// loop over the array so that we can identify which one needs to be preselected
for(local.dataValue in local.data.unitDetails){
if (local.unit.unitID eq local.dataValue.unitID) {
local.unit.selected = 'selected';
} else {
local.unit.selected = '';
}
}
arrayAppend(local.data.unitLabels, local.unit);
}
The JSON data looks like this but I have access to the query so I can reformat it if needed:
{
"data": {
"selectDataOptions": [{
"groupLabel": "COMPLETION",
"selected": "",
"unitID": 1,
"unitLabel": "Completion"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 2,
"unitLabel": "Meters"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 3,
"unitLabel": "Miles"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 4,
"unitLabel": "Yards"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "Hours"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "minutes"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "Seconds"
}]
}
}
As it stands, my select box looks like this (roughly):
<select>
<optgroup>COMPLETION</optgroup>
<option>Complettion</option>
<optgroup>DISTANCE</OPTGROUP>
<option>Meters</option>
<optgroup>DISTANCE</optgroup>
<option>Miles</option>
<optgtroup>DISTANCE</optgroup>
<option>Yards</option>
<optgtroup>TIME</optgroup>
<option>Hours</option>
<optgtroup>TIME</optgroup>
<option>Minutes</option>
</select>
Notice that the optgroup Distance and TIME are repeated. The desired output would look like this:
<select>
<optgroup>COMPLETION</optgroup>
<option>Complettion</option>
<optgroup>DISTANCE</OPTGROUP>
<option>Meters</option>
<option>Miles</option>
<option>Yards</option>
<optgroup>TIME</optgroup>
<option>Hours</option>
<option>Mintues</option>
</select>
Is the issue how to construct a JSON string that Select2 can understand? I'd suggest creating a nested array of children for each GroupLabel, as described in the documentation under Grouped Data.
CF11+ and Lucee 4.5+ support cfloop "group", which would make things a lot easier. Just cfloop through the query and group by "groupLabel". (NB: Don't forget to modify the SQL query and ORDER BY g.groupLabel so the grouping works as expected.)
TryCF.com Example
Code:
data= [];
cfloop(query="qDemo", group="groupLabel") {
children = [];
cfloop() {
arrayAppend(children, {"id": qDemo.unitID, "text": qDemo.unitLabel});
}
arrayAppend(data, {"text" : qDemo.GroupLabel, "children" : children });
}
writeDump(serializeJSON(data));
Result:
[
{
"text": "COMPLETION",
"children": [
{
"text": "Completion",
"id": 1
}
]
},
{
"text": "DISTANCE",
"children": [
{
"text": "Meters",
"id": 2
},
{
"text": "Miles",
"id": 3
},
{
"text": "Yards",
"id": 4
}
]
},
{
"text": "TIME",
"children": [
{
"text": "Hours",
"id": 5
},
{
"text": "minutes",
"id": 5
},
{
"text": "Seconds",
"id": 5
}
]
}
]
When parsing the data from the example, the disabled parameter works, but the selected one dosen't. Any ideas why?
Example:
{
"results": [
{
"id": 1,
"text": "Option 1"
},
{
"id": 2,
"text": "Option 2",
"selected": true
},
{
"id": 3,
"text": "Option 3",
"disabled": true
}
]
}
Result from site:
Select2 version 4.0.3 - link: Select2 Data Source
JQuery version 3.0.0
selected parameter did not work for me either. Had to use below workaround to make it work -
$(".select").select2({
data: data_names
});
data_names.forEach(function(name) {
if (name.selected) {
$(".select").select2('val', name.id);
}
});
I looking for best solution how to implement #observable on deep json object structure (for example a tree) data tree could be go really deep. and each node has many properties, but I need to observe only one property in tree node. Simply if I do
#observable questionnaire = {}
it works, but i think that is waist. I need observe only 'selected' property.
Here is json structure. Please correct me if i'm wrong here is questionnaire object simplified.
[
{
"id": "1",
"title": "level 1",
"description": "text",
"type": "Question",
"selected": false,
"childNodes": [
{
"title": "level 2",
"description": "text",
"type": "Question",
"selected": false,
"childNodes": [
{
"title": "level 3",
"description": null,
"type": "Question",
"selected": false,
"childNodes": [
{
"title": "level 4 1",
"childNodes": [],
"description": null,
"type": "Checkbox",
"selected": false
},
{
"title": "level 4 2",
"childNodes": [],
"description": null,
"type": "Checkbox",
"selected": false
},
{
"title": "level 4 3",
"childNodes": [],
"description": null,
"type": "Checkbox",
"selected": false
},
...
]
}, ...
One way is to have a Node class implemented as follows:
class Node {
#observable selected = false;
#observable childNodes = asFlat([]);
constructor(data) {
// Recursively create `Node` objects for all children.
data.childNodes = data.childNodes.map(child => new Node(child));
Object.assign(this, data);
}
}
Then you create a Node object from your top-level json object: new Node(json).
This solution will only observe selected and childNodes. It's not ideal because you need to wrap your json object in Node objects. But I can't think of any other way to do it.
I need to change the tree view icons and enable/disable checkboxes
please view the code below :
function LoadJSTree() {
$.noConflict();
$(function () {
$('#demoTree').jstree({
'checkbox': {
'keep_selected_style': false,
'two_state': true
},
"types": {
"#": {
"max_children": 1,
"max_depth": 4,
"valid_children": ["root"]
},
"root": {
"icon": "/static/3.1.1/assets/images/tree_icon.png",
"valid_children": ["default"],
"check_node": false,
},
"default": {
"valid_children": ["default", "file"],
"check_node": true,
"uncheck_node": true
},
"disabled":{
"check_node": false,
"uncheck_node": false
},
"file": {
"icon": "glyphicon glyphicon-file",
"valid_children": [],
"check_node": true,
"uncheck_node": true
}
},
"plugins": ["types"],
'core': {
'data': [
{
"text": "Root node", "type": "root", "parent":"#", "children": [
{ "text": "Child node 1", "type": "default" },
{ "text": "Child node 2", "type": "default" },
{ "text": "Child node 3", "type": "default" },
{ "text": "Child node 4", "type": "default" },
{ "text": "Child node 5", "type": "default" },
{ "text": "Child node 6", "type": "default" },
{ "text": "Child node 7", "type": "default" },
{ "text": "Child node 8", "type": "default" }
]
}
],
},
'plugins': ["checkbox"]
});
It doesn't seem to work.
The tree is displayed using same folder icons for every node and check box always present for every node, shouldn't it come disabled for "root" node?
Could you please let me know what's wrong?
You have listed plugins twice in your config:
"plugins": ["types"],
...
'plugins': ["checkbox"]
Change that to a single entry:
"plugins": ["checkbox", "types"]
However keep in mind there is no option (in v.3, if that is the version you are using) to prevent actions based on the type of the node. But using the most recent jsTree commit you can disable checkboxes on a per node basis using the state property of the node (you can also disable the whole node) - if that is what you need have a look here:
jsTree disable some of the checkboxes
I'm using jQuery.dynatree plugin, how to load JSON formatted data using AJAX?
I do all as said in documentation:
<script>
$(function() {
$( "#Tree" ).dynatree({
title:"Thetree",
imagePath:'/jquery/css/',
selectMode:1,
initAjax:{
url:"http://127.0.0.1:2013/jsfolderstree"
}
});
});
</script>
The JS scripts is correctly connected to the HTML page, witout errors.
The requested URL by AJAX returns valid JSON:
[{
"key": "0x55638DB3",
"children": [
{
"key": "0x5D43E57C",
"children": [
{
"key": "0x70A4C1CE",
"children": [
{
"key": "0x799E9590",
"children": [],
"expand": true,
"tooltip": "This is group 5",
"isFolder": true,
"title": "Group 5"
},{
"key": "0x78C952A8",
"children": [],
"expand": true,
"tooltip": "This is group 6",
"isFolder": true,
"title": "Group 6"
}],
"expand": true,
"tooltip": "This is group 3",
"isFolder": true,
"title": "Group 3"
}],
"expand": true,
"tooltip": "This is group 1",
"isFolder": true,
"title": "Group 1"
},{
"key": "0x45B98999",
"children": [
{
"key": "0x6C829354",
"children": [],
"expand": true,
"tooltip": "This is group 4",
"isFolder": true,
"title": "Group 4"
}],
"expand": true,
"tooltip": "This is group 2",
"isFolder": true,
"title": "Group 2"
},{
"key": "0x47BE4570",
"children": [],
"expand": true,
"tooltip": "This is group 7",
"isFolder": true,
"title": "Group 7"
}],
"expand": true,
"tooltip": "Main level of tree",
"isFolder": true,
"title": "Root"
}]
But in result I have message "Loading Error" amd nothing more...
Where is my mistake?
I need load some JSON tree to the web-page, the tree must have methods to get selected node, and visual selection by mouse, that is that I need. Maybe need to use more simple plugins?
Thanks!
If you using jQuery ajax to load a JSON data,jQuery will resolve JSON data by JSON.parse method.
So don't put your JSON data in [], it will call parse error in jQuery ajax method.
{
"key": "0x55638DB3",
"children": [{...}]
....
}