📜 ⬆️ ⬇️

State-level multi-level tree with markers (HTML, CSS, jQuery, Cookies)

The development of the multi-level tree with markers continues. Multi-level tree with state saving nodes
Now the tree has grown and strengthened, it has become more mature and remembers the selected node and the state of each node separately.
The page can be reloaded, and the tree will still remember everything that you have discovered and selected!


To save the state used cookies and jquery.cookies.js plugin. Working with cookies is very simple .

Html preparation


The tree will work if the basic condition is met - to arrange the html in the following form:
< div id ="multi-derevo" >
< h4 >< a href ="#" > </ a ></ h4 >
< ul >
< li >< span >< a href ="#1" > 1. </ a ></ span >
< ul >
< li >< span >< a href ="#11" > 1.1. </ a ></ span >
< ul >
< li >< span >< a href ="#111" > 1.1.1. </ a ></ span ></ li >
< li >< span >< a href ="#112" > 1.1.2. </ a ></ span ></ li >
< li >< span >< a href ="#113" > 1.1.3. </ a ></ span ></ li >
</ ul >
</ li >
</ ul >
</ li >
< li >< span >< a href ="#2" > 2. </ a ></ span ></ li >
</ ul >
</ div ><! -- / multi-derevo -- >


To create a sublevel, it is sufficient to insert a nested list of the same structure after the node header.
')
In principle, the depth of the attachment is not limited, but since all elements are loaded immediately, you risk getting traffic and long waiting, so be vigilant.

Updated tree script


All explanations in the comments code.
/*
(c) 2009 r3code.habrahabr.ru


: HTML .
r3code.habrahabr.ru/blog/59823

.
.
- (/).
- ,
, .
- (.current)
.
-
.
- (./.) cookies.
- cookies .

19/05/2009
*/
//=================================================================================

$( document ).ready( function () {
/* , .
'li' 'ul',
, .. 'li' 'a'
'<em class="marker"></em>'.
a:first , 1
.
*/
var root = $( '#multi-derevo' );
// , (Nested set)
$( 'li' , root).each( function (index) {
this .id = 'n' + index;
});
$( 'li:has("ul")' , root).find( 'a:first' ).prepend( '<em class="marker"></em>' );

//
var current_id = $.cookie( 'current_node' );
if (current_id) $( '#' +current_id).find( 'a:first' ).toggleClass( 'current' );

//
//-----------------------------------
$( 'li span' , root).click( function () {
//
$( 'a.current' , root).removeClass( 'current' );
var a = $( 'a:first' , this .parentNode);
a.toggleClass( 'current' );
var current_id = a.parent( 'li' ).attr( 'id' );
//alert(a.parents('li').get(0).tagName+"#"+a.parents('li').attr('id'));
setCookie( 'current_node' ,a.parents( 'li' ).attr( 'id' ) || null );
//
toggleNode( this .parentNode);
});
//postLoad(); // url
openNodes(); // cookie
})

//---------------------------------------------------------------------------------
//
function toggleNode(Node) { // node= li
prepareLast(Node);
//
var ul=$( 'ul:first' ,Node); //
if (ul.length) { //
ul.slideToggle(200); //
// /
var em=$( 'em:first' ,Node); // this = 'li span'
// em.hasClass('open')?em.removeClass('open'):em.addClass('open');
em.toggleClass( 'open' );
saveTreeState();
}
}

//
function prepareLast(Node) {
/* ,
*/
$(Node).each( function (){
if (!$( this ).next().length) {
/* <li>, <ul>,
ul > li, 'last' */
$( this ).find( 'ul:first > li' ).addClass( 'last' );
}
})
}
//
function postLoad(){
var url = window.location.toString();
var max = 0;
var a = null ;
$( '#multi-derevo li span a' ).each( function (){
//
if (url.indexOf( this .href) >= 0 && this .href.length > max){
a = this ;
max = this .href.length;
}
});
// ,
if ($(a). is ( ':hidden' ) || $(a).parents( ':hidden' ).length) {
var li = $(a).parents().filter( 'li' );
prepareLast(li);
toggleNode(li);
}
//
if (a) {
$(a).toggleClass( 'current' );
}
else { // , ( )
$( '#multi-derevo li span a:first' ).toggleClass( 'current' );
}
}

//
function GetOpenedNodes(items){ // li:has('ul')
var str = [];
$(items).each( function () {
var res = $( this ).attr( 'id' );
var state = $( 'em:first' , this ).hasClass( 'open' ) ? 1 : '' ;
if (res && state){
str.push(res);
}
});
return str.join( ',' );
}

//
function saveTreeState(){
var open_id = GetOpenedNodes($( '#multi-derevo li:has("ul")' )) || null ;
setCookie( "open_nodes" , open_id);
return false ;
}

//
function openNodes(){
//
var open_nodes = $.cookie( "open_nodes" );
if (open_nodes) {
var nodes = open_nodes.split( ',' );

if (nodes[0]){
for ( var node in nodes){
nodes[node] = '#' + nodes[node];
}
var ids = nodes.join( ',' );
$(ids).each( function () {
toggleNode($( this ));
});
}
}
return false ;
}

// Cookies 1
function setCookie(name, value){
var DAY = 24 * 60 * 60 * 1000;
var date = new Date();
date.setTime(date.getTime() + (1 * DAY)); // 1
$.cookie(name, value, {expires: date});
// alert("Cookie set: "+name+"="+value);
}



Of course, I would like to refactor the code, taking into account the jQuery capabilities, this version is written as I know. Do not give up useful thoughts to improve the appearance of this code.

Script at work


See a working example .

Example 2 Markers are placed to the left so that the text is aligned one vertical line at the same level. Modified CSS and script.

UPD 05/19/2009
Refused to save the state of the tree when unload - Opera does not support. Now the state of the tree is saved when clicking on a node. Sample and script updated.

UPD 02/24/2012
Made another design option as requested by sanch3z
habrahabr.ru/blogs/webdev/59823/#comment_1641197

Source: https://habr.com/ru/post/59823/


All Articles