hasCls() not working for my Extjs Grid - extjs4.2

i am applying css for a clicked record in my grid like below
listeners: {
select: function(record,rowIndex) {
this.getView().addRowCls(rowIndex, 'green');
}}
i need to check on a condition whether css is present or not, i am trying to check like this
select: function(record,rowIndex) {
this.getView().addRowCls(rowIndex, 'green');
if(this.getView().hasCls('green')){}
}
which is always returning false. Please help me...

You can use the bellow way to check if the specified CSS class exists.
var row = this.getView().getNode(rowIndex, false);
if (row) {
console.log( Ext.fly(row).hasCls('green') );
}

Related

Simple way to programatically remove all grouping and filtering

When the grid loads there is no grouping/filtering applied. I want to be able to remove any grouping/filtering which the user has applied manually i.e. get the grid format back to its original state.
You can do this with help of gridOptions of ag-grid. Try to do the below changes..
Initialize gridOptions if not yet along with column definitions and set the grid options in ag-grid.
Component.ts
this.gridOptions = {
defaultColDef: {
editable: true,
resizable: true,
filter: true
},
columnDefs: this.columnDefs,
rowData: this.rowData
};
clear the filters with like below
...
gridOptions.api.setFilterModel(null);
gridOptions.api.onFilterChanged();
...
component.html
<ag-grid .. [gridOptions] = "gridOptions" ..> </ag-grid>
You can see more about this in the ag-grid documentation.
you can define a function to reset everything
function ResetGrid(){
//clear filters
gridOptions.api.setFilterModel(null);
//notify grid to implement the changes
gridOptions.api.onFilterChanged();
//remove all pivots
gridOptions.columnApi.setPivotColumns([]);
// disable pivot mode
gridOptions.columnApi.setPivotMode(false);
//reset all grouping
gridOptions.api.setColumnDefs(columnDefs);
//where columDefs is the object you used while creating grid first time.
}
the above method does what you want but more sophisticated way to do this will be saving column state(it may be at iniital stage or later after certain operation).
function saveState() {
window.colState = gridOptions.columnApi.getColumnState();
window.groupState = gridOptions.columnApi.getColumnGroupState();
window.sortState = gridOptions.api.getSortModel();
window.filterState = gridOptions.api.getFilterModel();
console.log('column state saved');
}
function restoreState() {
if (!window.colState) {
console.log('no columns state to restore by, you must save state first');
return;
}
gridOptions.columnApi.setColumnState(window.colState);
gridOptions.columnApi.setColumnGroupState(window.groupState);
gridOptions.api.setSortModel(window.sortState);
gridOptions.api.setFilterModel(window.filterState);
console.log('column state restored');
}
function resetState() {
gridOptions.columnApi.resetColumnState();
gridOptions.columnApi.resetColumnGroupState();
gridOptions.api.setSortModel(null);
gridOptions.api.setFilterModel(null);
console.log('column state reset');
}
here is a demo
Here is how you can remove all filters and row groups. For more info, see GridApi.
gridApi.setFilterModel(null);
gridApi.setRowGroupColumns([]);
gridApi.onFilterChanged();
Live Example

startEditingCell in ag-grid does not work when Item has just been added

I am trying to have my ag-grid start editing as soon as a new item is added. It works when grid has data already but if it's the first item in the grid it does not work.
var a = $scope.gridOptions.api.updateRowData({add: [newItem]});
$scope.gridOptions.api.refreshCells({force:true}); // does not help
$scope.gridOptions.api.startEditingCell({
rowIndex: a.add[0].rowIndex,
colKey: 'Note'
});
using ag-grid version 12.0.2. Console shows nothing.
It seems like updateRowData does not automatically start a $digest loop. Adding $scope.$apply or $timeout or anything similar alleviates the problem.
The question showed AngularJS code.
Here's an example what you'd need to do, using regular Angular.
getContextMenuItems(params) {
var result = [
{
name: 'Add new row',
action: function() {
// Add a new row at the start of our agGrid's data array
params.context.rowData.unshift({});
params.api.setRowData(params.context.rowData);
params.api.refreshCells();
// Get the name of the first column in our grid
let columnField = params.column.userProvidedColDef.field;
// Highlight the left-hand cell in our new row, and start editing it
params.api.setFocusedCell(0, columnField, null);
params.api.startEditingCell({
rowIndex: 0,
colKey: columnField,
rowPinned: null
});
},
icon: '<img src="../../assets/images/icnAdd.png" width="14"/>'
}
];
return result;
}
Hope this helps.

Is it possible to have a date input in a w2ui toolbar

I am wondering if there is any way one could place a date input control in a toolbar similar to the one used for date input on a form?
Yes, it's possible, but it's quirky.
You will have to define the input field as a toolbar button:
{ type: 'html', id: 'roles', html: '<input id="id_role">' },
and in the toolbar's onRefresh() event you will have to cast the input to the desired w2filed:
onRefresh: function(event) {
if(event.target == 'roles'){
// w2field in toolbar must be initialized during refresh
// see: https://github.com/vitmalina/w2ui/issues/886
event.onComplete = function(ev){
$("#id_role").w2field('list', { items: roles });
};
}
},
In my example I'm inserting a drop down list, but you can adjust it to your needs.
Please see https://github.com/vitmalina/w2ui/issues/886 for an "official" reply.

