User-editing of treenode text

10 posts, 0 answers
  1. T
    T avatar
    15 posts
    Member since:
    Feb 2012

    Posted 22 Feb 2012 Link to this post

    After looking at the api it seems that treeview nodes are not editable inline by the user.  A lot of tree implementations (the mac finder to name one) allow clicking the selected node to commence editing mode during which the user can edit the text of a tree node, as when you change the name of a file on the mac when viewing a directory as a tree.

    The Dojo treeview also supports this, but not right out of the box...you have to set the nodes to be editable text controls.

    Can this sort of trick be done with the Kendo UI treeview?
  2. Miguel
    Miguel avatar
    8 posts
    Member since:
    Apr 2012

    Posted 09 Apr 2012 Link to this post

    Hi!  I had this limitation while evaluating kendo ui and had to come up with an answer...

    I am new here, so I don't know proper protocol for sharing resources.  But, here is the link to the kendo ui forum entry and to the jsfiddle I created

    http://www.kendoui.com/forums/ui/treeview/renaming-tree-nodes.aspx#2063301
    http://jsfiddle.net/65Dha/8/ 

    I hope this helps

    Miguel


  3. Kendo UI is VS 2017 Ready
  4. Rob
    Rob avatar
    4 posts
    Member since:
    Aug 2012

    Posted 08 Aug 2012 Link to this post

    @Miguel Hey, I took a look at your fiddle but couldn't work out how you are successfully changing the tree view node's text. How are you doing that?
  5. Miguel
    Miguel avatar
    8 posts
    Member since:
    Apr 2012

    Posted 09 Aug 2012 Link to this post

    Hi Rob, how are ya?

    I am not sure what part of the code is not clear, could you please ask a more straight question?

    In general, here is how I would approach this problem.

    1. Which inline editor you are going to use.  I used jeditable.
    2. What type of event will trigger the editing.  I used double clicking on the tree item.

    From there, you just got to wire up the kendoui, jeditable, and the event to orchestrate them both.  Here is how that works.

    1. Attach a doubleclick event to the tree, not particular tree items.  .on('dblclick''.k-in'function(event) 
    2. Figure out which item was double clicked so that you can wire up at runtime jeditable. $target $(event.target); 
    3. Bind jeditable to the target to enable inline editing... $target.editable(function (valuesettings) 
    4. Fire off a double click on the target to start inline editing.  $target.trigger('dblclick'[event]); 

     - Why you only attach the double click listener to the tree and not to individual tree items?  The reason is primarily that you generally want to attach as few event listeners as possible for efficiency reasons. What works well in HTML Dom events is that they "bubble up", so attaching a single double click handler on the tree will get you any double.  jQuery listener functionality allows you to filter out which items in particular should invoke the double click callback, which is how I accurately get the source of the event.  Adding the double click listener also has the benefit that you can dynamically add tree nodes, and their events will properly propagate correctly.

    Let me know you have more specific questions.


    Thanks,
    Miguel
  6. Thanos
    Thanos avatar
    9 posts
    Member since:
    Nov 2012

    Posted 23 Nov 2012 Link to this post

    Hey Miguel,
    Can you please explain a bit more the `".k-in"` part of the `"dblclick"` binder?
    For example I try to pass the node that was double clicked but I don't really understand this "selector" part...What type of data is this `"event"`? Shouldn't `"event.node"` give me the tree node clicked?
    My tree nodes are on an observable hierarchical data source and I want to get the `"text"` attribute they have.
  7. Miguel
    Miguel avatar
    8 posts
    Member since:
    Apr 2012

    Posted 26 Nov 2012 Link to this post

    Using jquery event handlers, you can pass a second parameter to filter specific elements that contain a css class that match the filter.  For example, that .on('dblclick''.k-in'function(event) will result in only calling that event handler when a child, including the element you attached the event handle to, is double clicked and has a class '.k-in'.  'k-in' was just a class I saw in the element I was interested in.

    Using event.target, you get the actual element you double clicked on.  You also have access to 'this', which the element that contains the '.k-in'; the current context of the event handler.

    Ok, here is an important part of using event handlers with filters the way I did.  You bind to a container element and the filters will make sure you get any children that's double clicked and has a class that matches the filter; even if the child element was attached after the container element event listener was setup.  Why would you want to do that?   Very often, you are dealing with the dynamic html content and the items you are interested in do not exist yet at the time you attach the event handler.  For example, if you tree is dynamic and you start with only the root parents, you will need to either attach an event handler to each child node as it is attached to the tree so that you can get the double click or you attach it to the container of the tree and filter out based on class matching.  You really don't want to attach event handlers to each node because it isn't efficient and they become a nightmare to manage.

    Also, very frequently you have tree nodes (or any hierarchical node) that is setup like this

    <ul>
    <li class='item'>
    <span>Name: </span>
    <span>Miguel</span>
    </li>
    <li class='item'>
    <span>Name: </span>
    <span>Thanos</span>
    </li>
    </ul>

    And you want to get notified when anything on the li is clicked...  So, you want to attach the event handler to ul and filter add a filter that represents the li.  Going further, the event handler will give you two very important pieces of information.  'this' is the li, and event.target is the item you clicked on.  You therefore can very selectively chose which item you want to process; make editable in your case.  The first span? The second span?


    I hope my long explanation helps :)


    -Miguel
  8. Thanos
    Thanos avatar
    9 posts
    Member since:
    Nov 2012

    Posted 26 Nov 2012 Link to this post

    I see,a bit confused but I think I sorted some stuff out...So with these event handlers you actually refer to the html elements right?

    What I want is to get the "node" that was double clicked.For example we have this tree:
    var treeview = $("#treeview").kendoTreeView({
                        dragAndDrop: true,
                        dataSource: kendo.observableHierarchy(data),
                        select: function (e) {
                                var dataItem = this.dataItem(e.node);
                            }
                        }).data("kendoTreeView");
    With a Hierarchical dataSource:
    var data =[
        {"text":"tree","expanded":true,"index":0,"items":[{"text":"oldChild","index":0,"expanded":true}]}];

    In the "select" event I get "e" which gives me through "e.node" the node that was selected and I get the dataItem of that node so that I can alter it etc..
    That's exactly what I want from the "dblclick" event..Get the node that was clicked and access it's "dataItem" on the dataSource..
    Something like:
    $("#treeview").on('dblclick', "node" , function(e) {
                             
                            var dataItem = this.dataItem(e.node);
                   dataItem.get("text"));
                        });

    So I want the "node" item of kendo,not the html element..
    Can I do that with this event handler?

    EDIT: I made this JS-Fiddle containing a view of the situation,can I make this example with that event handler to alert me the text attribute of the node that was double clicked?
  9. Miguel
    Miguel avatar
    8 posts
    Member since:
    Apr 2012

    Posted 26 Nov 2012 Link to this post

    Yes, the items I refer in the event handler are all html elements.  Either the ones I click on or the ones that match the filter.
    - event.target is what you clicked on. 'this' is what matches the filter.

    I am not too familiar with how the dataSource works in kendoui...  But if you have the item that was clicked (double clicked), I am hoping you can get the dataSource item from it and modify it.

    In your example below where you have:

    $("#treeview").on('dblclick', "node" , function(e) {
                             
                            var dataItem = this.dataItem(e.node);
                   dataItem.get("text"));
                        });

    So, we already established that 'this' is actually the html element that matches the filter 'node'; per your event handler filter.  So, unless kendoui is adding stuff directly into the html nodes like 'dataItem', your code won't work.  To get the data bound to your item, you probably want to look at a function that takes in an html node.  E.g. kendo.dataFor(e.node)

    Try changing up the fiddler I created in this thread and we can collaborate on the same piece of code :)
  10. Paul
    Paul avatar
    42 posts
    Member since:
    Aug 2005

    Posted 09 Aug 2014 Link to this post

    Hi Miguel

    Thank you for this excellent bit of code which I am using fine.

    I do however have one issue and that is I am allowing the users to use drag and drop to be able to re-order the treeview. This breaks the editing in that you can't use the mouse to select the text or place the cursor. The drag and drop events seem to take precedence.

    I've update the JS Fiddle with the drag and drop enabled so you can see what happens.

    http://jsfiddle.net/65Dha/449/

    Do you have any idea how I might sort this?

    Thank you for any help.

    Paul M
  11. Maxim
    Maxim avatar
    3 posts
    Member since:
    Jul 2015

    Posted 14 Jul 2015 in reply to Miguel Link to this post

    Is there any possibility not to use jeditable? To be more direct without using a jQuery on UI? I do a development in TypeScript and jeditable is not defined for it.
Back to Top
Kendo UI is VS 2017 Ready