ExtJS grid: handling action column's click event in the controller - extjs

I have a view 'EmployeeList'. Inside it there is a grid. I need to handle the actioncolumn's click event from controller. Here is the view:
Ext.define('ExtApp.view.Employees', {
extend: 'Ext.panel.Panel',
alias: 'widget.employees',
.
.
.
.
.
});
This view contains a grid:
xtype: 'grid',
columns:[{
.
.
.
.
xtype: 'actioncolumn',
text: 'Delete',
width: 100,
items: [{
icon: 'images/deleteEmployee.jpg',
tooltip: 'Delete'
}]
}]
How do I handle the actioncolumn's click event in my controller?
Here is the controller's code:
Ext.define('ExtApp.controller.Employees', {
extend: 'Ext.app.Controller',
refs: [{
ref: 'employees',
selector: 'employees'
}],
init: function () {
//reference for the grid's actioncolumn needed here
}
});

If you wanna handle the clicks with your controller, you will have to add a handler to your actioncolumn like this:
xtype:'actioncolumn',
width:50,
items: [{
icon: 'extjs/examples/shared/icons/fam/cog_edit.png', // Use a URL in the icon config
tooltip: 'Edit',
handler: function(view, rowIndex, colIndex, item, e, record, row) {
this.fireEvent('itemClick', view, rowIndex, colIndex, item, e, record, row, 'edit');
}
}]
And then add event handler in your controller for the itemClick event
init: function() {
this.control({
'actioncolumn': {
itemClick: this.onActionColumnItemClick
}
});
},
onActionColumnItemClick : function(view, rowIndex, colIndex, item, e, record, row, action) {
alert(action + " user " + record.get('firstname'));
}
And you should see it working, fiddle here: https://fiddle.sencha.com/#fiddle/grb

Related

How to handle body element events in a controller in ExtJS6?

I have a basic grid panel where I render custom <span> element inside one of the columns. I am trying to catch the click events on this element and handle them in a controller.
The problem is that inside the listener this refers to Window, so I can't even fire an event.
Ext.define('MyList', {
extend: 'Ext.grid.Panel',
xtype: 'mylist',
controller: 'mylist',
listeners: {
body: {
click: function(e, el){
//this.fireEvent('onTagClick');
},
delegate: 'span.tag',
scope: this
},
},
columns: [
{
text: 'Name',
dataIndex: 'name',
renderer: function(value, metaData, record){
return '<span class="tag">tag</span>' + value;
}
},
]
});
I can fire a global event with Ext.GlobalEvents.fireEvent() but running into some strange issues or bugs with duplicate event invocations after the grid gets reloaded. I want to see if there is a way to avoid global events.
Found one solution by attaching the listener directly from the controller, this would refer to the controller then:
Ext.define('MyListController', {
alias: 'controller.mylist',
init: function(){
this.getView().on({
body: {
click: function(e, el){
this.onTagClick(el);
},
delegate: 'span.tag',
scope: this
},
});
},
onTagClick: function(el) {
console.log("clicked", el);
},
});

Sencha Touch 2.x : Specifying Listeners in Config - howto

I am trying to add listeners of the itemtap event in a list view, however, when the list shows up correctly (ie loads from the store), and I tap an item of the list, the listener function is not triggered
Is this because I can't define the listeners inside config: in Ext.define()?
Thanks
Ext.define('Volt.view.FeedView', {
extend: 'Ext.Panel',
xtype: 'feedViewCard',
config: {
iconCls: 'home',
title: 'FeedView',
layout: {
type: 'vbox'
},
items: [
{
xtype: 'list',
itemTpl: '<div class="list-item-title">{title}</div> <div class="list-item-narrative">{narrative}</div>',
flex: 1,
listeners: {
itemtap: function(list, index, target, record, e, eOpts ){
console.log('List tapped , xtype = ' , list.getXTypes() );
debugger;
} //however when the list shows up and I tap the items, this function is not triggered
},
initialize: function(){
console.log('listview initialize');
console.log('XType = ',this.getXTypes(),'id = ',this.getId());
//console.log('XType = ',list.getXTypes());
//debugger;
this.setStore(Ext.getStore('Feeds'));
}
}
]
},
});

ExtJS button handler not working

