How to add a tooltip to an Extjs 4 gridpanel row using an xTemplate

How to add a tooltip to an Extjs 4 gridpanel row using an xTemplate

How to add a tooltip to an Extjs 4 gridpanel row, using an xTemplate

extjs gridpanel row tooltip

Please notice in the sample below that the function "hasValue" (or whatever you like to call it) is within the xTemplate, not in the tooltip itself !!!

This function is simply skipping fields that have no value. That doesn't show the tooltip wit some empty labels.

How to do it

Ext.define('Myapp.view.grid.Yourgrid', {
    extend: 'Ext.grid.Panel',
    ... more config ...
    initComponent: function() {
        var me = this;

        function createTooltip(view) {
            view.tip = Ext.create('Ext.tip.ToolTip', {
                tpl: new Ext.XTemplate(
                        '<dl class="eventTip">',
                        '<dt>LABEL 1</dt><dd>{field1}</dd>',
                        '<dt>LABEL 2</dt><dd>{field2}</dd>',
                        '<tpl if="this.hasValue(field3)"><dt>LABEL 3</dt><dd>{field3}</dd></tpl>',
                        '<tpl if="this.hasValue(field4)"><dt>LABEL 4</dt><dd>{field4}</dd></tpl>',
                        '</dl>',
                        {
                            hasValue: function(field) {
                                return field !== '';
                        }
                ),
                target: view.el,
                delegate: view.itemSelector,
                trackMouse: true,
                renderTo: Ext.getBody(),
                listeners: {
                    beforeshow: function(tip) {
                        var record = view.getRecord(tip.triggerElement);
                        if (record) {
                            tip.update(record.data);
                        } else {
                            tip.on('show', function() {
                                Ext.defer(tip.hide, 10, tip);
                            }, tip, {single: true});
                        }
                    }
                }
            });
        }

        Ext.applyIf(me, {
            viewConfig: {
                listeners: {
                    render: createTooltip
                }
            },
            columns: [
            ... the rest of your grid ...

Some CSS

.eventTip {
    padding-left : 10px;
    padding-right : 10px;
}
.eventTip dd {
     font-weight: bold;
}
.eventTip dd {
    padding: 5px 0 10px 0;
    margin-left: 0px;
    font-size: 13px;
}

Bonus: How to have a tooltip on every grid cell it's content doesn't fit

Sometimes you don't see the whole content in a grid cell. Then it would be nice if you could hover and that it would show a tooltip with the complete content popping up. This one is not from myself but from Joshua at this link. But the code that I found I modified a bit, for it would have some error interpreting rendered image (icons) as content that doesn't fit. The result looks like this:

ExtJS Grid Cell Tooltip

How to do it?

You create a new file showConditionalToolTip.js as a plugin (don't be afraid, it is also a javaScript file). You find the source code below. Then in your grid you declare the plugin. That's all. But first the plugin itself.

Make sure that you modify the name of this plugin to your own application structure.

Ext.define('Apps.plugin.showConditionalToolTip', {
   extend: 'Ext.AbstractPlugin',
   alias: 'plugin.showConditionalToolTip',
   init: function (grid) {
      grid.on('columnresize', function () {
         grid.getView().refresh();
      });
      grid.on('render', function () {
         var tm = new Ext.util.TextMetrics();
         Ext.Array.each(grid.columns, function (column) {
            if (column.hasCustomRenderer == true) {
               // This column already has a renderer applied to it
               // so we will be adding only the tooltip after the
               // custom renderer has formatted the data.
               column.renderer = Ext.Function.createSequence(column.renderer, function (a, b, c, d, e, f, g) {
                  // There could be instances where the column actually has no value, such as
                  // row expander, etc.. check for that and only apply the tooltip if the column
                  // has data.
                  if (a) {

                     // Check to see if the entire data string is visible in the cell, if it is then disregard
                     // otherwise add the tooltip
                     if ((g.ownerCt.columns[e].getEl().getWidth() || 10) <= (((tm.getSize(a).width + 15) || 0))) {
                        if (a.indexOf('<img') == -1) {  // not on icons !!!
                           b.tdAttr += 'data-qtip="' + a + '"';
                        }
                     }
                  }
               });

            } else {
               // Here we do the same as above, just w/o the sequence as there is no existing renderer
               column.renderer = function (a, b, c, d, e, f, g) {
                  if (a) {
                     if ((g.ownerCt.columns[e].getEl().getWidth() || 10) <= (((tm.getSize(a).width + 15) || 0))) {
                        if (a.indexOf('<img') == -1) { // not on icons !!!
                           b.tdAttr += 'data-qtip="' + a + '"';
                        }
                     }
                     return a;
                  }
               }
            }
         });
      });
   }
});

Now put the following code in your grid:

Ext.define('Yourgrid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.YourGrid',
    title: 'Some Title',
    plugins: ['showConditionalToolTip'],
    requires: [
        'Apps.plugin.showConditionalToolTip',
        ....
    ],
    ....

But be warned, it takes quite a toll on the performance of loading the grid. At least you can try it and see if it fits to your demand.