PDA

View Full Version : ActionColumn in ExtJS 4



thanhdo
25 Feb 2011, 1:02 AM
Anyone know the way to use actioncolumn in extjs 4?

aconran
25 Feb 2011, 1:29 PM
It's currently not integrated into Ext 4. It's something that will be addressed in the next release.

thanhdo
25 Feb 2011, 4:52 PM
Thanks aconran.

Do you know the next release date?

Stanback
15 Mar 2011, 5:10 PM
I ported it over to Ext4 if you're interested. I believe it's fully working. There's really not much code, so let me know if it doesn't work for you and I can try to resolve any issues. You'll need some CSS as well, which I've included at the bottom.


/**
* @class Ext.grid.ActionHeader
* @extends Ext.grid.Header
* <p>A Grid header type which renders an icon, or a series of icons in a grid cell, and offers a scoped click
* handler for each icon. Example usage:</p>
<pre><code>
Ext.require([
'Ext.grid.*',
'Ext.data.*'
]);
Ext.widget('gridpanel', {
store: myStore,
headers: [
{
xtype: 'actionheader',
width: 50,
items: [
{
icon : 'sell.gif', // Use a URL in the icon config
tooltip: 'Sell stock',
handler: function(view, rowIndex, item, e) {
var rec = store.getAt(rowIndex);
alert("Sell " + rec.get('company'));
}
},
{
getClass: function(v, meta, rec) { // Or return a class from a function
if (rec.get('change') < 0) {
this.items[1].tooltip = 'Do not buy!';
return 'alert-col';
} else {
this.items[1].tooltip = 'Buy stock';
return 'buy-col';
}
},
handler: function(view, rowIndex, item, e) {
var rec = store.getAt(rowIndex);
alert("Buy " + rec.get('company'));
}
}
]
}
//any other headers here
]
});
</pre></code>
* <p>The action header can be at any index in the headers array, and a grid can have any number of
* action headers. </p>
*/
Ext.define('Ext.grid.ActionHeader', {
extend: 'Ext.grid.Header',
alias: 'widget.actionheader',

/**
* @cfg {String} icon
* The URL of an image to display as the clickable element in the column.
* Optional - defaults to <code>{@link Ext#BLANK_IMAGE_URL Ext.BLANK_IMAGE_URL}</code>.
*/
/**
* @cfg {String} iconCls
* A CSS class to apply to the icon image. To determine the class dynamically, configure the Column with a <code>{@link #getClass}</code> function.
*/
/**
* @cfg {Function} handler A function called when the icon is clicked.
* The handler is passed the following parameters:<div class="mdetail-params"><ul>
* <li><code>view</code> : GridView<div class="sub-desc">The owning GridView.</div></li>
* <li><code>rowIndex</code> : Number<div class="sub-desc">The row index clicked on.</div></li>
* <li><code>item</code> : Object<div class="sub-desc">The clicked item (or this Column if multiple
* {@link #items} were not configured).</div></li>
* <li><code>e</code> : Event<div class="sub-desc">The click event.</div></li>
* </ul></div>
*/
/**
* @cfg {Object} scope The scope (<tt><b>this</b></tt> reference) in which the <code>{@link #handler}</code>
* and <code>{@link #getClass}</code> fuctions are executed. Defaults to this Column.
*/
/**
* @cfg {String} tooltip A tooltip message to be displayed on hover. {@link Ext.QuickTips#init Ext.QuickTips} must have
* been initialized.
*/
/**
* @cfg {Boolean} stopSelection Defaults to <code>true</code>. Prevent grid <i>row</i> selection upon mousedown.
*/
/**
* @cfg {Function} getClass A function which returns the CSS class to apply to the icon image.
* The function is passed the following parameters:<div class="mdetail-params"><ul>
* <li><b>v</b> : Object<p class="sub-desc">The value of the column's configured field (if any).</p></li>
* <li><b>metadata</b> : Object<p class="sub-desc">An object in which you may set the following attributes:<ul>
* <li><b>css</b> : String<p class="sub-desc">A CSS class name to add to the cell's TD element.</p></li>
* <li><b>attr</b> : String<p class="sub-desc">An HTML attribute definition string to apply to the data container element <i>within</i> the ta$
* (e.g. 'style="color:red;"').</p></li>
* </ul></p></li>
* <li><b>r</b> : Ext.data.Record<p class="sub-desc">The Record providing the data.</p></li>
* <li><b>rowIndex</b> : Number<p class="sub-desc">The row index..</p></li>
* <li><b>colIndex</b> : Number<p class="sub-desc">The column index.</p></li>
* <li><b>store</b> : Ext.data.Store<p class="sub-desc">The Store which is providing the data Model.</p></li>
* </ul></div>
*/
/* @cfg {Array} items An Array which may contain multiple icon definitions, each element of which may contain:
* <div class="mdetail-params"><ul>
* <li><code>icon</code> : String<div class="sub-desc">The url of an image to display as the clickable element
* in the column.</div></li>
* <li><code>iconCls</code> : String<div class="sub-desc">A CSS class to apply to the icon image.
* To determine the class dynamically, configure the item with a <code>getClass</code> function.</div></li>
* <li><code>getClass</code> : Function<div class="sub-desc">A function which returns the CSS class to apply to the icon image.
* The function is passed the following parameters:<ul>
* <li><b>v</b> : Object<p class="sub-desc">The value of the column's configured field (if any).</p></li>
* <li><b>metadata</b> : Object<p class="sub-desc">An object in which you may set the following attributes:<ul>
* <li><b>css</b> : String<p class="sub-desc">A CSS class name to add to the cell's TD element.</p></li>
* <li><b>attr</b> : String<p class="sub-desc">An HTML attribute definition string to apply to the data container element <i>within</i> the ta$
* (e.g. 'style="color:red;"').</p></li>
* </ul></p></li>
* <li><b>r</b> : Ext.data.Record<p class="sub-desc">The Record providing the data.</p></li>
* <li><b>rowIndex</b> : Number<p class="sub-desc">The row index..</p></li>
* <li><b>colIndex</b> : Number<p class="sub-desc">The column index.</p></li>
* <li><b>store</b> : Ext.data.Store<p class="sub-desc">The Store which is providing the data Model.</p></li>
* </ul></div></li>
* <li><code>handler</code> : Function<div class="sub-desc">A function called when the icon is clicked.</div></li>
* <li><code>scope</code> : Scope<div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the
* <code>handler</code> and <code>getClass</code> functions are executed. Fallback defaults are this Column's
* configured scope, then this Column.</div></li>
* <li><code>tooltip</code> : String<div class="sub-desc">A tooltip message to be displayed on hover.
* {@link Ext.QuickTips#init Ext.QuickTips} must have been initialized.</div></li>
* </ul></div>
*/
text: ' ',

actionIdRe: /x-action-col-(\d+)/,

/**
* @cfg {String} altText The alt text to use for the image element. Defaults to <tt>''</tt>.
*/
altText: '',

overCls: '',

eventName: 'beforeclick',

constructor: function(cfg) {
var me = this,
items = cfg.items || (me.items = [me]),
l = items.length,
i,
item;

this.callParent([cfg]);

// Renderer closure iterates through items creating an <img> element for each and tagging with an identifying
// class name x-action-col-{n}
me.renderer = function(v, meta, r) {
// Allow a configured renderer to create initial value (And set the other values in the "metadata" argument!)
v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';

meta.tdCls += ' x-action-col-cell';
for (i = 0; i < l; i++) {
item = items[i];

v += '<img alt="' + me.altText + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
'" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
}
return v;
};
},

onRender: function() {
// Hackjob event listener
var gridCmp = this.ownerCt.ownerCt;
gridCmp.on('afterrender', function() {
gridCmp.view.on(this.eventName, this.processEvent, this);
}, this);

return this.callParent(arguments);
},

onDestroy: function() {
delete this.items;
delete this.renderer;
return this.callParent(arguments);
},

onElClick: Ext.emptyFn,

/**
* @private
* Process and refire events routed from the GridView's processEvent method.
* Also fires any configured click handlers. By default, cancels the mousedown event to prevent selection.
* Returns the event handler's status to allow cancelling of GridView's bubbling process.
*/
processEvent: function(view, rowIndex, item, e) {
var m = e.getTarget().className.match(this.actionIdRe),
item, fn;
if (m && (item = this.items[parseInt(m[1], 10)])) {
e.stopEvent();
(fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, view, rowIndex, item, e);
return false;
}
return true;
}
});

