PDA

View Full Version : Animating a row inside a GridPanel



cblin
20 Jul 2010, 7:01 AM
Hi,

I am trying to animate the background-color of a row in a grid.
The use case is the following :
* the grid is binded to a form,
* when I press the right key -> the form is focused
* when I press the escape key -> the focus is given back to the grid with the following code :


focusCurrentRow: function() {
var sm = this.getGrid().getSelectionModel();
var index = sm.last || 0; //select the current row OR the first if none is selected
sm.selectRow(index, false);
this.getGrid().getView().focusRow(index);
}


What I am trying to do is to animate the grid to say "hey I have the focus now !"

Here is how I am doing it :


focusCurrentRow: function() {
var sm = this.getGrid().getSelectionModel();
var index = sm.last || 0; //select the current row OR the first if none is selected
sm.selectRow(index, false);
this.getGrid().getView().focusRow(index);
//animate the row so that the user see the grid now has the focus
var row = Ext.fly(this.getGrid().getView().getRow(index));
var oldBgColor = row.getColor('backgroundColor');
row.animate({
backgroundColor: { to: 'red' }
},
1,
function() {
row.animate({
backgroundColor: { to: oldBgColor }
},
1,
null,
'easeOut',
'color');
},
'easeOut',
'color');
},


But I see nothing on the screen.
The animate function is called and the callbackis also called.
If I delete the cbk (so the row should stay red), then it does not work either...

What am I doing wrong ?

Animal
20 Jul 2010, 7:31 AM
It can't go to "red". How would you?

You can only increment or decrement numbers (Or in the case of 'color' animation type, hex strings)



row.animate({
backgroundColor: { from: 'ffffff', to: 'ff0000' }
}, 1, Ext.emptyFn, 'easeOut', 'color');


And do not use Ext.fly to perform complex functions. It is to be used for one-off, atomic operations.

cblin
20 Jul 2010, 11:15 PM
Replacing red by '#000' (and using Ext.get instead of fly) changes nothing : the code is called but the animation does not appear on the screen.
As soon as I have some time, I am going to write a really small testcase with just a GridPanel that try to 'colorate' the row in black on selection (just to be sure that this is not interfering with other things).
I'll post it here.

Animal
20 Jul 2010, 11:34 PM
Replacing red by '#000' (and using Ext.get instead of fly) changes nothing

Did you read my code? I actually posted a working example!

cblin
21 Jul 2010, 5:31 AM
Yes Animal I read your code (you are one of the guy I always trust in this forum !)

Full code used in the function is :


focusCurrentRow: function() {
var sm = this.getGrid().getSelectionModel();
var index = sm.last || 0; //select the current row OR the first if none is selected
sm.selectRow(index, false);
this.getGrid().getView().focusRow(index);
//animate the row so that the user see the grid now has the focus
var row = Ext.get(this.getGrid().getView().getRow(index));
var oldBgColor = row.getColor('backgroundColor');
row.animate({
backgroundColor: { from: 'ffffff', to: 'ff0000' }
},
1,
Ext.emptyFn,
'easeOut',
'color');

}


If I setup a callback with only a console.Log('toto'); this is displayed BUT the selected row in the datagrid does have NO CHANGES AT ALL.

Here is a complete example showing the problem :


Open http://localhost/extjs/examples/grid/array-grid.html
Type in Firebug (I hope that the grid always has the id ext-comp-1001) :
Ext.get(Ext.getCmp('ext-comp-1001').getView().getRow(0)).animate({
backgroundColor: { from: 'ffffff', to: '000000' }
},
1,
Ext.emptyFn,
'easeOut',
'color');
=> this is working (the first row becomes black)

Now, select the second row (i.e the row with index==1) and type :
Ext.get(Ext.getCmp('ext-comp-1001').getView().getRow(1)).animate({
backgroundColor: { from: 'ffffff', to: '000000' }
},
1,
Ext.emptyFn,
'easeOut',
'color');
=> Nothinbg happen ! i.e it seems that when the row is selected THEN the animation does not work...

Animal
21 Jul 2010, 6:14 AM
Ext's rule for selected uses !important which apparently overrides inline styles.

IMHO, a library should not use !important

See the styling for selected:



.x-grid3-row-selected {
background-color:#DFE8F6 !important;
background-image:none;
border-color:#A3BAE9;
}


Maybe if you add an overriding style in your in-house stylesheet which comes AFTER ext-all.css:




.x-grid3-row-selected {
background-color:#DFE8F6;
}


I don't know if that rule will then override the previous one for that selector and that style! Try!

cblin
21 Jul 2010, 6:48 AM
Unfortunately, from the moment !important is used in a CSS rule then NO RULE (even positionned after) can override the declaration UNLESS the rule also has !important

i.e in my case, this is not going to solve my problem as I would have to write :


.x-grid3-row-selected {
background-color:blue !important;
}


but then my animation will still not be applied.

So what I did was to MODIFY the core files of extjs (which is bad but inevitable in this case) :
ext-all.css, line 5783 :
.x-grid3-row-selected {
background-color: #dfe8f6; /*hack by decalog : remove !important*/

xtheme-gray.css, line 630 :
.x-grid3-row-selected {
background-color:#CCCCCC; /*hack by decalog : remove !important*/

then the code in the first post is working if you use an hexa color instead of 'red'

Note that I think this is REALLY a bug in extjs to use !important on these styles.

Animal
21 Jul 2010, 6:49 AM
I agree, IMHO, the use of !important should be "considered harmful" in a library. It's just too heavy handed.

cblin
21 Jul 2010, 6:57 AM
just to post the fully working code :


focusCurrentRow: function() {
var sm = this.getGrid().getSelectionModel();
var index = sm.last || 0; //select the current row OR the first if none is selected
sm.selectRow(index, false);
this.getGrid().getView().focusRow(index);
//animate the row so that the user see the grid now has the focus
//the steps are
//1/go to black; (so that the user see the focus is on the row)
//2/revert to old color; (so that the row doesn't stay in black)
//3/ remove the style attribute (so the row doesn't stay in oldBgColor when not selected)
var row = Ext.get(this.getGrid().getView().getRow(index));
var oldBgColor = row.getColor('backgroundColor');
row.animate({
backgroundColor: { to: '000000' } //go to black
},
0.35,
function() {
row.animate({
backgroundColor: { to: oldBgColor } //revert to oldBgColor
},
0.1,
function() {
row.setStyle('backgroundColor', null) //remove backgroundColor attribute
},
'easeOut',
'color');
},
'easeOut',
'color');
},


I'd like to see a chaining animation API in ExtJs ...
Something like :


row.animate([
{mode: 'color', duration: 1, easing: 'easeOut', backgroundColor: { to: '000000'}}, //go to black
{mode: 'color', duration: 1, easing: 'easeOut', backgroundColor: { to: oldBgColor }}, //revert to oldBgColor
{mode: 'color', duration: 1, easing: 'easeOut', backgroundColor: { to: null }}, //remove attribute
]);

I think this is really possible only if all the param are in the config (because you may want to alternate color with motion and other animations) and also if the color animation handle the to: null (which means remove the backgroundColor attribute please)

Animal
21 Jul 2010, 6:58 AM
What would animate to null do?

It's a numeric value, so....