Български

  jsTree v.0.7

August 20, 2008

jsTree v.0.7

Filed under: Tech — Tags: , , — vakata @ 12:19 am

A even newer revision is available in the SVN, it includes fixes for almost all comments on this post so far, except for the multitree, which needs a lot of work. A new version will be out soon when I’m done with the documentation and examples.

Version 0.7 is out, though not throughly tested - I will keep testing so bear with me and submit any bugs or strange behavior you encounter.

  • Native support for async data loading is added (either JSON or XML)
  • A new “lock()” function is available to block any user interaction with the tree.
  • Customization of various strings used throughout the code (e.g. “New Folder”, “Loading …”) is now possible - you can now pass your own strings and even assign them to a language version.
  • There is a new hover_mode setting which forces the tree to change only the hover state and not the focus when using the get_* functions (usually used with keyboard shortcuts).
  • The options object is refactored - meaning that your current configs will not be functional!!! I’m sorry for this inconvineince but the options object was getting crowded and messy - now it is divided in groups - you can see a description in the documentation.
  • A setting was added so that now multiple selection is either always on, always off, or based on the Ctrl key (also fixed a couple of bugs with multiple selection).
  • A onrgtclk callback was added - so now you can display your own menu, and prevent the browser default.
  • The optional single-language XML structure is removed!!!. I noticed that nobody used it and it was rather confusing - now the xml structure is the same even if you have, or don’t have language versions.
  • Also a few other bugs were fixed.

All of the new stuff is included in the documentation. I’m working on the examples and downloader. I rushed this version out, as I might not be able to publish anything in the upcoming week. Still, I’ll be thankful for any ideas and critics you may have, so any feedback will be highly appreciated.

Thank you for all your ideas and contributions - I tried to include most of it in this version. If I missed a few things - remind me :). Let’s continue improving jsTree.