How to provide a background color for an entire row in ag grid based on a certain value in a column?

I need to provide a background color for an entire row in ag grid based on a condition in a column. I found no such examples where entire row is colored based on a certain value in a column..
The previous answer is somewhat outdated (although still correct and working) and now we have some more control over the styling of the grid. You could use getRowStyle(params) for this job, just like this:
gridOptions.getRowStyle(params) {
if (params.data.myColumnToCheck === myValueToCheck) {
return {'background-color': 'yellow'}
}
return null;
}
Obviously, myColumnToCheck would be the column you're checking your value against (the same name you input in the id/field property of the colDef object), and myValueToCheck would be the value you want said column to have to make the row all yellow.
I hope this helps others. A very common use case in any table or grid including AG Grid is going to be to set the even/odd background color of the whole row of the entire table in a performant way. ALSO, this needs to still work when SORTING.
ALL OF THESE WAYS OF DOING THIS IN AG-GRID ARE WRONG. Even though they WILL work without sort, they will not update properly when you go to use sorting. This is due to something the ag-grid team refers to in this issue https://github.com/ag-grid/ag-grid-react/issues/77 as initialization time properties.
// Initialization problem
getRowClass = (params) => {
if (params.node.rowIndex % 2 === 0) {
return this.props.classes.rowEven;
}
};
<AgGridReact
getRowClass={this.getRowClass}
>
// Initialization problem
getRowStyle = (params) => {
if (params.node.rowIndex % 2 === 0) {
return this.props.classes.rowEven;
}
};
<AgGridReact
getRowStyle={this.getRowStyle}
>
// Initialization problem
rowClassRules = {
rowEven: 'node.rowIndex % 2 === 0',
}
rowClassRules = {
rowEven: (params) => params.node.rowIndex % 2 === 0,
}
<AgGridReact
rowClassRules={this.rowClassRules}
>
// Trying to change the key so a rerender happens
// Grid also listens to this so an infinite loop is likely
sortChanged = (data) => {
this.setState({ sort: Math.random()})
}
<AgGridReact
key={this.state.sort}
onSortChanged={this.sortChanged}
>
Basically, most stuff in grid is just read once and not again, probably for performance reasons to save rerenders.
You end up with this problem when sorting when doing any of the above:
THE FOLLOWIUNG IS THE RIGHT WAY TO ACHIEVE EVEN ODD COLORING:
The correct way to add even/odd functionality in ag-grid is to apply custom css styles as follows:
You will need to overwrite/use ag variables as mentioned in the docs here:https://www.ag-grid.com/javascript-grid-styling/#customizing-sass-variables
The names of the variables in our case are
.ag-grid-even class name, or the .ag-grid-odd class name. You of course only need one if you just want an alternating color to help with visibility. For our purposes we only needed one.
Here is how this process looked in our repo:
1. Make a custom css file that overwrites/uses some of these ag- class variable names. We call it ag-theme-custom.css (I believe it needs to be a css file).
Note: We also have sass variables so this file just has a comment that this color I am adding in css is the value for our variable $GREY_100 so you don't need that part
You now will get the same result but it will still work when sorting.
Answer 2 is correct, but the syntax used is wrong, and caused me several problems trying to sort it out. Trying to minify the answer 2 code barfed, for example. It did work, but it's not proper syntax as far as I can see.
Note, this can be done inline, or with an external
function. For example an external function.
vm.gridOptions = {
columnDefs: columnDefs,
getRowStyle: getRowStyleScheduled
}
function getRowStyleScheduled(params) {
if (params.selected && params.data.status === 'SCHEDULED') {
return {
'background-color': '#455A64',
'color': '#9AA3A8'
}
} else if (params.data.status === 'SCHEDULED') {
return {
'background-color': '#4CAF50',
'color': '#F4F8F5'
};
}
return null;
};
You can add CSS classes to each row in the following ways:
rowClass: Property to set CSS class for all rows. Provide either a string (class name) or array of strings (array of class names).
getRowClass: Callback to set class for each row individually.
<ag-grid-angular
[rowClass]="rowClass"
[getRowClass]="getRowClass"
/* other grid options ... */>
</ag-grid-angular>
// all rows assigned CSS class 'my-green-class'
this.rowClass = 'my-green-class';
// all even rows assigned 'my-shaded-effect'
this.getRowClass = params => {
if (params.node.rowIndex % 2 === 0) {
return 'my-shaded-effect';
}
};
You can define rules which can be applied to include certain CSS classes via the grid option rowClassRules.
The following snippet shows rowClassRules that use functions and the value from the year column:
<ag-grid-angular
[rowClassRules]="rowClassRules"
/* other grid options ... */>
</ag-grid-angular>
this.rowClassRules = {
// apply green to 2008
'rag-green-outer': function(params) { return params.data.year === 2008; },
// apply amber 2004
'rag-amber-outer': function(params) { return params.data.year === 2004; },
// apply red to 2000
'rag-red-outer': function(params) { return params.data.year === 2000; }
};
You can't change the background color of an entire row in one command. You need to do it through the cellStyle callback setup in the columnDefs. This callback will be called per each cell in the row. You need to change the color of the row by changing the color of all the cells.
See the following column definition
{
headerName: "Street Address", field: "StreetAddress", cellStyle: changeRowColor
}
You need to do this for all your columns.
Here is your changeRowColor function.
function changeRowColor(params) {
if(params.node.data[4] === 100){
return {'background-color': 'yellow'};
}
}
It changes the color of a row if the value of the third cell is 100.
I set different color for even and odd rows you can do it in any way..
$scope.gridOptions.getRowStyle = function getRowStyleScheduled(params){
if(parseInt(params.node.id)%2==0) {
return {'background-color': 'rgb(87, 90, 90)'}
}else {
return {'background-color': 'rgb(74, 72, 72)'}
}
};
If you don't need to set the background color conditionally(based on the row data), it is not recommended to use rowStyle, as written on the row style documentation page:
// set background color on even rows
// again, this looks bad, should be using CSS classes
gridOptions.getRowStyle = function(params) {
if (params.node.rowIndex % 2 === 0) {
return { background: 'red' };
}
}
Instead, you can change the row colors using css:
#import "~ag-grid-community/dist/styles/ag-grid.css";
#import "~ag-grid-community/dist/styles/ag-theme-alpine.css";
#import "~ag-grid-community/dist/styles/ag-theme-balham.css";
#import "~ag-grid-community/src/styles/ag-theme-balham/sass/ag-theme-balham-mixin";
.ag-theme-balham {
#include ag-theme-balham((
// use theme parameters where possible
odd-row-background-color: red
));
}
If you are using AdapTable then the simplest way is to use a Conditional Style and apply it to a whole row.
The advantage of this is that it can be at run-time easily by users also.
https://demo.adaptabletools.com/style/aggridconditionalstyledemo

