Custom Edit control inside a ExtJS Editor grid - extjs

Got an issue, and need your advices
I just started writing an editor grid. (I will actually use this grid as a search filter editor, i.e. columns with criteria name, operators and values).
Now, for the value field, I want to have different edit controls for different rows. For instance, when a criteria type is string I want to display a text box, when it's date time, I want a datetime editor.
So the fact is, I need to control the "edit control creation/display" just before editing starts. and it should be different among rows. Unlike the examples I found which are fixed for the columns.
In order to implement this, can you guys please suggest the steps I need to do? I can probably figure out it if one of you can direct me a way.
Thanks and best regards

Actually you can easily accomplish this by dynamically returning different editors and renders depending on the column you're in. In your ColumnModel object you can define something like this below. Note that i'm getting a type property of each record to determine its type. I have an object containing all my different types of editors, and the same for renderers, and then based on the the type i dish out a different editor or renderer for that cell.
editors: { 'default': {xtype:'textfield'},
texttype: {xtype:'textfield'},
numbertype: {xtype:'numberfield'},
combotype: {xtype:'combo'}....... etc. }
getCellEditor: function(colIndex, rowIndex) {
var store = Ext.getCmp('mygrid').getStore();
var field = this.getDataIndex(colIndex);
var rec = store.getAt(rowIndex);
var type = rec.get('type');
if (type in this.editors) {
return this.editors[type];
} else {
return this.editors['default'];
}
},

In the configuration section of your editorgrid, you will need to define your custom editors:
{
xtype: 'editorgrid',
id : 'mygridID',
stripeRows: true,
...
...
,customEditors : {
//configs go here or pre-define the configs prior to this
'columnName1' : new Ext.grid.GridEditor(new Ext.form.Combobox(configObject)),
//configs go here or pre-define the configs prior to this
'columnName7' : new Ext.grid.GridEditor(new Ext.form.CheckBox(configObject))
}
}

use this grid config - in order to select whole rows:
selType: 'rowmodel'

Related

ExtJS Issue with boolean data and grid column list filter as well as Ext.Data.Store