56 Comments »

  1. hi,i just download your jsTree v.0.7 and trying to intergrate it into my project, and i think it’s the best tree i’ve ever seen, so brilliant and useful!!
    Also,i found something that maybe you can improved in the fulture:
    1,need onclick method in the callback.
    2,i wish i can add html code into the nodes,like checkbox.
    i’m looking forward to your next version, great work! ^^

    Comment by ZhangLei — August 27, 2008 @ 5:03 am

  2. Thanks man! This is awesome as always. Looking forward to some docs! :P

    Comment by Atom — August 27, 2008 @ 6:05 pm

  3. when using async data, what do you send if the node it is asking about has no children.

    I send an empty list [] and it sends the script into an endless loop trying to GET the children of that node.

    If I send nothing, it just says loading… for ever.

    Comment by William — August 27, 2008 @ 9:52 pm

  4. Another bug in async mode.

    If I drag a node into a closed node(which has not yet been opened), when I open the node, it does not check to see if there are other children.

    Comment by William — August 27, 2008 @ 10:35 pm

  5. Hi,

    I have been using version 0.7 and I think I have found a bug, on the create/open_branch methods.

    When you try and create a new node/leaf on a closed node/leaf, It just opens the leaf that you where creating the node on. This only happens on non-async mode.

    I think the problem is on the code starting on line 804

    if(parseInt(this.settings.ui.animation) > 0 && !disable_animation && !($.browser.msie && $.browser.version < 7) )

    {

    obj.children(”ul:eq(0)”).css(”display”,”none”); obj.removeClass(”closed”).addClass(”open”); obj.children(”ul:eq(0)”).slideDown(parseInt(this.settings.ui.animation), function() {

    $(this).css(”display”,”");

    });

    } else obj.removeClass(”closed”).addClass(”open”); this.set_cookie(”open”); this.settings.callback.onopen.call(null, obj.get(0), this);

    }

    This code, IMHO, should call the callback function passed on the open_branch method, but it doesn’t, I think a quick fix would be adding

    if(callback) callback.call();

    after

    this.settings.callback.onopen.call(null, obj.get(0), this);

    One other thing and this is just a sugestion, I think it would be pretty useful, for the create method to return the created node.
    Thanks

    Comment by Nuno Mota — August 28, 2008 @ 6:12 am

  6. Thanks for the bug submissions, I’ll get to fixing right away. Sorry for the delay - I just don’t have access to the internet. I guess it will be another week till I’m home and can update the svn and release a next minor version.

    Comment by vakata — August 28, 2008 @ 5:34 pm

  7. Hi again,

    I just detected something that might I think is a bug. First let me explain how my tree is defined I have the following css:

    li.open a {
    background-image:url(”/images/tree_images/folderOpen.gif”);
    text-transform: uppercase;
    }
    li.closed a {
    background-image:url(”/images/tree_images/folderClosed.gif”);
    text-transform: uppercase;
    }
    li.leaf a {
    background-image:url(”/images/tree_images/leaf.gif”);
    text-transform: uppercase;
    }

    Now, when I have a leaf that only has one element in it and I remove that element, the element is removed and the parent leaf is now empty, the icon remains as an opened icon.

    The code that does this is:

    line 990: $li.removeClass(”open”).removeClass(”closed”).children(”ul”).remove().addClass(”leaf”);

    Now when I have the same situation as I had before removing the node, and move the leaf out of his parent leaving it as en empty parent, the icon turns into the leaf icon thus loosing the class open, so different behaviour.

    The code that does this is:

    line 1086:
    $li.removeClass(”open”).removeClass(”closed”).addClass(”leaf”).children(”ul”).remove();

    Diferent order in the jquery expression, if I set it to be like the code on line 990, the behaviour is now consistent.

    I don’t now wich should be the proper behaviour, the one that is happening with the move operation, or the delete one, in my particular example, I prefer the delete behaviour, but I think the logic should be using the move operation.

    Quick fix, copy line 1086 into line 990, or vice-versa depending on what the original intention was.

    Comment by Nuno Mota — September 2, 2008 @ 12:29 pm

  8. Another bug.

    When using multitree: When moving a node to a different tree it does not check if that move is permitted. It does not check if the target is locked or the move is against the drag-rules.

    Comment by William — September 3, 2008 @ 6:51 pm

  9. When you make a move where TYPE=’inside’ it always adds it as the first child. Even if the createat=’bottom’. This seems unexpected. I expected that move inside would move it to first-child when createat=’top’ ad last-child when createat=’bottom’

    Comment by William — September 3, 2008 @ 11:14 pm

  10. @Nuno

    Will fix right away.

    @William

    Multitree needs a lot of work - I have a few things on the TODO list and rules & lock check are one of them. Thanks.

    As for the insertion - good point - I did not think of that :) I will check and fix right away.

    Expect a new version beginning next week.

    Comment by vakata — September 4, 2008 @ 1:53 pm

  11. Hi
    Thanks for this great work. please submit some example so that I can understand what to do with it in json mode. i have no idea how to use it and documentation could not help me.
    I want to have some closed node so that when user click on them, node receive its children via json. please tell me how to do that.

    Comment by bone_collector363 — September 8, 2008 @ 3:12 pm

  12. Hi!
    Maybe those who tell how to build a tree from json. Of the documentation can not understand. What you need to change settings when compared with those on the site which in the example. Thank you!

    Comment by evgen — September 18, 2008 @ 4:54 pm

  13. hi,vakata,may i know the address and account of your SVN?thanks!
    and by the way ,will you support contextmenu in v0.8?cause if not i’m going to build a menu by myself now :-)

    Comment by ZhangLei — September 19, 2008 @ 7:24 am

  14. Hi,

    I’m trying to modify leafs on creation or juste after the tree is loaded. For example by using JSON and this data:

    attributes: { id : “node_7″, rel : “param”, error: “5″ }

    I want to look at the error value of the leaf, and adapt css of the Node depending of the value.

    Unfortunately, there is no onloading callback for nodes. Is there an easy way to parse the Json tree and modify CSS after the tree is loaded ?

    Thx in advance

    Comment by Pimox — September 19, 2008 @ 9:32 am

  15. Thanks for the great work!

    Just a simple question: what settings to use that allows the predefined html on your example page to be draggable, renameable, deletable etc?

    I tried using the settings for the other examples but it would only allow me to drag with a “x” icon - i can’t drop the item at the new location.

    Comment by John — September 20, 2008 @ 11:31 am

  16. Great thing, one annoyance.. When doing ctrl-click selection, the onchange is called. If ctrl-click deselect occurs, onchange is not called… Only on selection is the callback done..

    Comment by jstreeuser — September 22, 2008 @ 4:36 pm

  17. BTW, fixed my problem by adding: this.settings.callback.onchange.call(null, this.selected.get(0), _this);

    to end of deselect_branch. An obvious method to overcome my problem

    Comment by jstreeuser — September 22, 2008 @ 4:40 pm

  18. I found a minor issue in version 0.7. When using async trees the id atribute of a node is passed back to the server script as url argument called ‘id’. However, this argument is not properly urlencoded. The fix is simple:
    File tree_component.js:
    Line 786 is this:
    var str = (this.settings.data.url.indexOf(”?”) == -1) ? “?id=” + this.escape(obj.attr(”id”)) : “&id=” + this.escape(obj.attr(”id”));

    I rewrote it like this:
    var str = (this.settings.data.url.indexOf(”?”) == -1 ? ‘?’ : ‘&’) + ‘id=’ + encodeURIComponent(obj.attr(”id”));

    Thanks!

    Arjan

    Comment by Arjan Haverkamp — September 23, 2008 @ 4:37 pm

  19. Sorry, for the “long time - no write” situation. It’s been a hectic few weeks.

    I’m still working on the examples - I’ll get them up as soon as possible. Anyway - I’ll do a quick demo on async JSON in the next few, as this seems to be most problematic for everyone.

    Thank you for the bug reports - I’ll include them in the next update.

    As for the onload callback when using async - I shall consider how to include that - in the mean time the onopen callback should do the trick - it is fired after content has loaded.

    As for the context menu - the event is processed and a callback is fired if attached.
    I believe it is better for everyone to attach a custom callback. I hope the API is good enough to do the job. An internal context menu would limit the user.
    Still, if I decide to include it somehow, it will be configurable - I just haven’t thought about that.

    Comment by vakata — September 23, 2008 @ 5:31 pm

  20. I’m not sure if I made myself very clear, but let me rephrase the question. Is there anyway to move nodes while using predefined HTML? I can’t seem to do it. These are the options I am using:

    data : {
    type : “predefined”,
    async : false,
    url : false,
    json : false
    },
    ui : {
    dots : false,
    rtl : false,
    animation : 0,
    hover_mode : true
    },
    rules : {
    multiple : false,
    metadata : false,
    type_attr : “rel”,
    multitree : false,
    createat : “bottom”,
    use_inline : false,
    clickable : “all”,
    renameable : “all”,
    deletable : “all”,
    creatable : “all”,
    draggable : “all”,
    dragrules : [
    "folder after folder",
    "folder before folder",
    "folder inside folder"
    ]
    }

    Comment by John — September 26, 2008 @ 7:35 am

  21. It would be very nice if you can define a “title” tag in the XML or JSON items, that would be shown when you hover over a tree node.
    Of course, this title attribute should also be available in the callback functions.
    When will the next version be available?

    Comment by Arjan Haverkamp — September 27, 2008 @ 11:56 am

  22. @John
    set dragrules to “all”
    or add a rel attribute “folder”, to all the nodes in the predefined HTML.

    @Arjan Haverkamp
    Just add a title attribute in the attributes object:
    attributes: {
    id : ‘ID_HERE’,
    title : ‘TITLE HERE’,
    ….
    }
    For XML - just the same - add the title attribute :)

    Comment by vakata — September 29, 2008 @ 10:24 am

  23. Setting dragrules to “all”, instead of an array did the trick. Thanks Ivan!

    Comment by John — September 29, 2008 @ 11:12 am

  24. Hi there,

    I am encountered a problem, maybe you can figure it out. Here is the link to my example: http://labs.autenticmedia.com/tree/index.html

    What i want to achieve, is to populate the tree through a php json file. (see http://labs.autenticmedia.com/tree/json.php). I want it to load the entire tree once. The idea is that is not working, and i think it has something to do with the id you are passing. I am not sure. Any help is really appreciated.

    Thx,
    Marius.

    Comment by Marius Bratu — October 2, 2008 @ 4:27 pm

  25. @Marius Bratu
    I checked the url - everything in the config seems fine, but you have an error in your php file. The GET parameter has nothing to do with it.

    Parse error: syntax error, unexpected ':' in /home/auten7/public_html/labs/tree/json.php on line 3

    Please check your syntax - if there are more errors I’ll take a look.

    Comment by vakata — October 2, 2008 @ 4:36 pm

  26. Wow,

    You answered so fast! Thx a lot. I see the error but i am not sure why i get it. Here what i have in the php file (http://labs.autenticmedia.com/tree/_json.txt). I am a little confused on the exact structure of this file. The json structure its fine, i have checked it in a json syntax checker. Can you please help me on the right structure, or maybe give me an example.

    Kindly appreciated,
    Marius.

    Comment by Marius Bratu — October 2, 2008 @ 5:37 pm

  27. @Marius Bratu
    As I can see you do not need a php file for now. Just remove the ‘< ?php' in the beginning and the '?>‘ at the end of the file. This will work.

    Also, if there will be nothing done on the server-side (eg. no php functions will be called) you could also rename the file to ‘json.txt’. Don’t forget to change the configuration data.url option from ‘json.php’ to ‘json.txt’ if you rename the file.

    Comment by vakata — October 2, 2008 @ 5:45 pm

  28. :( No luck. I have removed those php tags, and renamed to .txt, and also changed the data.url. It is not showing the tree. I have updated on my server.

    Comment by Marius Bratu — October 2, 2008 @ 5:57 pm

  29. Please add an opening bracket ‘[' at the beginning of the file and a closing bracket ']‘ at the end of the file.

    The function expects an array - I am fixing this for the next version.

    Hope everything will be fine now :)

    Comment by vakata — October 2, 2008 @ 7:43 pm

  30. It’s working! Thx a lot for your help and time invested, i really appreciated it. Also, i want to say that your work is awesome, i mean this is exactly what i needed. After spending so much time searching on net for this kind of tree, i almost gave up, but then i found your work fortunately. You are really a timer saver, and hair:P

    Thank you,
    Marius.

    Comment by Marius Bratu — October 2, 2008 @ 9:04 pm

  31. I’m glad I could help! :) Feel free to mail/write anytime.

    Comment by vakata — October 2, 2008 @ 10:26 pm

  32. I would have a small question: how could I change the white background of the tree? So i would need grey background with white letters on it.

    Thankx!
    Briganti

    Comment by Briganti — October 3, 2008 @ 8:49 pm

  33. @Briganti
    Just add the following CSS (somewhere after tree_component.css)

    .tree {
    background:gray;
    }
    .tree li,
    .tree li.last {
    background-color:gray !important;
    }
    .tree li a {
    color:white !important;
    }

    Comment by vakata — October 3, 2008 @ 10:43 pm

  34. Thank You,
    Briganti

    Comment by Briganti — October 3, 2008 @ 11:10 pm

  35. Thanx for the tree. Works great. Got one problem here. After getting the data from database an arrange it proberly i want to store the tree with ranks after i rearrange the tree with the drag and drop. Is it possible to store the tree with a form submit? Using PHP on server.

    Thanx

    Comment by Stefan — October 6, 2008 @ 1:05 am

  36. @Stefan
    You could do that on the fly using the callbacks, or you could build your own javascript function that traverses the tree and passes ordered node lists to the server.
    For example (just a rough one, I guess it could be done much better):

    function save_order(YOUR_NODE) {
      var nodes = new Array();
      $(YOUR_NODE)
        .children("ul:eq(0)")
        .children("li")
        .each(function (i) {
          nodes.push(this.id);
        });
      $.get(YOUR_SCRIPT?nodes=nodes.join(","));
    }

    And on the server:

    $nodes = explode(",",$_GET["nodes"]);
    foreach($nodes as $k=>$node) {
      SQL_HERE: UPDATE table SET weight = (int)$k WHERE id = (int)$node
    }

    Comment by vakata — October 6, 2008 @ 12:50 pm

  37. Thanx Vakata for the script. Did some scripting with it and here is the result:

    function save_order(nodeValue) {
    var saveString = ”;
    $(”ul li”, nodeValue).each(function (i) {

    //get child and parent node if avail
    var childNode = $(this).attr(”rel”);
    var parentNode = $(this).parents(”li”).attr(”rel”);

    //add seperator
    if(saveString.length>0)saveString = saveString + ‘,’;

    //put childnode into string
    if(typeof(childNode) != “undefined”){
    saveString = saveString + childNode;
    saveString = saveString + ‘-’;

    //put parent node intor string if avail
    if(typeof(parentNode) != “undefined”){
    saveString = saveString + parentNode;
    } else {
    saveString = saveString + ‘0′;
    }
    }
    });
    alert(saveString);
    }

    What you get is a string with the node id and which parent id it connects.

    Example string: 29-0,4-0,3-0,6-3,19-3,8-19,5-3,9-3
    Results in:

    29-0
    4-0
    3-0
    6-3
    19-3
    8-19
    5-3
    9-3

    Comment by Stefan — October 7, 2008 @ 12:00 am

  38. Hi:
    I´m using 0.7.
    I write a simple UL list and the tree works correctly, but no in all browsers.
    It works correctly in Firefox and Chrome.
    In IE (6 and 7) the javascript code is not loading. I just can see a normal UL list.
    I´m sure i´m doing something badly, but i don´t know what. Because your examples in http://www.vakata.com/jsTree/examples/ are working correctly in IE.

    ¿Someone can help me?

    Comment by nomen — October 7, 2008 @ 11:52 am

  39. @nomen
    Please, send me an URL or your source, so that I can check what is wrong.

    Comment by vakata — October 7, 2008 @ 1:50 pm

  40. Hi Vakata:
    Thank you very much for your fast answer and thank you very much.
    Here you can donwload my code http://rapidshare.com/files/151752593/tree.zip.html.

    Bye..

    Comment by nomen — October 7, 2008 @ 5:58 pm

  41. @nomen
    Your problem is an Explorer problem ;) You just need to remove a comma from the config section:
    THIS:

    onrgtclk : function(NODE, TREE_OBJ, EV) { alert("Has hecho doble click derecho"); },

    SHOULD BE THIS

    onrgtclk : function(NODE, TREE_OBJ, EV) { alert("Has hecho doble click derecho"); }

    Note the missing comma at the end - this is your problem.

    Comment by vakata — October 7, 2008 @ 6:13 pm

  42. Hi Vakata:

    You are the King!

    Thank you again!

    Comment by nomen — October 7, 2008 @ 6:56 pm

  43. Hi Vakata,
    Can u please provide an async example. I’ve already spend 3 days on it, and it is still not working. It seems that the JSON data is not parsed.

    Rgds,
    Fred

    Comment by Frederick Eyland — October 9, 2008 @ 12:09 pm

  44. Hi:

    I´m testing the tree and it works fantastic.
    Now i should like to make two things and i don´t know wich is the best way (i´m very new to javascript).

    1)I have seen that a new node is created always in the next deep.
    If i have a tree like this:
    - 1
    - 2
    - 3
    And I am in node 1, when I create a new node this is created:
    - 1
    - 4
    - 2
    - 3

    And i would like to create in the same deep:
    - 1
    - 2
    - 3
    - 4
    How can i do it?

    2) I would like to avoid the deletion of nodes with childs. How can i know (in beforedelete function) if the selected node has childs?

    Thank you in advance!

    Comment by nomen — October 10, 2008 @ 11:41 am

  45. Hi Vakata:

    If I have a tree like this:
    - 1
    - 2
    -3
    And I have selected the node 1. When i create a new node it does:
    - 1
    - 4
    - 2
    -3
    How can i dot a “create in same level”, to obtain this:
    - 1
    - 2
    - 4
    - 3

    Thank you very much for this great job!

    Comment by nomen — October 10, 2008 @ 5:20 pm

  46. Ups! The post has lost the format!
    I don´t know how to format correctly so… here you have te correct post
    http://rapidshare.com/files/152681760/same_level_node.txt.html

    Comment by nomen — October 10, 2008 @ 5:27 pm

  47. Currently you cannot create in the same level - just select the upper node and then create, after that you can always reselect the original node. I will consider passing an argument for the create function for the next version.

    Examples will be up soon with v.0.8.1

    Comment by vakata — October 11, 2008 @ 10:47 pm

  48. Hi Vakata:

    I use jsTree as predefined HTML (with UL as you say in your doc).
    The tree is working correctly.
    I use the id parameter of “li” to pass all information I need. So id=”node_id=10,other_info=info”.

    In this way, when i wan´t to create a new node i use oncreate callback to call with ajax to server. In this call I send the parent node id and it works perfectly.

    The problem: the new node has not this info in his “li”, so, if i want to delete this new node i can´t find this info and my server don´t know what to do. (The only way to do it is reload all the page to get the all tree well formatted)

    The question is: When I create the node, how can i create his “li” with all the info I need. If i can´t generate just this “li” how can i update all the “ul”?

    Thank you very much in advance and excuse me for my poor english.

    Comment by Nostrum — October 15, 2008 @ 2:54 pm

  49. I am not sure if this is the best way to store data about the nodes (check the metadata jquery plugin - it is integrated in jsTree).
    Still - since you are using oncreate and making an AJAX call - use the return data of the server (have the server return the text that you need for the id attribute). For example:

    oncreate : function(NODE, REF_NODE, TYPE, TREE_OBJ) {
      $.get("YOUR_URL_HERE", function (data) {
        $(NODE).attr("id", data);
      });
    }

    Comment by vakata — October 15, 2008 @ 3:25 pm

  50. Hi Vakata:

    This works great!
    Anyway, I will see metadata jquery plugin. Maybe it is a best way to do it…

    Thank you very much.

    Comment by Nostrum — October 15, 2008 @ 4:22 pm

  51. Hi Vakata:

    I have a very curious problem.

    The tree works now perfectly. I can add nodes, delete nodes, call by ajax to my server and get the answer.
    The problem is, when I put in the head:

    The tree now fails:
    Let´s supose we are working on http://www.mysite.com/tree.
    Whe I want to delete a node, the node is deleted, but inmediately the site is redirected to the base href.
    The same when i want to create and when i want to rename.

    I need to use base href, to write the correct ajax urls in this mode:
    $(’base’).attr(’href’) + relative_url

    Thank you very much in advance.

    Comment by Nostrum — October 17, 2008 @ 12:40 pm

  52. Excuse me:

    I don´t know why my last post has deleted the line about href. I was writing about http://www.w3schools.com/TAGS/tag_base.asp

    The line was (I hope let´s see it):

    Comment by Nostrum — October 17, 2008 @ 12:53 pm

  53. @Nostrum
    What do you put in the head?
    And can you show me an example?
    I’ll try putting a <base> tag and see what happens.

    Comment by vakata — October 17, 2008 @ 12:57 pm

  54. Hi Vakata:
    I have see the new Jstree site. Congratulations!
    Excuse me for not sending you examples. I have some problem with them. Will work on it ;-).
    But now, I have a different problem. Maybe you can help me.
    As I say you in other post I save node info in the “id” of the node. When i want to create a new node use oncreate callback to call with ajax to server. Then, I change the node “id”, as you say, with
    $(NODE).attr(”id”, data);

    The problem is that now, i want to change the node “id” without using the callback functions. Is there posible?
    Excuse me if this is a very obvious question, but i´m not a javascript programer.
    Thanks in advance!

    Comment by Nostrum — October 21, 2008 @ 2:52 pm

  55. Obviously, i want to change the currently selected node “id”

    Comment by Nostrum — October 21, 2008 @ 4:24 pm

  56. I finally have solved this.
    If someone is interested:
    1.- I enabled the cookies in tree init:
    cookies : {prefix : “tree”},
    2.- Now i have the cookie tree_selected wich says me the selected node.
    3.- Whe my own ajax function (external to jstree) returns on his “success” y call to this function ChangeSelectedIDValue(newIDvalues)

    function ChangeSelectedIDValue(newID)
    {
    var myID = document.getElementById($.cookie(’tree_selected’));
    myID.setAttribute(’id’,newID);
    }

    So, now i have the id value updated

    Comment by Nostrum — October 24, 2008 @ 6:19 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment