[CLOSED] Plugin to display extra buttons on treenode hover

Page 1 of 3 123 LastLast
  1. #1

    [CLOSED] Plugin to display extra buttons on treenode hover

    I want to create a treepanel plugin such that on treenode hover/mouseover, I want to inject a delete icon next to the treenode. On mouseout, delete icon will be removed.

    My problem is that there is no onNodeOver event on the treepanel.
    Last edited by Daniil; Jul 25, 2011 at 8:50 AM. Reason: [CLOSED]
  2. #2
    Hi,

    Yes, there is no such public event.

    In such situation with a TreePanel when you need some event, look at the TreeEventModel.
    <SVN root>\Ext.Net\Build\Ext.Net\extjs\src\widgets\tree\TreeEventModel.js
    Example

    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Ext.Net Example</title>
    
        <script type="text/javascript">
            var onAfterRender = function () {
                this.eventModel.onNodeOver = this.eventModel.onNodeOver.createSequence(
                    function (e, node) {
                        Label1.setText("onNodeOver: " + node.attributes.text);
                    });
            }
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            <ext:TreePanel runat="server" AutoHeight="true">
                <Root>
                    <ext:TreeNode Text="Root (level 0)" Expanded="true">
                        <Nodes>
                            <ext:TreeNode Text="Node1 (level 1)" Expanded="true">
                                <Nodes>
                                    <ext:TreeNode Text="Node1 (level 2)" Expanded="true">
                                        <Nodes>
                                            <ext:TreeNode Text="Node1 (level 3)" />
                                            <ext:TreeNode Text="Node2 (level 3)" />
                                        </Nodes>
                                    </ext:TreeNode>
                                </Nodes>
                            </ext:TreeNode>
                            <ext:TreeNode Text="Node2 (level 1)" Expanded="true">
                                <Nodes>
                                    <ext:TreeNode Text="Node1 (level 2)" Expanded="true">
                                        <Nodes>
                                            <ext:TreeNode Text="Node1 (level 3)" />
                                            <ext:TreeNode Text="Node2 (level 3)" />
                                        </Nodes>
                                    </ext:TreeNode>
                                </Nodes>
                            </ext:TreeNode>
                        </Nodes>
                    </ext:TreeNode>
                </Root>
                <Listeners>
                    <AfterRender Fn="onAfterRender" />
                </Listeners>
            </ext:TreePanel>
            <ext:Label ID="Label1" runat="server" />
        </form>
    </body>
    </html>
  3. #3
    I am able to get the right events by overriding TreeNodeUI. My prooblem now is that the hover icon class is not removed from the treenode in one corner case.

    Steps to Reproduce:
    1. Expand root node
    2. Hover over Node2 and move mouse to the right so it's over the icon
    3. Move mouse up and notice Node2 AND Node1 are highlighted.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Hover.aspx.cs" Inherits="MyExtNetSandbox.Hover" %>
    
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e) {
            if (!(this.IsPostBack)) {
                this.ResourceManager1.RegisterIcon(Ext.Net.Icon.Information);
            }
        }
    </script>
    
    
    <head runat="server">
        <title></title>
        <style type="text/css">
            .x-hoveractions-outer
            {
               float:right;
            }
            .x-hoveractions-img
            {
                height: 16px;
                width: 16px;
                cursor: hand;
            }
        </style>
    </head>
    <body>
        <form id="form1" runat="server">
        <script type="text/javascript">
            Ext.override(Ext.tree.TreeNodeUI, {
                onOver: function(e) {
                    this.fireEvent('onnodeover', this.node);
                    this.addClass('x-tree-node-over');
                },
    
    
                onOut: function(e) {
                    this.fireEvent('onnodeout', this.node);
                    this.removeClass('x-tree-node-over');
                }
            });
    
    
            Ext.ux.HoverActions = Ext.extend(Ext.util.Observable, {
                defaults: {
                    actions: []
                },
    
    
                constructor: function(config) {
                    Ext.apply(this, config || {}, this.defaults);
    
    
                    this.addEvents('action');
    
    
                    Ext.ux.HoverActions.superclass.constructor.call(this);
                },
    
    
                init: function(tree) {
                    this.tree = tree;
    
    
                    tree.on({
                        scope: this,
                        onnodeover: this.onNodeOver,
                        onnodeout: this.onNodeOut,
                        destroy: this.destroy
                    });
    
    
                    this.createEl();
                },
    
    
                destroy: function() {
                    document.removeChild(this.el);
                },
    
    
                createEl: function() {
                    var tpl = new Ext.XTemplate(
                        '<div class="x-hoveractions-outer">',
                        '<tpl for=".">',
                            '<img class="{iconCls} x-hoveractions-img" title="{name}" />',
                        '</tpl>',
                        '</div>'
                    );
    
    
                    this.el = tpl.append(document.body, this.actions);
                    Ext.fly(this.el).hide();
                },
    
    
                onNodeOver: function(node, e) {
                    var nodeUI = node.getUI();
                    var nodeEl = new Ext.Element(nodeUI.getIconEl().parentNode);
    
    
                    nodeEl.insertFirst(this.el);
                    Ext.fly(this.el).show();
                },
    
    
                onNodeOut: function(node, e) {
                    Ext.fly(this.el).hide();
                    document.body.appendChild(this.el);
    
    
                }
            });
        </script>
    
    
        <ext:ResourceManager ID="ResourceManager1" runat="server" Theme="Slate" ScriptMode="Debug">
        </ext:ResourceManager>
        <ext:TreePanel ID="tree" runat="server" Title="Test" Height="400" Width="400">
            <Root>
                <ext:TreeNode Text="Test">
                    <Nodes>
                        <ext:TreeNode Text="Node1">
                        </ext:TreeNode>
                        <ext:TreeNode Text="Node2">
                        </ext:TreeNode>
                    </Nodes>
                </ext:TreeNode>
            </Root>
            <Plugins>
                <ext:GenericPlugin runat="server" InstanceName="Ext.ux.HoverActions">
                    <CustomConfig>
                        <ext:ConfigItem Name="actions" Value="[{id: 'btnInfo', name: 'Info', iconCls: 'icon-information'}]">
                        </ext:ConfigItem>
                    </CustomConfig>
                </ext:GenericPlugin>
            </Plugins>
        </ext:TreePanel>
        </form>
    </body>
    </html>
  4. #4
    To fix we can suggest to add a small delay.

    As well, we'd suggest you to fire events - nodeover and nodeout - for a tree, not for a node's ui.

    Example
    Ext.override(Ext.tree.TreeNodeUI, {
        onOver : function (e) {
            this.addClass('x-tree-node-over');
            this.node.getOwnerTree().fireEvent('nodeover', this.node);
        },
    
    
        onOut : function (e) {
            this.removeClass('x-tree-node-over');
            this.node.getOwnerTree().fireEvent('nodeout', this.node);
        }
    });
    
    init : function (tree) {
        this.tree = tree;
    
        tree.addEvents('nodeover', 'nodeout');
    
        tree.on({
            scope: this,
            nodeover: this.onNodeOver,
            nodeout: this.onNodeOut,
            destroy: this.destroy,
            delay : 10
        });
    
        this.createEl();
    }
  5. #5
    Thanks! I can still sometimes reproduce the issue but 99% of the time, it works great. Can you explain why the delay and firing the event off the tree fix the issue?
  6. #6
    Quote Originally Posted by jchau View Post
    Thanks! I can still sometimes reproduce the issue but 99% of the time, it works great. Can you explain why the delay and firing the event off the tree fix the issue?
    Firing the events by the way I demonstrated is just a good design. It should not fix the issue.

    That small delay fixed the issue because it allowed to trigger node's "mouseout".

    Btw, you can try to increase delay to, for example, 50. Maybe, you will get 100% instead of 99%.
  7. #7
    I actually did increase it to 50 and it helps =). My other problem now is that the onclick event of the icon is not firing. If the div is outside the tree, it fires fine. Once it has been inserted into the tree, it no longer fires. Looking at the TreeEventModel (thanks for that, i was scratching my head for hours last night trying to find the hook to all those tree events), the delegateClick function doesn't get fired at all when clicking on the icon.

    
        createEl: function() {
            var tpl = new Ext.XTemplate(
                '<div id="hi" class="x-hoveractions-outer">',
                '<tpl for=".">',
                    '<img class="{iconCls} x-hoveractions-img" title="{name}" />',
                '</tpl>',
                '</div>'
            );
    
    
            this.el = new Ext.Element(tpl.append(document.body, this.actions));
            this.el.on('click', this.onClick);
            this.el.hide();
        },
    
        onClick: function() {
            alert('hi');
    
    
        },
  8. #8
    dblclick fires fine though...
  9. #9
    It looks you are testing under IE, right?

    Confirmed, 'click' isn't fired or prevented under IE.

    Under FF I can't see event an icon.

    And under Chrome it appears to be working as expected including 'click' event.

    Hope it will help to narrow the problem.
  10. #10
    Yes, this is under IE. I will post to ExtJS forum to see if they can help. It's really weird that the click event is not firing. With firefox, it's probably some css issue but we dont support FireFox anyway =P.
Page 1 of 3 123 LastLast

Similar Threads

  1. Replies: 2
    Last Post: Mar 14, 2012, 2:05 PM
  2. [CLOSED] Plugin to display button after node name in treepanel
    By bakardi in forum 1.x Legacy Premium Help
    Replies: 3
    Last Post: Oct 26, 2011, 7:49 PM
  3. Replies: 0
    Last Post: Dec 10, 2009, 11:14 AM
  4. How to make menus in toolbar auto display on hover?
    By dbassett74 in forum 1.x Help
    Replies: 0
    Last Post: May 30, 2009, 11:05 PM
  5. Image buttons / Custom built buttons
    By conman in forum 1.x Help
    Replies: 2
    Last Post: Jul 15, 2008, 11:01 AM

Tags for this Thread

Posting Permissions