.x-action-col-icon {
width: 16px;
height: 16px;
cursor: pointer;
}
Don't blame me if Sencha refactors this entirely before they officially release it; you might want to rename it to Ext.ux.grid.ActionHeader to keep it separate from the codebase. (I set Ext.ux to a directory outside of the main source folder in my Ext.Loader configuration)

PV-Patrick
17 Mar 2011, 12:31 PM
@ Stanback

I can't seem to get this to work correctly in regards to the action handler. It shows up correctly in the grid and when I go to click on the icon, nothing happens. As you can see I have a simple console.log('Hi') to test the output; nothing... Any help would be appreciated, thanks!



...
},{
xtype : 'actionheader',
text : 'Actions',
width : 50,
items : [{
iconCls : 'icon-delete',
handler : function(grid, rowIndex, colIndex) {
//var record = store.getAt(rowIndex);
//console.log(record);
console.log('Hi');
}
}]
}]

Stanback
17 Mar 2011, 1:24 PM
@ Stanback

I can't seem to get this to work correctly in regards to the action handler. It shows up correctly in the grid and when I go to click on the icon, nothing happens. As you can see I have a simple console.log('Hi') to test the output; nothing... Any help would be appreciated, thanks!


I was wondering when someone would reply - the event handling changed and the destroy method has been moved in Ext4, I got some code working last night. Give me a few to test everything and I'll post an update.

Stanback
17 Mar 2011, 2:59 PM
I've updated the code above, it's working well for me. Please take note of the updated handler parameters (only tested with RowSelectionModel). You should also be able to change the eventName property from 'beforeclick' to 'beforeselect' depending on your event listeners. I expect the Sencha devs to mock me for how I'm binding to the click event but it works for now and I couldn't think of an obvious better way without having to write an accompanying plugin. >:)

PV-Patrick
17 Mar 2011, 10:36 PM
That did the trick! Thanks Stanback, I really appreciate your time with implementing a work-around!

Animal
19 Mar 2011, 1:00 AM
This feature will be added soon. Next on the list after grouped column headers.

sandy.huang
22 Jun 2011, 6:19 AM
Hi Extjs Team:

I was trying to user iconCls attribute in actionColumn. However, it does not work for me. The image will not display on column. If I use icon:'/images/cross.png', then it works fine.

Am I missing something or doing something wrong ? Also, If that's possible to display some text after image on action column.


{
name:'removeActionCol',
xtype: 'actioncolumn',
items: [
{
iconCls:'icon-cross',
tooltip: 'Click to reomve ... '
}
],
width:30
}
Many thanks for your help
Sandy:)

ssamayoa
22 Jun 2011, 6:46 AM
I noticed that about a week ago but I'm too busy developing my solution so I didn't reported and I added a "TODO" comment in the view which uses the column to change to iconCls when fixed.

I also found that TabPanel's icon property doesn't work, you can only put an icon on it using iconCls.

Regards.

gaellafond
26 Jun 2011, 4:15 PM
Hi Extjs Team:
I was trying to use iconCls attribute in actionColumn. However, it does not work for me. The image will not display on column. If I use icon:'/images/cross.png', then it works fine.


Sandy, you can use the iconCls to add a CSS class to be to the image, to add some margin for example. You still have to provide a icon attribute (bug?). Try something like:


{
name:'removeActionCol',
xtype: 'actioncolumn',
items: [
{
icon:'/images/cross.png',
iconCls:'icon-cross',
tooltip: 'Click to reomve ... '
}
],
width:30
}

neonshark
21 Jul 2011, 5:36 AM
Most probably you don't have such attribute as 'width' & 'height' in your custom iconCls.

I also had this issue, but introducing sizes for the icon solved the problem.

It seems that ExtJS need sizes in order to set up clickable area in the column.

dbrin
10 Oct 2011, 7:03 PM
Has this issue been addressed in later releases after 4.0.2?

Stanback
10 Oct 2011, 8:03 PM
Has this issue been addressed in later releases after 4.0.2?

Yep, they've added support into the 4.x release. Let me know if you need any help implementing it.

Ext.grid.column.Action: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.column.Action

dbrin
10 Oct 2011, 9:00 PM
Neonshark was right, it was the height of the icon that was missing. Incidentally the same icon works fine as a button in the form, so there is some inconsistency of how the two are implemented.
My example:


xtype:'actioncolumn',
width:120 ,
items:[
{ iconCls: 'pause h16', tooltip: 'Pause'}
]


I had to add h16 class which is just :

.h16{
height: 16px;
}

without this height setting css the icon will not show up.

Stanback
10 Oct 2011, 9:03 PM
Ah yes, I've also applied a class with a height - forgot about that. It would be nice if this was addressed with an appropriate Sass variable.

sandy.huang
11 Oct 2011, 12:14 AM
Sandy, you can use the iconCls to add a CSS class to be to the image, to add some margin for example. You still have to provide a icon attribute (bug?). Try something like:


{
name:'removeActionCol',
xtype: 'actioncolumn',
items: [
{
icon:'/images/cross.png',
iconCls:'icon-cross',
tooltip: 'Click to reomve ... '
}
],
width:30
}


Hi Gaellafond:

Thanks for your reply. Can I not using iconCls to add background image in Ext JS 4 ?


.icon-cross{
background-image:url(/images/cross.png) ! important;
}

{
name:'removeActionCol',
xtype: 'actioncolumn',
items: [
{
iconCls:'icon-cross',
tooltip: 'Click to reomve ... '
}
],
width:30
}

dbrin
11 Oct 2011, 9:34 AM
You can, see my post above. You need to provide height attribute in CSS to your background image .icon-cross and it will work.

sandy.huang
11 Oct 2011, 12:37 PM
You can, see my post above. You need to provide height attribute in CSS to your background image .icon-cross and it will work.

Thanks :)