1. #1
    Sencha User
    Join Date
    May 2011
    Posts
    15
    Vote Rating
    1
    webdev2111 is on a distinguished road

      1  

    Exclamation Unanswered: Grid cell tooltip

    Unanswered: Grid cell tooltip


    I have been searching everywhere for a solution to using quicktip/tooltip on how to add tooltip to each gridcell and it doesnt seem to be working..



    What I am trying to do is have a mouse over on a cell I want a t tooltip to show with the value in the cell

    Anyone have any suggestions how I can add extjs tooltip to this?

    Code:
    var listView = Ext.create('Ext.grid.Panel', {
            store: mystore,
            multiSelect: true,
            viewConfig: {
                emptyText: 'No images to display'
            },
            //reserveScrollOffset: true,
        renderTo: containerEl,
       
            columns: [
    {
                text: 'Class',
                flex: 10,
                dataIndex: 'ClassName',
                renderer: function(value, metaData, record) {
       return Ext.String.format('<a href="#" class="tooltip2">{0}<span>{0}</span></a>', value);
            }
    
       ]     
        });
    Last edited by webdev2111; 8 Feb 2012 at 9:10 AM. Reason: added [CODE] tags

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,547
    Vote Rating
    872
    Answers
    3566
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Moved to the Ext JS 4 Q&A forum and wrapped your code with [CODE] tags.

    In Ext JS 4, the attribute you should use is 'data-qtip'
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha User
    Join Date
    May 2011
    Posts
    15
    Vote Rating
    1
    webdev2111 is on a distinguished road

      0  

    Default data-qtip usages

    data-qtip usages


    How can I go about adding the data-qtip on the code?
    I like the anchor and mousetrackign and the ba sic tooltps
    http://www.extjs.com/examples/explorer.html#tooltips

    Thanks
    Quote Originally Posted by mitchellsimoens View Post
    Moved to the Ext JS 4 Q&A forum and wrapped your code with [CODE] tags.

    In Ext JS 4, the attribute you should use is 'data-qtip'

  4. #4
    Sencha User charris's Avatar
    Join Date
    Sep 2010
    Location
    Brooklyn, NY
    Posts
    106
    Vote Rating
    13
    Answers
    8
    charris will become famous soon enough

      6  

    Default


    You can configure your column to use a renderer that, in addition to returning the value shown in the cell, can modify the <td> element surrounding the cell. Specifically, you can add the "data-qtip" attribute, which will cause ExtJS to display a tooltip when the mouse rolls over the <td> (e.g., <td ... data-qtip="Here's the tooltip">). The column config might look like this:
    Code:
    {    
         text: 'Column Header Blah',
        dataIndex: 'blah',
        renderer: function(value, metaData, record, rowIdx, colIdx, store) {
            metaData.tdAttr = 'data-qtip="' + value + '"';
            return value;
        }
    }
    Make sure to HTML encode the cell value and data-qutip value (twice) if your data needs it:
    Code:
    {
        renderer: function(value, metaData, record, rowIdx, colIdx, store) {
            // Sample value: msimms & Co. "like" putting <code> tags around your code
    
            value = Ext.String.htmlEncode(value);
    
            // "double-encode" before adding it as a data-qtip attribute
            metaData.tdAttr = 'data-qtip="' + Ext.String.htmlEncode(value) + '"';
    
            return value;
        }
    }

  5. #5
    Sencha User
    Join Date
    Mar 2010
    Posts
    39
    Vote Rating
    0
    Answers
    2
    WBX is on a distinguished road

      0  

    Default


    Thanks Clint and Mitchell for the tips (no pun intended) on this. This post should probably be marked as answered.

    Clint, could you explain the need to double encode the value?

    Also, I discovered that this strategy doesn't work well with the Ext.grid.column.Column convenience subclasses as it overrides the defaultRenderer for those classes. I made a post asking about this: http://www.sencha.com/forum/showthre...lumn.*-columns

    Do either of you have any ideas of how to address this?

    Thanks
    Gary

  6. #6
    Sencha - Support Team slemmon's Avatar
    Join Date
    Mar 2009
    Location
    Boise, ID
    Posts
    6,052
    Vote Rating
    215
    Answers
    484
    slemmon has much to be proud of slemmon has much to be proud of slemmon has much to be proud of slemmon has much to be proud of slemmon has much to be proud of slemmon has much to be proud of slemmon has much to be proud of slemmon has much to be proud of slemmon has much to be proud of

      0  

    Default


    Not sure how long you can count on this code since it uses some undocumented stuff, but.... works in 4.1.3

    But, this way you don't have to keep up with a renderer for each column - it'll grab the value dynamically for every column.

    http://jsfiddle.net/slemmon/GEwkG/
    Code:
    Ext.tip.QuickTipManager.init();
    
    Ext.create('Ext.data.Store', {
        storeId:'simpsonsStore',
        fields:['name', 'email', 'phone'],
        data:{'items':[
            { 'name': 'Lisa',  "email":"lisa@simpsons.com",  "phone":"555-111-1224"  },
            { 'name': 'Bart',  "email":"bart@simpsons.com",  "phone":"555-222-1234" },
            { 'name': 'Homer', "email":"home@simpsons.com",  "phone":"555-222-1244"  },
            { 'name': 'Marge', "email":"marge@simpsons.com", "phone":"555-222-1254"  }
        ]},
        proxy: {
            type: 'memory',
            reader: {
                type: 'json',
                root: 'items'
            }
        }
    });
    
    Ext.create('Ext.grid.Panel', {
        title: 'Simpsons',
        store: Ext.data.StoreManager.lookup('simpsonsStore'),
        columns: [
            { text: 'Name',  dataIndex: 'name' },
            { text: 'Email', dataIndex: 'email', flex: 1 },
            { text: 'Phone', dataIndex: 'phone' }
        ],
        height: 200,
        width: 400,
        renderTo: Ext.getBody()
        , listeners: {
            viewready: function (grid) {
                var view = grid.view;
                
                // record the current cellIndex
                grid.mon(view, {
                    uievent: function (type, view, cell, recordIndex, cellIndex, e) {
                        grid.cellIndex = cellIndex;
                        grid.recordIndex = recordIndex;
                    }
                });
                
                grid.tip = Ext.create('Ext.tip.ToolTip', {
                    target: view.el,
                    delegate: '.x-grid-cell',
                    trackMouse: true,
                    renderTo: Ext.getBody(),
                    listeners: {
                        beforeshow: function updateTipBody(tip) {
                            if (!Ext.isEmpty(grid.cellIndex) && grid.cellIndex !== -1) {
                                header = grid.headerCt.getGridColumns()[grid.cellIndex];
                                tip.update(grid.getStore().getAt(grid.recordIndex).get(header.dataIndex));
                            }
                        }
                    }
                });
    
            }
        }
    });
    This snippet assumes a dataIndex property for each column.

  7. #7
    Sencha Premium Member
    Join Date
    Dec 2011
    Location
    London, UK
    Posts
    260
    Vote Rating
    8
    Answers
    3
    bseddon will become famous soon enough

      0  

    Default These handy trick don't work when using Sencha Architect

    These handy trick don't work when using Sencha Architect


    When using Sencha Architect it's not possible to override the 'renderer' method as it's protected. Instead you can add an event listener to intercept the 'afterLayout' event and add this code:

    Code:
    var store = this.getView().getStore();
    var nodes = this.getView().getNodes();
    
    Ext.Array.forEach(nodes, function(tr, i)
    {
        var record = store.getAt(i);
        if ( record.data.qtip === undefined) return;
    
        var el = Ext.get(tr);
        el.set({'data-qtip': record.data.qtip});
    });
    This example assumes your record has a field 'qtip' but of course you can use any field or combination or mechanism to compute the tip you want.

    If you are using the cell editor plug-in, add a listener to the 'edit' event of the plug-in and in the event update the qtip (or other field(s) you are using) with the consequences of the edit.

  8. #8
    Sencha Premium Member joshua.ball@osi.com's Avatar
    Join Date
    Nov 2012
    Location
    Sacramento, CA
    Posts
    43
    Vote Rating
    1
    Answers
    1
    joshua.ball@osi.com is on a distinguished road

      0  

    Default A bit closer to a supported implementation

    A bit closer to a supported implementation


    This is a function I call (among others) from the 'viewready' event of the main grid panel:

    Code:
    initToolTip: function(){
            var view = this.view.getView();
            this.toolTip = Ext.create('Ext.tip.ToolTip', {
                target: view.el,
                delegate: view.cellSelector,
                trackMouse: true,
                renderTo: Ext.getBody(),
                listeners: {
                    beforeshow: function(tip) {
                        var trigger = tip.triggerElement,
                            parent = tip.triggerElement.parentElement,
                            columnTitle = view.getHeaderByCell(trigger).text,
                            columnDataIndex = view.getHeaderByCell(trigger).dataIndex,
                            columnText = view.getRecord(parent).get(columnDataIndex).toString();
                        if (columnText){
                            tip.update("<b>" + columnTitle + ":</b> " + columnText);
                        } else {
                            return false;
                        }
                    }
                }
            });
    This only utilizes the private method 'getHeaderByCell' of the Ext.grid.View object. Fair compromise. I'd love for something like this to be fully supported by the framework, though.

  9. #9
    Ext JS Premium Member
    Join Date
    Jun 2011
    Location
    St. Louis
    Posts
    212
    Vote Rating
    9
    jimmylu98 will become famous soon enough

      0  

    Default


    Thanks, this works with 4.2.2. http://jsfiddle.net/slemmon/GEwkG/ is not work any more with 4.2.2.

    Quote Originally Posted by joshua.ball@osi.com View Post
    This is a function I call (among others) from the 'viewready' event of the main grid panel:

    Code:
    initToolTip: function(){
            var view = this.view.getView();
            this.toolTip = Ext.create('Ext.tip.ToolTip', {
                target: view.el,
                delegate: view.cellSelector,
                trackMouse: true,
                renderTo: Ext.getBody(),
                listeners: {
                    beforeshow: function(tip) {
                        var trigger = tip.triggerElement,
                            parent = tip.triggerElement.parentElement,
                            columnTitle = view.getHeaderByCell(trigger).text,
                            columnDataIndex = view.getHeaderByCell(trigger).dataIndex,
                            columnText = view.getRecord(parent).get(columnDataIndex).toString();
                        if (columnText){
                            tip.update("<b>" + columnTitle + ":</b> " + columnText);
                        } else {
                            return false;
                        }
                    }
                }
            });
    This only utilizes the private method 'getHeaderByCell' of the Ext.grid.View object. Fair compromise. I'd love for something like this to be fully supported by the framework, though.

  10. #10
    Sencha Premium Member
    Join Date
    Feb 2012
    Location
    North Carolina
    Posts
    308
    Vote Rating
    22
    Answers
    3
    worthlutz will become famous soon enough

      0  

    Default


    All these methods of adding a tooltip to a cell seem to fall apart when locking columns. Apparently locked columns splits the grid up into two grids, locked and normal.

    With a locked column or two, the "viewready" event is never caught so the methods described above do not work.


    So many options and I cannot get them to work together.


    Can anyone point me in the right direction to attempt a fix which will work with locked columns?

    EDIT:

    My solution was to setup a listener for "viewready" on both grids contained in the lockable grid if they existed. My solution may not cover every possibility but it seem to be working.

    I did it like this in my plugin:

    Code:
     
    init: function (grid) {
        var me = this,
            grids = [grid],
            i,ii;
    
        if (grid.lockedGrid) {
            grids[0] = grid.lockedGrid;
            grids[1] = grid.normalGrid;
        }
        
        for (i = 0, ii = grids.length; i < ii; i++) {
            grid.mon(grids[i], {
                viewready: me.onViewReady,
                scope: me
            });
        }
    }
    I'd like to hear if you see any obvious problems with this. Also if they are not obvious.


    Worth
    Last edited by worthlutz; 22 Sep 2014 at 10:55 AM. Reason: Figured it out myself...