Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically switch views in ExtJS 4 grid panel

There is a need to dynamically change a view in ExtJS 4 grid panel.

By default grid is displayed as a table, but in my application I need a feature to switch grid from table view to tiles (or cards) view. Below I tried to represent how it should look like.

 Normal view:                               Tiles view:
 ======================================     ====================================
 | Name       | Description           |     | Name       | Description         |
 ======================================     ====================================
 | Name 1     | First description   |^|     |  ------     ------     ------  |^|
 |----------------------------------|X|     | | O  O |   | @  @ |   | >  < | |X|
 | Name 2     | Second description  |X|     | | \__/ |   | \__/ |   | \__/ | |X|
 |----------------------------------|X|     |  ------     ------     ------  |X|
 | Name 3     | Third description   | |     |  Name 1     Name 2     Name 3  | |
 |----------------------------------| |     |                                | |
 |            |                     | |     |  ------     ------     ------  | |
 | ...        | ...                 |v|     | | o  O |   | -  - |   | *  * | |v|
 ======================================     ====================================

I have found almost perfect implementation of what I need, named Ext.ux.grid.ExplorerView. However, the extension was developed for ExtJS versions 2.x (3.x), and cannot be reused for ExtJS 4.

I use a grid which is created as simple as:

Ext.create("Ext.grid.Panel", {
    store: ...,
    columns: [{
        header: "Name",
        dataIndex: "name",
    }, {
        header: "Description",
        dataIndex: "description"
    }],
    tbar: [ ... ],
    bbar: [ ... ],
    listeners: { ... },
    multiSelect: true,
    viewConfig: {
        stripeRows: true,
        markDirty: false,
        listeners: { ... }
    }
});

I have tried to update tpl property of the inner view component, but nothing seems to work.

Do you have any idea of how to make the dynamic switch between the views for a single grid panel?

like image 558
VisioN Avatar asked Oct 27 '12 20:10

VisioN


2 Answers

The problem was easily solved with wonderful feature for grid panel named "Tileview" developed by Harald Hanek. The solution was specially developed for ExtJS 4.

The basic usage example is:

var grid = Ext.create("Ext.grid.Panel", {
    store: ...,
    columns: [{
        header: "Name",
        dataIndex: "name",
    }, {
        header: "Description",
        dataIndex: "description"
    }],
    tbar: [ ... ],
    bbar: [ ... ],
    listeners: { ... },
    multiSelect: true,
    viewConfig: {
        stripeRows: true,
        markDirty: false,
        listeners: { ... }
    },

    features: [Ext.create("Ext.ux.grid.feature.Tileview", {
        getAdditionalData: function(data, index, record, orig) {
            if (this.viewMode) {
                return {
                    name: record.get("name").toLowerCase(),
                };
            }
            return {};
        },
        viewMode: 'tileIcons',   // default view
        viewTpls: {
            tileIcons: [
                '<td class="{cls} ux-tileview-detailed-icon-row">',
                '<table class="x-grid-row-table">',
                    '<tbody>',
                    '<tr>',
                        '<td class="x-grid-col x-grid-cell ux-tileview-icon" style="background-image: url(&quot;...&quot;);">',
                        '</td>',
                        '<td class="x-grid-col x-grid-cell">',
                            '<div class="x-grid-cell-inner">{name}</div>',
                        '</td>',
                    '</tr>',
                    '</tbody>',
                '</table>',
                '</td>'
            ].join(""),

            mediumIcons: [ ... ].join(""),
            largeIcons: [ ... ].join("")
        }
    })]
});

To change the view we should just use setView() method, i.e.

grid.features[0].setView("tileIcons");

That's how the feature looks like in the real life.

  • Example of tile view:

enter image description here

  • Example of image view:

enter image description here


References:

  • https://github.com/harrydeluxe/extjs-ux/blob/master/ux/grid/feature/Tileview.js -- Tileview sources
  • https://github.com/harrydeluxe/extjs-ux -- All Harald's extensions with screenshots
  • http://www.sencha.com/forum/showthread.php?183023-Thumbnails-in-Grid-with-switching-between-views -- Feature discussion node on Sencha forum
  • http://harrydeluxe.github.com/extjs-ux/example/grid/tileview.html -- Demo
like image 109
VisioN Avatar answered Oct 02 '22 00:10

VisioN


I wouldn't do it like that. Instead, have a grid and a view in a card layout, the view gives you the ability to have pretty much any markup per item, here's a simple example:

Ext.define('Thing', {
    extend: 'Ext.data.Model',
    fields: ['name']
});

Ext.require('*');

Ext.onReady(function() {

    var store = Ext.create('Ext.data.Store', {
        model: Thing,
        data: [{
            name: 'Name 1'
        }, {
            name: 'Name 2'
        }, {
            name: 'Name 3'
        }]
    });

    var gridActive = true;

    var panel = Ext.create('Ext.panel.Panel', {
        renderTo: document.body,
        width: 400,
        height: 400,
        layout: 'card',
        tbar: [{
            text: 'Switch',
            handler: function(){
                var item;
                if (gridActive) {
                    item = panel.items.last();
                } else {
                    item = panel.items.first();
                }
                gridActive = !gridActive;
                panel.getLayout().setActiveItem(item);
            }
        }],
        items: [{
            border: false,
            xtype: 'gridpanel',
            columns: [{
                text: 'Name',
                dataIndex: 'name'
            }],
            store: store
        }, {
            xtype: 'dataview',
            itemTpl: '<b>{name}</b>',
            store: store
        }]
    });

});
like image 26
Evan Trimboli Avatar answered Oct 01 '22 23:10

Evan Trimboli