I have finally made a network graph with highcharts. I would like to sort the graph in a specific shape if possible.
Expected shape:
// Add the nodes option through an event call. We want to start with the parent
// item and apply separate colors to each child element, then the same color to
// grandchildren.
Highcharts.addEvent(
Highcharts.seriesTypes.networkgraph,
'afterSetOptions',
function (e) {
var colors = Highcharts.getOptions().colors,
i = 0,
nodes = {};
e.options.data.forEach(function (link) {
if (link[0] === 'last01') {
nodes['last01'] = {
id: 'last01',
marker: {
radius: 20
}
};
nodes[link[1]] = {
id: link[1],
marker: {
radius: 10
},
color: colors[i++]
};
} else if (nodes[link[0]] && nodes[link[0]].color) {
nodes[link[1]] = {
id: link[1],
color: nodes[link[0]].color
};
}
});
e.options.nodes = Object.keys(nodes).map(function (id) {
return nodes[id];
});
}
);
const options = {
chart: {
type: 'networkgraph',
height: '100%'
},
title: {
text: 'Main diag'
},
subtitle: {
text: 'Router connection'
},
plotOptions: {
networkgraph: {
keys: ['from', 'to'],
layoutAlgorithm: {
enableSimulation: false,
repulsiveForce: function (d, k) {
return k * k * k * k / d;
}
}
}
},
series: [{
dataLabels: {
enabled: true,
linkFormat: ''
},
data: [
['last01','last02'],
['last01','medium201'],
['last01','medium202'],
['last01','medium203'],
['last01','medium204'],
['last01','medium205'],
['last01','medium206'],
['last01','medium207'],
['last01','medium208'],
['last01','medium209'],
['last01','medium210'],
['last01','medium211'],
['last01','medium212'],
['last01','medium213'],
['last01','medium214'],
['last01','medium215'],
['last01','medium216'],
['last02','last01'],
['last02','medium201'],
['last02','medium202'],
['last02','medium203'],
['last02','medium204'],
['last02','medium205'],
['last02','medium206'],
['last02','medium207'],
['last02','medium208'],
['last02','medium209'],
['last02','medium210'],
['last02','medium211'],
['last02','medium212'],
['last02','medium213'],
['last02','medium214'],
['last02','medium215'],
['last02','medium216'],
['medium201','last01'],
['medium201','last02'],
['medium201','medium101'],
['medium201','medium102'],
['medium201','medium103'],
['medium201','medium104'],
['medium202','last01'],
['medium202','last02'],
['medium202','medium101'],
['medium202','medium102'],
['medium202','medium103'],
['medium202','medium104'],
['medium203','last01'],
['medium203','last02'],
['medium203','medium101'],
['medium203','medium102'],
['medium203','medium103'],
['medium203','medium104'],
['medium204','last01'],
['medium204','last02'],
['medium204','medium101'],
['medium204','medium102'],
['medium204','medium103'],
['medium204','medium104'],
['medium205','last01'],
['medium205','last02'],
['medium205','medium101'],
['medium205','medium102'],
['medium205','medium103'],
['medium205','medium104'],
['medium206','last01'],
['medium206','last02'],
['medium206','medium101'],
['medium206','medium102'],
['medium206','medium103'],
['medium206','medium104'],
['medium207','last01'],
['medium207','last02'],
['medium207','medium101'],
['medium207','medium102'],
['medium207','medium103'],
['medium207','medium104'],
['medium208','last01'],
['medium208','last02'],
['medium208','medium101'],
['medium208','medium102'],
['medium208','medium103'],
['medium208','medium104'],
['medium209','last01'],
['medium209','last02'],
['medium209','medium101'],
['medium209','medium102'],
['medium209','medium103'],
['medium209','medium104'],
['medium210','last01'],
['medium210','last02'],
['medium210','medium101'],
['medium210','medium102'],
['medium210','medium103'],
['medium210','medium104'],
['medium211','last01'],
['medium211','last02'],
['medium211','medium101'],
['medium211','medium102'],
['medium211','medium103'],
['medium211','medium104'],
['medium212','last01'],
['medium212','last02'],
['medium212','medium101'],
['medium212','medium102'],
['medium212','medium103'],
['medium212','medium104'],
['medium213','last01'],
['medium213','last02'],
['medium213','medium101'],
['medium213','medium102'],
['medium213','medium103'],
['medium213','medium104'],
['medium214','last01'],
['medium214','last02'],
['medium214','medium101'],
['medium214','medium102'],
['medium214','medium103'],
['medium214','medium104'],
['medium215','last01'],
['medium215','last02'],
['medium215','medium101'],
['medium215','medium102'],
['medium215','medium103'],
['medium215','medium104'],
['medium216','last01'],
['medium216','last02'],
['medium216','medium101'],
['medium216','medium102'],
['medium216','medium103'],
['medium216','medium104'],
['medium101','medium201'],
['medium101','medium202'],
['medium101','medium203'],
['medium101','medium204'],
['medium101','medium205'],
['medium101','medium206'],
['medium101','medium207'],
['medium101','medium208'],
['medium101','medium209'],
['medium101','medium210'],
['medium101','medium211'],
['medium101','medium212'],
['medium101','medium213'],
['medium101','medium214'],
['medium101','medium215'],
['medium101','medium216'],
['medium101','first104'],
['medium101','first103'],
['medium101','first102'],
['medium101','first101'],
['medium102','medium201'],
['medium102','medium202'],
['medium102','medium203'],
['medium102','medium204'],
['medium102','medium205'],
['medium102','medium206'],
['medium102','medium207'],
['medium102','medium208'],
['medium102','medium209'],
['medium102','medium210'],
['medium102','medium211'],
['medium102','medium212'],
['medium102','medium213'],
['medium102','medium214'],
['medium102','medium215'],
['medium102','medium216'],
['medium102','first104'],
['medium102','first103'],
['medium102','first102'],
['medium102','first101'],
['medium103','medium201'],
['medium103','medium202'],
['medium103','medium203'],
['medium103','medium204'],
['medium103','medium205'],
['medium103','medium206'],
['medium103','medium207'],
['medium103','medium208'],
['medium103','medium209'],
['medium103','medium210'],
['medium103','medium211'],
['medium103','medium212'],
['medium103','medium213'],
['medium103','medium214'],
['medium103','medium215'],
['medium103','medium216'],
['medium103','first104'],
['medium103','first103'],
['medium103','first102'],
['medium103','first101'],
['medium104','medium201'],
['medium104','medium202'],
['medium104','medium203'],
['medium104','medium204'],
['medium104','medium205'],
['medium104','medium206'],
['medium104','medium207'],
['medium104','medium208'],
['medium104','medium209'],
['medium104','medium210'],
['medium104','medium211'],
['medium104','medium212'],
['medium104','medium213'],
['medium104','medium214'],
['medium104','medium215'],
['medium104','medium216'],
['medium104','first104'],
['medium104','first103'],
['medium104','first102'],
['medium104','first101'],
['first101','medium104'],
['first101','medium103'],
['first101','medium102'],
['first101','medium101'],
['first102','medium104'],
['first102','medium103'],
['first102','medium102'],
['first102','medium101'],
['first103','medium104'],
['first103','medium103'],
['first103','medium102'],
['first103','medium101'],
['first104','medium104'],
['first104','medium103'],
['first104','medium102'],
['first104','medium101'],
]
}]
};
Highcharts.chart('container', options);
Highcharts.chart('container2', options);
#container {
min-width: 320px;
max-width: 800px;
margin: 0 auto;
}
#container2 {
min-width: 320px;
max-width: 400px;
margin: 0 auto;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/networkgraph.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container"></div>
I have a Kendo TreeList where I search for the row where myDataItem is (with help of the uid or value).
When I execute:
$("#treeList tbody").on("click", "tr", function (e) {
var rSelectedRow = $(this);
var getSelect = treeList.select();
console.log("'real' selected row: "+rSelectedRow);
console.log("selected row: "+getSelect);
});
and in another function, where I want to get a row (not the selected one, just a row where myDataItem is):
var grid = treeList.element.find(".k-grid-content");
var myRow = grid.find("tr[data-uid='" + myDataItem.uid + "']"));
//or
// myRow = treeList.content.find("tr").eq(myDataItem.val);
console.log("my row:" + myRow)
I get:
'real' selected row: Object [ tr.k-alt ... ]
selected row: Object { length: 0 ... }
my row: Object { length: 0 ... }
I need the same structure of rSelectedRow for myRow. So how can I get the ,real' tr-element?
UPDATE: I wrote this method to find the row of my new added item:
//I have an id of the item and put it in an invisible row in the treelist.
getRowWhereItem: function (itemId) {
treeList.dataSource.read();
$("#menuItemTree .k-grid-content tr").each(function (i) {
var rowId = $(this).find('td:eq(1)').text();
console.log(itemId);
console.log(rowId);
if (rowId == itemId) {
console.log("found");
console.log(itemId + " " + rowId);
var row = this;
console.log(row);
return row;
}
});
},
The each-iteration reaches all tr's until/except the new added one. Why?
Use the change event instead of binding a click event to the widget's DOM. Note that for change to work, you need to set selectable to true:
<!-- Orginal demo at https://demos.telerik.com/kendo-ui/treelist/index -->
<!DOCTYPE html>
<html>
<head>
<base href="https://demos.telerik.com/kendo-ui/treelist/index">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.911/styles/kendo.material.mobile.min.css" />
<script src="https://kendo.cdn.telerik.com/2018.3.911/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.911/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example">
<div id="treelist"></div>
<script id="photo-template" type="text/x-kendo-template">
<div class='employee-photo'
style='background-image: url(../content/web/treelist/people/#:data.EmployeeID#.jpg);'></div>
<div class='employee-name'>#: FirstName #</div>
</script>
<script>
$(document).ready(function() {
var service = "https://demos.telerik.com/kendo-ui/service";
$("#treelist").kendoTreeList({
dataSource: {
transport: {
read: {
url: service + "/EmployeeDirectory/All",
dataType: "jsonp"
}
},
schema: {
model: {
id: "EmployeeID",
parentId: "ReportsTo",
fields: {
ReportsTo: { field: "ReportsTo", nullable: true },
EmployeeID: { field: "EmployeeId", type: "number" },
Extension: { field: "Extension", type: "number" }
},
expanded: true
}
}
},
height: 540,
filterable: true,
sortable: true,
columns: [
{ field: "FirstName", title: "First Name", width: 280,
template: $("#photo-template").html() },
{ field: "LastName", title: "Last Name", width: 160 },
{ field: "Position" },
{ field: "Phone", width: 200 },
{ field: "Extension", width: 140 },
{ field: "Address" }
],
pageable: {
pageSize: 15,
pageSizes: true
},
/* See here */
selectable: true,
change: function() {
let $selectedItem = this.select(),
dataItem1 = this.dataItem($selectedItem),
uid1 = $selectedItem.data("uid"),
uid2 = dataItem1.uid,
dataItem2 = this.dataSource.getByUid(uid1);
console.log("selected item", $selectedItem);
console.log("dataItem", dataItem1);
console.log("dataItem(alternative way)", dataItem2);
console.log("uid", uid1);
console.log("uid(alternative way)", uid2);
}
});
});
</script>
<style>
.employee-photo {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-left: 5px;
}
.employee-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 3px;
}
</style>
</div>
</body>
</html>
The part that really matters:
selectable: true,
change: function() {
let $selectedItem = this.select(),
dataItem1 = this.dataItem($selectedItem),
uid1 = $selectedItem.data("uid"),
uid2 = dataItem1.uid,
dataItem2 = this.dataSource.getByUid(uid1);
console.log("selected item", $selectedItem);
console.log("dataItem", dataItem1);
console.log("dataItem(alternative way)", dataItem2);
console.log("uid", uid1);
console.log("uid(alternative way)", uid2);
}
Demo
I didn't find a solution where I can get the tr by datauid.
But in my case, I took the id of the item and put it in an invisible row in the treelist.
Therefore, the method getRowWhereItem(itemId) in the question works well when making it execute after a successfull Ajax Call. With the callback from my ajax call, I load the new item and then the method can find the row. So the issue was that I had to have the uptodate data from my database.
Another issue was with contexts. The method getRowWhereItem(itemId) was a method of a namespace. I tried to call that method outside the namespace and couldn't get its return. Now, I moved the method into the same context where I call it.
(note: My development follows the MVC pattern, Administration is a Controller-class)
$.ajax({
url: General.createMethodUrl("Administration", "Admin", "Add_New"),
data: { parentItemId: parentOfNewId },
type: "POST",
dataType: "json",
success: function (response) {
if (response) {
var addedItem = $.parseJSON(response);
//waiting for callback because otherwise the window opens a few milliseconds before the properties are loaded and newRow cannot be find
tManag.ajaxCallSelectedEntry(addedItem.Id, treeList, function () {
newRow = tManag.getRowWhereItem(addedItem.Id);
});
jQuery(newRow).addClass("k-state-selected")
} else {
tManag.alertDialog(dialog, "Adding New Item Notification", response.responseText);
}
},
error: function (response) {
tManag.alertDialog(dialog, "Adding New Item Error", "Error");
}
});
How can I add my own style with a class css in quilljs?
I have this following css class
.ql-editor spanblock {
background-color: #F8F8F8;
border: 1px solid #CCC;
line-height: 19px;
padding: 6px 10px;
border-radius: 3px;
margin: 15px 0;
}
and an event targeting this CSS transformation
var toolbarOptions = [
[{ "header": [false, 1, 2, 3, 4, 5, 6] }, "bold", "italic"],
[{ "list": "ordered"}, { "list": "bullet" }, { "indent": "-1"}, { "indent": "+1" }],
["blockquote","code-block", "span-block","link", "hr"]
];
var quill = new Quill("#form_field_" + options.id + " .editor-container > .editor", {
modules: {
toolbar: toolbarOptions
},
theme: "snow"
});
var toolbar = quill.getModule("toolbar");
toolbar.addHandler("span-block", function(){});
var spanBlockButton = document.querySelector(".ql-span-block");
spanBlockButton.addEventListener("click", () => {
let range = quill.getSelection(true);
// what should I add here
}
I cannot find anything in the documentation of quilljs
https://quilljs.com
thank you
Basically you have to extend Parchment blots to have custom styled element in quill.
I went through this tutorial here and here.
Following is the simple html
<link href="http://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<link href="http://cdn.quilljs.com/1.3.6/quill.bubble.css" rel="stylesheet">
<link href="http://cdn.quilljs.com/1.3.6/quill.core.css" rel="stylesheet">
<style>
.ql-spanblock:after {
content: "<spanblock/>";
}
.spanblock {
background-color: #F8F8F8;
border: 1px solid #CCC;
line-height: 19px;
padding: 6px 10px;
border-radius: 3px;
margin: 15px 0;
}
</style>
<div id="editor">
</div>
Here is the actual answer,I have extended blots/inline in following way to wrap selected text into a div with desired class.
<script src="http://cdn.quilljs.com/1.3.6/quill.min.js"></script>
<script type="text/javascript">
let Inline = Quill.import('blots/inline');
class SpanBlock extends Inline{
static create(value){
let node = super.create();
node.setAttribute('class','spanblock');
return node;
}
}
SpanBlock.blotName = 'spanblock';
SpanBlock.tagName = 'div';
Quill.register(SpanBlock);
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script':'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'], // remove formatting button
['link', 'image', 'video'],
['spanblock']
];
var quill = new Quill('#editor', {
modules: {
toolbar: toolbarOptions
},
theme: 'snow'
});
var spanBlockButton = document.querySelector('.ql-spanblock');
//event listener to spanblock button on toolbar
spanBlockButton.addEventListener('click', function() {
var range = quill.getSelection();
if(range){
quill.formatText(range,'spanblock',true);
}else{
}
}
);
</script>
Codepen-demo.
Quite late to the scene, but it seems there's a better way to do this (than the previous answers) through Parchment's Attributor Class, hence this post.
Parchment Class Attributors and the Quill toolbar handlers are in-built ways to let you do exactly that, without having to create a new Blot.
Just register a new Class Attributor for span-block:
Parchment = Quill.import('parchment');
let config = { scope: Parchment.Scope.BLOCK };
let SpanBlockClass = new Parchment.Attributor.Class('span-block', 'span', config);
Quill.register(SpanBlockClass, true);
and attach a handler to format (or removeFormat if already formatted) for the toolbar button (rather than a separate event listener):
// ...
toolbar: {
container: toolbarOptions,
handlers: {
'span-block': function() {
var range = quill.getSelection();
var format = quill.getFormat(range);
if (!format['span-block']) {
quill.format('span-block', 'block');
} else {
quill.removeFormat(range.index, range.index + range.length);
}
}
}
}
// ...
Here's a demo (Or if you prefer, see it on Codepen)
Parchment = Quill.import('parchment');
let config = { scope: Parchment.Scope.BLOCK };
let SpanBlockClass = new Parchment.Attributor.Class('span-block', 'span', config);
Quill.register(SpanBlockClass, true)
var toolbarOptions = [
[{ "header": [false, 1, 2, 3, 4, 5, 6]}, "bold", "italic"],
[{"list": "ordered"}, {"list": "bullet"}, {"indent": "-1"}, {"indent": "+1"}],
["blockquote", "code-block", "span-block", "link"]
];
var icons = Quill.import('ui/icons');
icons['span-block'] = 'sb';
var quill = new Quill("#editor-container", {
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
'span-block': function() {
var range = quill.getSelection();
var format = quill.getFormat(range);
if (!format['span-block']) {
quill.format('span-block', 'block');
} else {
quill.removeFormat(range.index, range.index + range.length);
}
}
}
}
},
theme: "snow"
});
#editor-container {
height: 375px;
}
.ql-editor .span-block {
background-color: #F8F8F8;
border: 1px solid #CCC;
line-height: 19px;
padding: 6px 10px;
border-radius: 3px;
margin: 15px 0;
}
<link href="//cdn.quilljs.com/1.2.4/quill.snow.css" rel="stylesheet" />
<script src="//cdn.quilljs.com/1.2.4/quill.js"></script>
<div id="editor-container"></div>
#moghya's answer has a problem for me: I can't redraw the content from generated html, the element will loose the added class name.
I fixed it by add a formats() method and set the className. See my demo below.
let Block = Quill.import('blots/block');
var icons = Quill.import('ui/icons');
// Lottery tooltip
class LotteryTitle extends Block {
static create() {
let node = super.create();
node.setAttribute('class', this.className);
return node;
}
static formats(domNode) {
return true;
}
}
LotteryTitle.blotName = 'lottery-title';
LotteryTitle.className = "sc-lottery-title"
Quill.register(LotteryTitle);
icons['lottery-title'] = icons.header["2"];
It's a little bit complicated to explain. I would like to save the position on which the tree has been repositioned, and then when the user opens the page again it will appear the way the user left it (I do not want to make it only for one user but for all, because only the admin is going to have access to it anyway). it sounds ununderstandable, that's why I made an example right below:
Simplifying: 1 - Get the order of the tree's elements that the user left
2 - Send it to my server as a text file (Probably Ajax)
Thus, when I reload the page or/and clean up the cache, it will still be in that position that I left. I want the "position" to be sent as a text file using ajax to my server. Is there a way to do it?
Thanks in advance.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="./tree.jquery.js"></script>
<link rel="stylesheet" href="./jqtree.css">
<script src="./jquery-cookie/src/jquery.cookie.js"></script>
<style>
body{overflow-x:hidden}
#navdata{width:auto; height:auto; flex:1; padding-bottom:1px;}
#navgrid{width:50%; height:200px; overflow-x:hidden; overflow-y:scroll; border:solid 1px #79B7E7; background-color:white;}
#header{background-color: #79B7E7; width:100%; text-align: center;border: 1px solid white;}
.jqtree-element{background-color:#DDEBF7;border: 1px solid white;height:23px;color:red;}
.jqtree-tree .jqtree-title {color: black;}
ul.jqtree-tree ul.jqtree_common {margin-left: 0px;}
ul.jqtree-tree .jqtree-toggler {color: #325D8A;}
ul.jqtree-tree .jqtree-toggler:hover {color: #3966df;text-decoration: none;}
.jqtree-tree .jqtree-title.jqtree-title-folder {margin-left: 0;}
span.jqtree-dragging {background: #79B7E7;}
ul.jqtree-tree li.jqtree-selected > .jqtree-element,ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover {background: -webkit-gradient(linear, left top, left bottom, from(#BEE0F5), to(#79B7E7));}
</style>
</head>
<body>
<div id="navgrid">
<div id="header">Header</div>
<div id="tree1"></div>
</div>
</body>
<script type="text/javascript">
var ExampleData = {};
ExampleData.data = [
{
label: 'node1', id: 1,
children: [
{ label: 'child1', id: 2 },
{ label: 'child2', id: 3 }
]
},
{
label: 'node2', id: 4,
children: [
{ label: 'child3', id: 5 }
]
}
];
ExampleData.getFirstLevelData = function(nodes) {
if (! nodes) {
nodes = ExampleData.example_data;
}
var data = [];
$.each(nodes, function() {
var node = {
label: this.label,
id: this.id
};
if (this.children) {
node.load_on_demand = true;
}
data.push(node);
});
return data;
}
ExampleData.getChildrenOfNode = function(node_id) {
var result = null;
function iterate(nodes) {
$.each(nodes, function() {
if (result) {
return;
}
else {
if (this.id == node_id) {
result = this;
}
if (this.children) {
iterate(this.children);
}
}
});
}
iterate(ExampleData.example_data);
return ExampleData.getFirstLevelData(result.children);
}
$('#tree1').tree({
data: ExampleData.data,
autoOpen: false,
dragAndDrop: true
});
</script>
</html>
I think earlier i got your question wrong. This will be your answer.
$(document).ready(function(){
//var data is a dynamic json file that should be created in the backend.
var data = [
{
label: 'node1', id: 1,
children: [
{ label: 'child1', id: 2 },
{ label: 'child2', id: 3 }
]
},
{
label: 'node2', id: 4,
children: [
{ label: 'child3', id: 5 }
]
}
];
$('#tree1').tree({
data: data,
autoOpen: true,
dragAndDrop: true
});
console.log($('#tree1').tree('toJson')); //This will give you the loading jqtree structure.
$('#tree1').bind(
'tree.move',
function(event) {
event.preventDefault();
// do the move first, and _then_ POST back.
event.move_info.do_move();
console.log($(this).tree('toJson')); //this will give you the latest tree.
// $.post('your_url', {tree: $(this).tree('toJson')}); //this will post the json of the latest tree structure.
}
);
});
Updating the Code with HTML/JS/PHP with
Folder Structure
Root Folder
stackoverflow-2.html
libs/jquery/jquery.js
libs/jqtree/tree.jquery.js
libs/jqtree/jqtree.css
scripts/stackoverflow-2.js //custom script created by me
json/stackoverflow-2.json //json file output to create the nodes and children.
php/stackoverflow-2.php //php commands to write.
stackoverflow-2.html //same as your reference. Changed only mapping of the library files.
<head>
<script type="text/javascript" src="libs/jquery/jquery.min.js"></script>
<script src="libs/jqtree/tree.jquery.js"></script>
<link rel="stylesheet" href="libs/jqtree/jqtree.css">
<script src="scripts/stackoverflow-2.js"></script>
<style>
body{overflow-x:hidden}
#navdata{width:auto; height:auto; flex:1; padding-bottom:1px;}
#navgrid{width:50%; height:200px; overflow-x:hidden; overflow-y:scroll; border:solid 1px #79B7E7; background-color:white;}
#header{background-color: #79B7E7; width:100%; text-align: center;border: 1px solid white;}
.jqtree-element{background-color:#DDEBF7;border: 1px solid white;height:23px;color:red;}
.jqtree-tree .jqtree-title {color: black;}
ul.jqtree-tree ul.jqtree_common {margin-left: 0px;}
ul.jqtree-tree .jqtree-toggler {color: #325D8A;}
ul.jqtree-tree .jqtree-toggler:hover {color: #3966df;text-decoration: none;}
.jqtree-tree .jqtree-title.jqtree-title-folder {margin-left: 0;}
span.jqtree-dragging {background: #79B7E7;}
ul.jqtree-tree li.jqtree-selected > .jqtree-element,ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover {background: -webkit-gradient(linear, left top, left bottom, from(#BEE0F5), to(#79B7E7));}
</style>
</head>
<body>
<div id="navgrid">
<div id="header">Header</div>
<div id="tree1"></div>
</div>
</body>
stackoverflow-2.js
$(document).ready(function(){
$.ajax({ /*Makes a ajax call and gets the contents from the json file*/
method:"get",
url:"json/stackoverflow-2.json"
}).success(function(data){
$('#tree1').tree({
data: jQuery.parseJSON(data.tree),
autoOpen: true,
dragAndDrop: true
});
});
$('#tree1').bind(
'tree.move',
function(event) {
event.preventDefault();
// do the move first, and _then_ POST back.
event.move_info.do_move();
$.post('php/stackoverflow-2.php', {tree: $(this).tree('toJson')}); //this will post the json of the latest tree structure.
}
);
});
Initial stackoverflow-2.json
{
"tree": [
{
"label": "node1",
"id": 1,
"children": [
{
"label": "child1",
"id": 2
},
{
"label": "child2",
"id": 3
}
]
},
{
"label": "node2",
"id": 4,
"children": [
{
"label": "child3",
"id": 5
}
]
}
]
}
stackoverflow-2.php
<?php
file_put_contents("../json/stackoverflow-2.json", json_encode($_POST)); //calls the file and enters the new tree structure.
Code tested in my localhost.
Referring to the jqtree documentation you can have your code like this.
var lastOpenedByAUser = 0; // make a ajax call to get this value. This value is also stored in database or any file in your server end if the last user clicked another node.
$('#tree1').tree({
data: data,
autoOpen: lastOpenedByAUser //shall be 0 for node-1, 1 for node-2
});
Make sure, you run this $('#tree') code only after the code your ajax code is completed.