My ExtJS button's handler is not invoked after clicking. Now the code looks like this.
Ext.define('EDS.view.selector.Container', {
extend: 'Ext.form.Panel',
alias : 'widget.selectorcontainer',
title: 'Selector_V2',
renderTo: 'input-div',
layout: 'fit',
height: '100%',
items: [
{
xtype: 'tabpanel',
defaults: {
bodyPadding: 10
},
}
],
buttons: [
{
text: 'Reset',
handler: function(){
console.log("Reset");
this.up('form').getForm().reset();
}
},
{
text: 'Add to constrain',
handler: this.addConstrain,
}
],
/*
* Logic for button "Add to constrain"
*
* Adds an entry into the constrain list describing a person, cost center or an application
*/
addConstrain: function(button, event){
console.log('Add_to_constrain clicked');
}
});
Originally this 'selectorcontainer' was put diretly in my app.js. But I extracted it into a stand-alone view. Before the extraction, it works perfect but now it is not working.
BTW, I've two buttons and the first "reset" works fine. So I'm wondering if there's anything wrong with "this.addConstrain" related to scoping.
You're right, it is a scoping issue - this is not the class you're defining; it's the scope at the time the Ext.define function is called (likely window). There are a few ways to handle this. The easiest (in my opinion) is to change your handler to work similarly to your reset handler:
{
text: 'Add to constrain',
handler: function(btn, e) {
//'this' is now the button
this.up('selectorcontainer').addConstrain(btn, e);
}
}
You could also add the buttons as part of the initComponent function instead of defining them as part of the Ext.define config.
initComponent: function() {
//'this' is now the selector container
this.buttons = [{
text: 'Reset',
handler: function(){
console.log("Reset");
this.up('form').getForm().reset();
}
}, {
text: 'Add to constrain',
handler: this.addConstrain
}];
this.callParent();
}
The proper way to design your class is like this. You apply your config settings to the object before you do the callParent.
Ext.define('EDS.view.selector.Container', {
extend: 'Ext.form.Panel',
alias : 'widget.selectorcontainer',
title: 'Selector_V2',
renderTo: 'input-div',
layout: 'fit',
height: '100%',
initComponent: function() {
Ext.applyIf(this, {
items: [
{
xtype: 'tabpanel',
defaults: {
bodyPadding: 10
}
}
],
buttons: [
{
text: 'Reset',
scope: this, // <--- scope to form panel
handler: function(){
console.log("Reset");
this.getForm().reset();
}
},
{
text: 'Add to constrain',
scope : this, // <--- scope to form panel
handler: this.addConstrain
}
]
});
this.callParent(arguments);
}
/*
* Logic for button "Add to constrain"
*
* Adds an entry into the constrain list describing a person, cost center or an application
*/
addConstrain: function(button, event){
console.log('Add_to_constrain clicked');
}
});

extjs4 CheckboxModel select all

I want that the CheckboxModel appear all checked when grid is rendered:
This is my code:
sm = Ext.create('Ext.selection.CheckboxModel', {
listeners: {
selectionchange: function (sm, selections) {
// Must refresh the view after every selection
sm.view.refresh();
}
}
})
The grid:
{
xtype: 'gridpanel',
title: 'gridTitle',
selModel: sm,
store: my_store,
columns: {
items:[
..
]
}
}
You could use afterrender listeners of the grid to select all the rows :
listeners:{
afterrender:function( thisObj, eOpts ){
var sm=thisObj.getSelectionModel();
sm.selectAll(true);
}
},
afterrender may not work, try afterlayout instead:
// in your grid
listeners: {
afterlayout : function (thisObj, eOpts) {
thisObj.getSelectionModel().selectAll();
}
},
// ...

How to add a (existing) panel into a region on a Tree ItemClick

I think this is just simple, but I have no idea, how to load an existing panel on Tree ItemClick in the region of a viewport!?
TreeController snipped
init: function() {
this.control({
'treemenu': {
itemclick: function(view, node, record, item, index, e ) {
if(node.isLeaf()) {
}
},
itemexpand: function (t,e){
console.log(t.data.value);
}
}
});
}
Viewport snipped:
{
region: 'center',
layout: 'fit',
items: [{
xtype: ''
}]
}
The GridPanel:
Ext.define('MyProject.view.FlyerGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.flyergrid',
border:'0 0 0 0',
title:'Flyer Übersicht',
bbar: Ext.create('Ext.toolbar.Paging', {
//store: store
}),
columns: [
{ text: 'Typ', dataIndex: 'type',flex:1 },
{ text: 'year', dataIndex: 'year' ,flex:1},
]
});
First define a ref that will fetch the panel and the view
refs: [{
ref: 'panel',
selector: 'panel[region=center]' // you might give the panel a itemId instead of using region=center
}]
and a controller method that will add the view
showPanel: function(view, node, record, item, index, e ) {
if(node.isLeaf) {
var grid= this.getFlyerGrid();
if(!grid) {
this.getPanel().add({xtype:'flyergrid'});
}
}
}
As a alternative way for the ref you can also use Ext.ComponentQuery let's say if you need a grid for each record Id and remove a old
showPanel: function(view, node, record, item, index, e ) {
if(node.isLeaf) {
var grid= Ext.ComponentQuery.query('flyergrid[itemId=record.data.id]');
if(!grid) {
var panel = this.getPanel();
Ext.suspendLayouts();
panel.removeAll();
panel.add({xtype:'flyergrid',itemId:record.data.id});
Ext.resumeLayouts(true);
}
}
}
Update your control
this.control({
'treemenu': { itemclick: this.showPanel}
}
});
Please note that all this code is untested and should just show you the trick.

Resources