Ext JS – Make Grid Text Selectable (with a mouse)

For some unfathomable reason, Ext JS makes text in a grid unselectable. You cannot select the text in the grid with your mouse to copy and paste it. The second you show a user a grid, the first thing he or she wants to do with it is select the text! The workarounds for this are well documented in the Grid FAQ and also in some of the threads on the Sencha forum. This is my “roundup” of the solutions.

For Ext JS 3
(solution is directly from the Grid FAQ) and it looks like this:

CSS to add:

<style type="text/css">
	.x-selectable, .x-selectable * {
		-moz-user-select: text!important;
		-khtml-user-select: text!important;
	}
</style>

To make the text selectable on one grid:

var grid = new Ext.grid.GridPanel({
   viewConfig: {
      templates: {
         cell: new Ext.Template(
            '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id}
                        x-selectable {css}" style="{style}" 
                        tabIndex="0" {cellAttr}>',
            '<div class="x-grid3-cell-inner x-grid3-col-{id}"
                        {attr}>{value}</div>',
            '</td>'
         )
      }
   },
   ...
});

To make all the grids have selectable text:

if (!Ext.grid.GridView.prototype.templates) {
   Ext.grid.GridView.prototype.templates = {};
}
Ext.grid.GridView.prototype.templates.cell = new Ext.Template(
   '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} x-selectable {css}"
               style="{style}" tabIndex="0" {cellAttr}>',
   '<div class="x-grid3-cell-inner x-grid3-col-{id}" {attr}>{value}</div>',
   '</td>'
);

For Ext JS 4 (4.0.7 in my case)
Solution is from this thread in the forums:
Make grid unselectability a boolean attribute

Add this css – I had to modify what is in the thread a little bit and add the changes to .x-grid-cell-inner for the selection to work on Chrome

.x-grid-cell-inner, .x-selectable {
    -moz-user-select: text !important;
    -khtml-user-select: text !important;
    -webkit-user-select: text !important;
}

Define a new “feature” that can be added to a grid

Ext.define('xxx.grid.SelectFeature', {
    extend: 'Ext.grid.feature.Feature',
    alias: 'feature.selectable',

    mutateMetaRowTpl: function(metaRowTpl) {
        var i,
        ln = metaRowTpl.length;

        for (i = 0; i < ln; i++) {
            tpl = metaRowTpl[i];
            tpl = tpl.replace(/x-grid-row/, 'x-grid-row x-selectable');
            tpl = tpl.replace(/x-grid-cell-inner x-unselectable/g, 'x-grid-cell-inner');
            tpl = tpl.replace(/unselectable="on"/g, '');
            metaRowTpl[i] = tpl;
        }
    }
});

Add the following override to your Ext application:

 Ext.override(Ext.view.Table, {
    afterRender: function() {
        var me = this;

        me.callParent();
        me.mon(me.el, {
            scroll: me.fireBodyScroll,
            scope: me
        });
        if (!me.featuresMC &&
            (me.featuresMC.findIndex('ftype', 'unselectable') >= 0)) {
            me.el.unselectable();
        }

        me.attachEventsForFeatures();
    }
});

And last step, add the feature to your grid:

{
    xtype: 'grid',
    features: [{ ftype: 'selectable' }],
    // All the other configs for a grid
}

Hopefully Sencha will just make this a standard feature of grids, or preferably a config on the grid. In the meantime, it’s a lot of steps, but necessary.

UPDATE: For Ext JS 4.1+
Config is now available on the grid view. The new config is enableTextSelection. http://docs.sencha.com/ext-js/4-1/#!/api/Ext.grid.View-cfg-enableTextSelection. Set enableTextSelection to true in the viewConfig of your grid.

Advertisements

11 comments

  1. Where would I add this functionality “Ext.override(Ext.view.Table,” ?
    Also is there any way After selecting the text If I can retreive the value for that?

    1. Ext.overrides are added after Ext.onReady and only need to be called once.

      I haven’t accessed the clipboard text programatically, so I’m not sure, but a search on “accessing text clipboard javascript” or whatever you are using might help.

      Also, 4.1 has text selection as a grid option, so no more work arounds needed.

  2. This worked GREAT! I am using Ext 3.4 and just copied your solution in – worked like a champ! I have credited you in my code, thanks!

  3. Great solution
    For some reason selection on a tree grid for the first cell does not work.
    Any idea before I dive in and try to fix it?

  4. Why not give the grid an extra class, ‘jobs-grid’ in my case and make the rows or columns you want, or if needed the whole grid selectable with simple css? The text in columns 1 and 4 is selectable in this example:

    .jobs-grid .x-grid3-td-1, .jobs-grid .x-grid3-td-4{
    -moz-user-select: text !important;
    cursor: text;
    }

  5. Can anybody get a working solution for Ext JS 3 for tree nodes? The Ext JS generated markup is something like this:

    Some text…

    I can’t figure out what the correct type for the prototype would be but I was thinking a possible solution would be something similar to the following:

    if (!Ext.grid.TreeGrid.prototype.templates) {
    Ext.grid.TreeGrid.prototype.templates = {};
    }
    Ext.grid.TreeGrid.prototype.templates.node = new Ext.Template(
    ‘,
    ‘{value}’,

    );

    Thoughts???

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s