@coon-js/extjs-lib-comp
Version:
NPM package providing component library for ExtJS projects
383 lines (327 loc) • 11.6 kB
JavaScript
/**
* coon.js
* extjs-lib-comp
* Copyright (C) 2017-2021 Thorsten Suckow-Homberg https://github.com/coon-js/extjs-lib-comp
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* Grid Feature which extends RowBody and is capable to switch between regular
* grid view and view with RowBody enabled by calling this feature's
* #disable()/#enable() methods.
* This feature tries to remember current column state to make sure
* when switching to detail view by disabling this feature the columns are
* re-arranged in their last known order and their proper visibility state.
* By specifying #previewColumnConfig, this feature knows about the columns
* that should be initially rendered along with the preview body.
*
* Note:
* =====
* - You must still override #getAdditionalData() to make sure the RowBody is
* rendered. Make sure you return "undefined" if this feature is disabled.
* - This feature hides the column headers when it gets enabled.
*
* @example
*
* Ext.define('MyGrid', {
*
* extend : 'Ext.grid.Panel',
*
* features : [{
* ftype : 'cn_comp-gridfeature-rowbodyswitch',
* id : 'rowbodyswitchfeature',
* getAdditionalData : function (data, idx, record, orig) {
*
* var me = this;
*
* if (me.disabled) {
* return undefined;
* }
*
* return {
* rowBody : 'Subject: <div>' + record.get('subject') + '</div>'
* };
* },
* previewColumnConfig : {
* 'isRead' : {hidden : true},
* 'subject' : {hidden : true},
* 'to' : {}
* }
* }],
*
* store : {
* fields : ['isRead', 'subject', 'to'],
* data : [{
* isRead : false, subject : 'Subject 1', to : 'to 1'
* }, {
* isRead : true, subject : 'Subject 2', to : 'to 2'
* }, {
* isRead : false, subject : 'Subject 3', to : 'to 3'
* }],
* },
*
* columns : [{
* text : 'Read',
* dataIndex : 'isRead',
* }, {
* text : 'Subject',
* dataIndex : 'subject'
* }, {
* text : 'To',
* dataIndex : 'to'
* }]
*
* });
*
* var myGrid = Ext.create('MyGrid', {
* renderTo : document.body
* ));
*
* var feature = myGrid.view.getFeature('rowbodyswitchfeature');
*
* feature.disable();
* feature.enable();
*
*
*
*/
Ext.define("coon.comp.grid.feature.RowBodySwitch", {
extend: "Ext.grid.feature.RowBody",
alias: "feature.cn_comp-gridfeature-rowbodyswitch",
/**
* @cfg {String} enableCls
* Additional css class that should be added to the grid's view as soon
* as the feature gets enabled. Gets removed from the grid's view as soon as
* the feature gets disabled.
* @see disableCls
*/
enableCls: "cn_comp-rowbodyswitch-enable",
/**
* @cfg {String} enableCls
* Additional css class that should be added to the grid's view as soon
* as the feature gets disabled. Gets removed from the grid's view as soon as
* the feature gets enabled.
* @see enableCls
*/
disableCls: "cn_comp-rowbodyswitch-disable",
/**
* @cfg {Object} previewColumnConfig
* Initial state of columns that should be shown along with the row body
* when this feature gets enabled. The keys are the dataIndex of the column,
* values are objects with information about their visibility, e.g.
* {hidden : true/false}.
*/
previewColumnConfig: null,
/**
* Set this explicitely to "false" to prevent rendering issues with Ext6.7. The problem
* is that ExtJS set variableRowHeight for the grid/view automatically to "true" if a
* RowBody plugin is detected. That leads to re-calculating the average rowHeight once pages
* are loaded, and if the last page is loaded and only 34 remaining records are loaded into a page
* that would fit 50, the average row height suddenly changes, although it has been fix for the
* previous pages. This can cause trouble with BufferedStores where the user uses infinite scrolling.
* Set this to false only if the contents of the RowBody are always the same for each and every
* data loaded.
*
* @see BufferedRenderer#getScrollHeight
*/
variableRowHeight: true,
/**
* @private
*/
columnConfig: null,
/**
* @inheritdoc
*
* @see initFeatureForGrid
*/
init: function (grid) {
var me = this;
if (grid.rendered) {
me.initFeatureForGrid(grid);
} else {
grid.on("afterrender", me.initFeatureForGrid, me, {single: true});
}
me.callParent(arguments);
if (me.variableRowHeight === false) {
grid.variableRowHeight = grid.view.variableRowHeight = false;
}
},
/**
* @param {Ext.grid.Panel} grid The grid this feature should be initiated with
*
* @private
*/
initFeatureForGrid: function (grid) {
const me = this;
if (!me.disabled) {
me.saveColumns();
grid.view.addCls(me.enableCls);
me.restoreColumns(me.previewColumnConfig);
grid.setHideHeaders(true);
} else {
grid.view.addCls(me.disableCls);
}
},
/**
* @inheritdoc
*/
disable: function () {
var me = this;
if (!me.view.grid.rendered) {
Ext.raise({
msg: "Cannot disable since grid was not rendered yet."
});
}
me.callParent(arguments);
me.restoreColumns(me.columnConfig);
me.disablePreview(true);
},
/**
* @inheritdoc
*/
enable: function () {
var me = this;
if (!me.view.grid.rendered) {
Ext.raise({
msg: "Cannot enable since grid was not rendered yet."
});
}
me.callParent(arguments);
me.saveColumns();
me.restoreColumns(me.previewColumnConfig);
me.disablePreview(false);
},
/**
* Disables or enables this features based on the specified argument.
* This feature controls the view and the grid it is used with by showing/
* hiding grid columns, refreshing the view and changing css classes accordingly.
*
* @param {Boolean} disable true to disable this feature
*/
disablePreview: function (disable) {
var me = this,
view = me.view,
grid = view.grid,
gridBody = grid.body;
disable = !!disable;
grid.setHideHeaders(!disable);
if (disable) {
/**
* @bug https://www.sencha.com/forum/showthread.php?308038-grid-hideHeaders-true-and-border-true-border-top-not-visible
*/
gridBody.removeCls("x-noborder-trbl").addCls("x-noborder-rbl");
view.addCls(me.disableCls).removeCls(me.enableCls);
} else {
gridBody.removeCls("x-noborder-rbl").addCls("x-noborder-trbl");
view.addCls(me.enableCls).removeCls(me.disableCls);
}
view.refresh();
},
/**
* Saves the current state of the columns (position and visibility) to make
* sure it's possible to re-apply this exact state later on when switching
* between states.
*
* @private
*/
saveColumns: function () {
var me = this,
view = me.view,
grid = view.grid,
columns = grid.getColumns(),
columnConfig = {},
col;
for (var i = 0, len = columns.length; i < len; i++) {
col = columns[i];
columnConfig[col.dataIndex] = {
hidden: col.rendered
? col.isHidden()
: col.hidden === true,
width: col.rendered
? col.getWidth() === 0
? undefined
: col.getWidth()
: col.width
? col.width
: undefined
};
if (columnConfig[col.dataIndex].width === undefined) {
delete columnConfig[col.dataIndex].width;
}
if (!col.rendered && col.flex) {
delete columnConfig[col.dataIndex].width;
columnConfig[col.dataIndex].flex = col.flex;
}
}
me.columnConfig = columnConfig;
},
/**
* Restores the column model and their positions based on the information
* passed in the object, wheres the keys are the dataIndex of the associated
* column, and the value is an object with information about the state (e.g.
* {hidden : true/false}.
*
* @param {Object} columnConfig
*
* @private
*
* @see previewColumnConfig
* @see columnConfig
* @see saveColumns
*/
restoreColumns: function (columnConfig) {
var me = this,
view = me.view,
grid = view.grid,
columns = grid.getColumns(),
col = null,
dataIndex = null,
restoreCount = 0,
configCol, i , len;
for (dataIndex in columnConfig) {
if (!Object.prototype.hasOwnProperty.call(columnConfig, dataIndex)) {
continue;
}
for (i = 0, len = columns.length; i < len; i++) {
col = columns[i];
col.setVisible(true);
if (col.dataIndex === dataIndex) {
grid.headerCt.move(i, restoreCount);
columns = grid.getColumns();
break;
}
}
restoreCount++;
}
columns = grid.getColumns();
for (i = 0, len = columns.length; i < len; i++) {
col = columns[i];
configCol = columnConfig[col.dataIndex];
if (configCol.hidden === true) {
col.setVisible(false);
}
if (configCol.flex !== undefined) {
col.setFlex(configCol.flex);
} else if (configCol.width !== undefined) {
col.setWidth(configCol.wdth);
}
}
}
});