I am using ExtJS 6 (although from what I can tell it applies up to version 7.4 as well) and I have a grid with a booleancolumn xtype. For that boolean column I wanted to use the filter list option. Yes I know there is a boolean filter option however I don't like how it works using a radio button. I wanted to be able to select the Yes or No with checkboxes, however I found that only the option with true as the value worked. Here is my column config:
{
header: 'Active'
, dataIndex: 'inactive'
, xtype: 'booleancolumn'
, trueText: 'No'
, falseText: 'Yes'
, filter:{
type: 'list',
options: [[true,"No"],[false, "Yes"]]
}
}
This didn't work when excluding the 'options' property and letting it get the data from the store either by the way. After looking through the code I discovered that it takes the 'options' config and creates its own Ext.Data.Store using that as the data. See here as a simple example that can be run that will get the same issue:
var teststore = new Ext.data.Store({
fields: [
'id',
'text'
],
data: [[true,"No"],[false, "Yes"]]
});
The problem is that the 'false' boolean value is changed and is replaced with a dynamically created generic id. I discovered the issue lays in the constructor for 'Ext.data.Model' for the following line:
if (!(me.id = id = data[idProperty]) && id !== 0) {
If that line evaluates to true it will replace the id with the generated one. To fix this I just added ' && id !== false' to the end of the if statement and this fixed the issue.
I have not tested this fully, however the logic seems sound and it looks like the same type of issue occurred with the value of '0' hence the ' && id !==0'. Since we are directed here from the sencha forums I wanted to bring this up in case it helps someone.
Since my post already has the answer I will post a better way to do it other than directly changing the Ext code file (whether this is the proper way I may be wrong). Instead, you can create a new js file that will need to be included in your application (you can name it ext-overrides.js). In the new js file you need only type:
Ext.override(Ext.data.Model, {
constructor: function(data, session) {
.....
}
}
You would then copy the constructor function code from your version of the ExtJS code in where the '.....' is (if perchance the constructor function arguments are different you would have to update those as well) and just add the suggested change I made above in the 'question'. A search of the Extjs code for Ext.define('Ext.data.Model' should get you there easily and then just scroll to the constructor function.

How to update autoGroupColumnDef property of ag-Grid after table is initialized

I have an ag-grid table (Enterprise version: 22.1.0) which is grouped using autoGroupColumnDef property. The grouping is dependent on the table's data and the data loads on a button click. I need to update the autoGroupColumnDef property's field name (_this.colName in the below code) after the page is loaded, right before loading the data.
Table's grid options:
_this.gridOptions = {
defaultColDef: {
sortable: true,
resizable: true,
filter: true
},
columnDefs: _this.columnDefs,
rowData: [],
enableRangeSelection: true,
autoGroupColumnDef: {
headerName: "Sector",
field: _this.colName,
cellRendererParams: {
suppressCount: true
},
tooltipValueGetter: function(params) {
return _this.tooltipVal
}
},
suppressAggFuncInHeader: true,
enableBrowserTooltips: true
};
I update the variable _this.colName before setting data to the grid. I have tried the following options and none of them worked for me:
_this.gridOptions.api.refreshClientSideRowModel('group');
_this.gridOptions.api.refreshCells();
_this.gridOptions.autoGroupColumnDef.field = 'Column's Name'
Any help would be appreciated!
There is a good workaround for this. You can set autoGroupColumnDef, then remove and readd all row groupings. It will redraw the group column with the new name.
gridOptions.autoGroupColumnDef.headerName = 'new_name';
// Get current groupings
var colstate = gridOptions.columnApi.getColumnState();
var colstateclear = gridOptions.columnApi.getColumnState();
// Clear groupings
var x = 0, xcount = colstateclear.length;
while ( x < xcount ) {
colstateclear[x].rowGroupIndex = null;
x += 1;
}
gridOptions.columnApi.setColumnState(colstateclear);
// Reset groupings
gridOptions.columnApi.setColumnState(colstate);
I contacted ag-grid support and apparently this is a bug and they have it in their backlog with no ETA available for now. A workaround they provided was to use: https://www.ag-grid.com/javascript-grid-grouping/#showRowGroup.
This is not really a good workaround because the grouped columns are separated and makes the page feel cramped. Also there are some look and feel issues that keep popping up (Eg: empty space added before each column that increases with each grouped column. ie second column has 1 cm added before it, third column has 2 cm added before it and so on. I guess this was added to bring the grouped look in the group column but you wouldn't expect this behavior when the columns are separated.)
ag-grid's backlog ID for the ticket: AG-3359 - Allow the autoGroupColumn to be used in the API calls for columns, at the moment there is no way to dynamically change it after creation. (ie, setColumnDefs …)
Link to track the progress: https://www.ag-grid.com/ag-grid-pipeline/
there is a straight forward method to update the autoGroupColumnDef object and its properties with setAutoGroupColumnDef
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
minWidth: 500
})
if any problems with the spread operator,
do it manually:
this.gridOptions.api.setAutoGroupColumnDef(<ColDef>{
// ...this.gridOptions.autoGroupColumnDef, // preserve the other settings except the ones you need to change
headerName: this.gridOptions.autoGroupColumnDef.headerName,
minWidth: 500
})
and one more thing, add this if you have any visual bugs, like: header row gets resized but bellow rows stays the same as previus state, so the refresh of model is required:
this.gridOptions.api.refreshClientSideRowModel();
this refresh is not ideal solution, because it refreshes everything, so you will loose expanded levels for example, still no clue how to preserve all settings.
https://angulargrid.com/angular-grid/client-side-model/#refreshing-the-client-side-model
and best solution for now is tu use:
this.gridOptions.api.redrawRows();
it keeps the rows expanded if are, checkbox selected if is.

Get Grid Feature by ftype, not id

I am writing a generic class which is derived from ExtJS grid, and I have to check that the grouping feature is used during toolbar instantiation (if grouping is enabled, I want to auto-add two buttons to collapse/expand all groups).
var groupingFeature = me.getView().getFeature("grouping")
if(groupingFeature && me.store.grouper) {
me.toolbar.insert(0,[{
iconCls:'icon-plus',
handler:function() {
groupingFeature.expandAll();
}
},{
iconCls:'icon-minus',
handler:function() {
groupingFeature.collapseAll();
}
}]);
}
But the grouping feature is not selected, because getFeature only works with ID (and I can't rely that a special id is added to every grouping feature).
Is there a way to get the feature by ftype?
You could search by ftype in a loop over the features array or use the private Method findFeature of the Ext.grid.View, which is doing this.
By the extjs documentation:
Finds a features by ftype in the features array
So using this function, you should get you the required information.
var view = me.getView();
var groupingFeature = view.findFeature("grouping");

ExtJS setting one element in propertyGrid sourceConfig as hidden dynamically

I'm working with an ExtJS 4 propertygrid that can list three different kinds of items that display when clicked on in another grid. One kind of item has to have a particular field hidden, so that it is't shown but any updates caused by editing other fields aren't affected by potentially missing information.
Attempts of using hidden/isHidden/visible/isVisible, with quoted and unquoted true/false values, haven't worked, and show the ShapeLength field in the propertyGrid.
Is there a "hidden: true" setting within the sourceConfig that I can apply somehow?
Example code:
var lengthDisplayName = '';
if(record.data.Type_ID == 'Circle(s)'){
lengthDisplayName = 'Radius (mm)';
}
if(record.data.Type_ID == 'Triangle(s)'){
lengthDisplayName = 'Side Length (mm)';
}
detailsGrid.sourceConfig['ShapeLength'] = {displayName: lengthDisplayName, type: 'number'};
if(record.data.Item_No == '-1'){
detailsGrid.sourceConfig['ShapeLength'] = {
displayName: lengthDisplayName,
type: 'number'
//, hidden/isVisible/visible value set here
}
};
No there is no hidden property for sourceConfig. But one possibility is to remove the property from the sourceConfig and reinsert it if it should be visible again.
delete detailsGrid.sourceConfig['ShapeLength'];
Was directed to an answer by a colleague - I can getRowClass within the propertyGrid and apply a hidden style on source data for an identifying property and the row name to hide, or else return out:
detailsGrid.getView().getRowClass = function(row) {
if(detailsGrid.source['Item_No'] == '-1' && row.data.name == 'ShapeLength')
return 'x-hidden';
return;
};

Agile Toolkit manipulating Grid column content

Just started using ATK4 and appreciating it very much so far, but not sure how to do this...
What I am trying to accomplish:
I am outputting a query's results to a grid, one of the fields is 'status', the data will either be '-1' or '1'.
Instead of outputting -1 or 1 to the column, how do I output an HTML snippet (or whatever I need to to get what I want) instead that shows a different icon for each value?
In short:
In column 'status':
if the value is -1, display iconDown.gif;
if the value is 1, display iconUp.gif
Code so far:
class page_showlist extends Page {
function init(){
parent::init();
$q=$this->api->db->dsql();
$q->table('remote_system')
->join('customers.id','customer_id')
->field('customer_id')
->field('ip')
->field('nickname')
->field('name','customers')
->field('status')
;
$grid = $this->add('Grid');
$grid->addColumn('text','status')->makeSortable();
$grid->addColumn('text','name')->makeSortable();
$grid->addColumn('text','ip');
$grid->addColumn('text','nickname');
$grid->addButton('Reload Grid')->js('click',$grid->js()->reload());
$grid->addQuickSearch(array('name'));
$grid->setSource( $q );
}
}
Any pointers/tips?
To add column with icons in Grid you can use custom template.
In one of my projects I do like this:
$url = $this->api->pm->base_url . $this->api->locateURL('template', 'images/');
$grid->addColumn('template', 'type', false)
->setTemplate('<img src="' . $url . 'icon_object_<?$type?>.png">');
It'll use model field named type (in your case use status) and show icons in that column. Icon source URL is generated dynamically and it'll search for image files in your template/images directory named icon_object_XXX.png where XXX value will be taken from field type value.
In my case type is like this: array('building','apartment','land','garage') etc.
And one more thing - you should start using Models whenever possible! That way you'll ease your life later when your project becomes bigger. Also can have extra security (conditions, etc.) with them.

Resources