Drag from Tree to div

I am trying to implement a drag and drop senario from an extJs TreePanel into a div in the body of the page. I have been following an example by Saki here.
So far I have the below code:
var contentAreas = new Array();
var tree = new Ext.tree.TreePanel({
title : 'Widgets',
useArrows: true,
autoScroll: true,
animate: true,
enableDrag: true,
border: false,
layout:'fit',
ddGroup:'t2div',
loader:new Ext.tree.TreeLoader(),
root:new Ext.tree.AsyncTreeNode({
expanded:true,
leaf:false,
text:'Tree Root',
children:children
}),
listeners:{
startdrag:function() {
$('.content-area').css("outline", "5px solid #FFE767");
},
enddrag:function() {
$('.content-area').css("outline", "0");
}
}
});
var areaDivs = Ext.select('.content-area', true);
Ext.each(areaDivs, function(el) {
var dd = new Ext.dd.DropTarget(el, {
ddGroup:'t2div',
notifyDrop:function(ddt, e, node) {
alert('Drop');
return true;
}
});
contentAreas[contentAreas.length] = dd;
});
The drag begins and the div highlights but when I get over the div it does not show as a valid drop target and the drop fails.
This is my first foray into extJS. I'm JQuery through and through and I am struggling at the moment.
Any help would be appreciated.
Ian
Edit
Furthermore if I create a panel with a drop target in it, this works fine. What is the difference between creating an element and selecting an existing element from the dom. This is obviously where I am going wrong but I'm none the wiser. I have to be able to select existing dom elements and make them into drop targets so the code below is not an option.
Here is the drop target that works
var target = new Ext.Panel({
renderTo: document.body
,layout:'fit'
,id:'target'
,bodyStyle:'font-size:13px'
,title:'Drop Target'
,html:'<div class="drop-target" '
+'style="border:1px silver solid;margin:20px;padding:8px;height:140px">'
+'Drop a node here. I\'m the DropTarget.</div>'
// setup drop target after we're rendered
,afterRender:function() {
Ext.Panel.prototype.afterRender.apply(this, arguments);
this.dropTarget = this.body.child('div.drop-target');
var dd = new Ext.dd.DropTarget(this.dropTarget, {
// must be same as for tree
ddGroup:'t2div'
// what to do when user drops a node here
,notifyDrop:function(dd, e, node) {
alert('drop');
return true;
} // eo function notifyDrop
});
}
});
See if adding true as the second param here makes any difference:
var areaDivs = Ext.select('.content-area', true);
As a cosmetic note, the param name e conventionally indicates an event object (as in the second arg of notifyDrop). For an element, el is more typical. Doesn't matter functionally, but looks weird to someone used to Ext code to see e passed into the DropTarget constructor.
If you are having problem duplicating a working example such as that, copy the entire thing, then modify it to your needs line-by-line - you can't go wrong.
As i know you can't set DropZone to any Ext element, just to Ext component. So this might be you problem. Try to use DropTarget instead of DropZone.