Create tree with dynamic level function for nodes (movable nodes) using jQuery
2 answers
I created this idea with the following codes Here . anyone can use or extend it for free ...;)
I know it can be improved and made better, but now you can use it and enjoy ....
Features:
"" Support for keyboard arrow keys to move nodes (left and right)
"" Support for dragging nodes with mouse right and left
"" Store the level data of each node in the DOM and display it on each node
Thanks to @ FabrícioMatté for his answer here . I used some of my codes to create my jQuery class.
The result of my codes:
JS and jQuery
/*Code by Ram >> http://stackoverflow.com/users/1474613/ram */
(function ($) {
$.Noder = function (oneOfNodes) {
this.element = '';
oneOfNodes=(oneOfNodes instanceof $) ? oneOfNodes : $(oneOfNodes)
this.baseX=oneOfNodes.position().left;
this.currentX=0;
};
$.Noder.prototype = {
InitEvents: function () {
//`this` references the created instance object inside an instace method,
//however `this` is set to reference a DOM element inside jQuery event handler functions' scope.
//So we take advantage of JS lexical scope and assign the `this` reference to
//another variable that we can access inside the jQuery handlers
var that = this;
//I'm using `document` instead of `this` so it will catch arrow keys
//on the whole document and not just when the element is focused.
//Also, Firefox doesn't fire the keypress event for non-printable characters
//so we use a keydown handler
$(document).keydown(function (e) {
var key = e.which;
if (key == 39) {
that.moveRight();
} else if (key == 37) {
that.moveLeft();
}
});},
setElement: function(element){
this.element = (element instanceof $) ? element : $(element);
console.log(this.element);
this.currentX=this.element.position().left;
console.log('currentX: '+this.currentX);
this.element.addClass('active');
},
moveRight: function () {
console.log('bseX: '+this.baseX);
console.log('currentX: '+this.currentX);
var max=(25*2)+this.baseX;
console.log('max: '+max);
if(this.currentX<max)
{
this.element.css("left", '+=' + 25);
this.currentX=this.element.position().left;
setElementLevel(this.element,this.currentX,this.baseX);
console.log('currentX: '+this.currentX);
}
},
moveLeft: function () {
if(this.currentX>this.baseX)
{
this.element.css("left", '-=' + 25);
this.currentX=this.element.position().left;
setElementLevel(this.element,this.currentX,this.baseX);
console.log('currentX: '+this.currentX);
}
}
};
$.Noder.defaultOptions = {
currentX: 0
};
}(jQuery));
function setElementLevel(element,currentX,baseX){
var level=0;
if (currentX==baseX+25)
level=1;
else if(currentX==baseX+25+25)
level=2;
element.data('level', level);
setLevelOnElement(element);
}
function getElementLevel(element){
console.log(element.data('level'));
return element.data('level');
}
function setLevelOnElement(element){
var level = 0;
if(typeof getElementLevel(element) !=='undefined')
level = getElementLevel(element);
console.log('my level: '+level);
var $levelElement=element.find( ".node-level" );
if ($levelElement && $levelElement.length>0)
{
$levelElement=$($levelElement[0]);
console.log($levelElement);
$levelElement.html(level);
}
}
var noder = new $.Noder($("#myTree>.node")[0]);
$("#myTree>.node").on('click',function(){
$("#myTree>.node").each(function(){
$(this).removeClass('active')
});
console.log($(this)[0].id +' clicked')
noder.setElement($(this)[0]);
})
noder.InitEvents();
$(document).ready(function() {
var $dragging = null;
var $myTree=$('ul#myTree');
var $oneOfNodes=null;
var baseX=0;
if($myTree.length>0)
{
console.log($myTree);
$oneOfNodes=$($myTree.children()[0]);
console.log($oneOfNodes);
baseX=$oneOfNodes.position().left;
console.log('baseX >> '+baseX);
console.log($myTree);
var x=0;
$('ul#myTree').find('li').each(function(){
x++;
console.log(x);
setLevelOnElement($(this));
});
}
$(document.body).on("mousemove", function(e) {
if ($dragging) {
var currentX=$dragging.position().left;
if(e.pageX>(baseX+25) && e.pageX<(baseX+(2*25)))
{
$dragging.offset({left: (baseX+25)});
setElementLevel($dragging,currentX,baseX);
}
else if((e.pageX)>(baseX+(2*25)) )
{
$dragging.offset({left: (baseX+(2*25))});
setElementLevel($dragging,currentX,baseX);
}
else if(e.pageX<(baseX+25) )
{
$dragging.offset({left: (baseX)});
setElementLevel($dragging,currentX,baseX);
}
}
});
$(document.body).on("mousedown", function (e) {
var $myTree=$('ul#myTree');
if($(e.target) && $myTree && $myTree.length>0)
{
var $li=$(e.target).parent();
var $ul=$(e.target).parent().parent();
if ( $ul.is($myTree) && $(e.target).hasClass("node-level") )
{
$ul.find('li').each(function(){
$(this).removeClass('active');
});
$li.addClass('active');
$dragging = $($li);
}
}
});
$(document.body).on("mouseup", function (e) {
$dragging = null;
});
});
Html
<ul id="myTree">
<li class="node" id="node1">
<span class="node-level"></span>
<span class="node-content">Node 1</span>
</li>
<li class="node" id="node2">
<span class="node-level"></span>
<span class="node-content">Node 2</span>
</li>
<li class="node" id="node3">
<span class="node-level"></span>
<span class="node-content">Node 3</span>
</li>
<li class="node" id="node4">
<span class="node-level"></span>
<span class="node-content">Node 4</span>
</li>
<li class="node" id="node5">
<span class="node-level"></span>
<span class="node-content">Node 5</span>
</li>
<li class="node" id="node6">
<span class="node-level"></span>
<span class="node-content">Node 6</span>
</li>
<li class="node" id="node7">
<span class="node-level"></span>
<span class="node-content">Node 7</span>
</li>
</ul>
CSS
#myTree{
margin:20px;
padding:0;
list-style-type:none;
font-size:11px;
}
#myTree>li>.node-level{
padding:6px 10px;
color:#ddd;
background:gray;
position:relative;
cursor:move;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#myTree>li>.node-content{
padding:5px; 15px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#myTree>.node:hover {
background:#acd;
color:#004;
}
#myTree>.node.active {
border:1px #a66 solid;
background:#fd8;
color:#004;
}
#myTree>li.node {
width:151px;
background:#ddd;
margin-top:2px;
padding:5px 0px 5px 0;
color:#555;
cursor:pointer;
position:relative;
border:1px solid #ccc;
}
html, body {
height:100%;
}
div { width:151px;
background:#ddd;
margin-top:2px;
padding:5px 15px;
color:#555;
cursor:pointer;
position:relative;
border:1px solid #ccc; }
0
source to share