In the process of working on one of the projects, I was faced with the task of creating a collapsible folder tree based on information about it in the database. To clarify, it looks like this:

Actually, the task was the following: on the server in the database table is stored the directory tree structure, which after certain transformations should appear in the above form.
We have the following table structure in the database:
id - string identifier
level - the level of the element
left_key - left key
right_key - right key
caption - the name of the directory.
You can learn more about creating such a table
here .
Through AJAX, this data, sorted by the value of the left_key field, goes to the client, where we have to build a nested list based on them.
The list should have the following structure:
<ul>, : <li>, . , <span>, . , <ul> ... ...
We proceed to the generation of the tree.
First of all, you need to create a function that returns the child elements or an empty array if they are missing.
var getChilds = function(trgt, arr){ var childs = Array(); var length = arr.length; for (var i = 0; i < length; i++){ var curr = getInts(arr[i]); var under = (curr.level > trgt.level) ; var l_in = (curr.left_key > trgt.left_key); var r_in = (curr.right_key < trgt.right_key); if (under && l_in && r_in) childs.push(arr[i]); } return childs; }
This function does nothing more than checking each element of an array for a given element of the same array, that is: if the level of the element in question is lower than the level of a given element, while the left and right keys are respectively between the left and right keys of a given element, then write the element in question into the array of child elements.
The getInts function in this case is engaged in converting the values of the level, left_key and right_key fields into numeric values. This is necessary in order to compare numbers, not strings.
var getInts = function(arr){ temp = Object(); for (var i in arr){ if (i!='name') temp[i] = parseInt(arr[i]) else temp[i] = arr[i] return temp }
After getting the children, you need to clear the original array from them. I didn’t think of anything better than writing another function.
var cleanDuplicates = function(from, elements){ var length = arr.length; for (var i = 0; i < length; i++){ if ($.inArray(from[i], elements) > -1) delete from[i] } return from; }
Here, the elements array contains the elements that need to be removed from the from array.
And finally, we build the list using the above functions.
var ul = function(arr){ if (!arr[0]) return '' else{ var html = '<ul>'; var length = arr.length; for (var i = 0; i < length; i++){ var el = arr[i]; var childs = getChilds(el, arr); arr = cleanDuplicates(arr, childs) html += '<li>'+'<span id="cat_'+el.id+'">'+el.name+'</span>' html += ul(childs) html += '</li>' } return html + '</ul>' } }
Usage example:
'<div class="tree">' + ul(data) + '</div>'
where data is the data received from the server.
For the final transformation of this list into a tree menu, there is a sufficiently large number of plug-ins for jQuery, for example
jQuery Treeview .
Work with him is quite simple. You must first connect
jQuery itself, then this plugin. After connecting, it is enough just to set it on the block containing your generated list. If to take from an example, it is an element $ ('. Tree').
$('.tree').treeview();
As a result, we have a tree-like menu that supports minimizing / expanding on clicking on a folder (the expanded tree of folders is built by default, but thanks to the plugin settings, options are possible, read more
here ).
')
PS Please note that the jQuery Treeview plugin no longer develops, but to build a simple tree-like menu of functions of this plugin is more than enough. The developer himself proposes using the
JqTree plugin.