Tuesday, November 21, 2017

Auto size page in ExtJS grid.

Yesterday I was looking for solution to auto size page in grid, but have found not usable solutions and also for old ExtJS version. Then I've tried itself and got this:

You can declare simple two listener in your grid
Ext.define('app.view.main.List', {
    extend: 'Ext.grid.Panel',

    controller: 'list',

...

    listeners: {
     afterrender: 'onAfterRender',
     resize: 'onGridResize'
    }
});
and implement it in controller:
Ext.define('app.view.main.ListController', {
    extend : 'Ext.app.ViewController',
    alias : 'controller.list',

    onAfterRender: function(grid) {
        this.calcPageSize(grid);
    },
 
    onGridResize: function(grid) {
        this.calcPageSize(grid);
    },
 
    calcPageSize(grid) {
        var me = this,
            bodyHeight = grid.body.dom.clientHeight,
            hasLines = grid.rowLines,
            view = grid.getView(),
            row = view.getRow(0),
            // if there is now rows - assume row height 33 pixel
            rowHeight = row ? row.offsetHeight + (hasLines ? 1 : 0) : 33,
            store = grid.getStore(),
            currPageSize = store.getPageSize(),
            newPageSize = Math.floor(bodyHeight/rowHeight);
        if (bodyHeight == 0) {
            Ext.defer(function() {
                me.onGridResize(grid);
            }, 200);
            return;
        }
        if (currPageSize != newPageSize) {
            store.setPageSize(newPageSize);
            // if store loaded - reload them
            if (store.isLoaded()) {
                store.load();
            }
        }
    },
 
...

});
or you can create your own class:
Ext.define('Ext.ux.grid.AutoSizeGrid', {
    extend: 'Ext.grid.Panel',
    xtype: 'autoPageSize',

    initComponent: function() {
        var me = this;
        me.mon(grid, 'resize', me.onGridResize, me);
        me.mon(grid, 'afterrender', me.onAfterRender, me);
        me.callParent(arguments);
    },

    onAfterRender: function(grid) {
        this.calcPageSize(grid);
    },
 
    onGridResize: function(grid) {
        this.calcPageSize(grid);
    },
 
    calcPageSize(grid) {
        var me = this,
            bodyHeight = grid.body.dom.clientHeight,
            hasLines = grid.rowLines,
            view = grid.getView(),
            row = view.getRow(0),
            // if there is now rows - assume row height 33 pixel
            rowHeight = row ? row.offsetHeight + (hasLines ? 1 : 0) : 33,
            store = grid.getStore(),
            currPageSize = store.getPageSize(),
            newPageSize = Math.floor(bodyHeight/rowHeight);
        if (bodyHeight == 0) {
            Ext.defer(function() {
                me.onGridResize(grid);
            }, 200);
            return;
        }
        if (currPageSize != newPageSize) {
            store.setPageSize(newPageSize);
            // if store loaded - reload them
            if (store.isLoaded()) {
                store.load();
            }
        }
    }
});
You can see the example here https://fiddle.sencha.com/#view/editor&fiddle/29vf
Enjoy!

Disable hibernate query cache

Do you have a problem, that hibernate returns by calling stored procedure with the same parameters the same result also if you put id column is native query?

For example you have stored procedure which delivers last modified date of recent change for some object:
CREATE PROCEDURE GET_LAST_MODIFIED_DATE
(
    @objectId [bigint]
)
AS
BEGIN
    SET NOCOUNT ON

    SELECT
        a.id,
        top(1) a.lastModified
    FROM
        Table a
    WHERE
        a.deleted = 0
        AND a.objectId = @objectId
    ORDER BY
        a.lastModified DESC
END
GO
Solution is simple. You can change cache mode for single query:
    String sql = "exec dbo.GET_LAST_MODIFIED_DATE @objectId=123";
    Query query = entityManager.createNativeQuery(sql);
    query.setHint("javax.persistence.cache.storeMode", "REFRESH");