Inside my extjs grid, when I right click I call a context menu. When I click on one of the items I want to launch a method in the controller. This all works successfully, problem is I want to pass the parent grid that this is being called from into the controller method. Can someone please show me how to do this?
This is my context menu
Ext.define('Example.ContextMenuTradematch', {
xtype: 'contextMenuTradematch',
extend: 'Ext.menu.Menu',
items: [
{
text: 'Match Trade',
iconCls: 'greenIcon',
listeners: {
click: {
fn: 'onMatchTrade',
params: {
param1: this
}
}
}
},
{
text: 'Delete Trade',
iconCls: 'deleteIcon',
listeners: {
click: 'onDeleteTrade'
}
}
]
});
then this is my controller method
onMatchTrade: function (event, target, options) {
debugger;
var me = this;
How can I access the grid that the event originated from?
--and this is how I add the context menu to the grid
title: 'Tradematch Results: UNMATCHED',
xtype: 'grid',
itemId: 'gridUnmatchedId',
ui: 'featuredpanel-framed',
cls: 'custom-grid',
margin: '0px 10px 0px 10px',
flex: 2,
width: '100%',
bind: {
store: '{myTM_ResultsStore}'
},
listeners: {
itemcontextmenu: 'showContextMenuTradematch'
},
and this is how the controller adds it...
getContextMenu: function (cMenu) {
if (!this.contextMenu) {
debugger;
this.contextMenu = this.getView().add({ xtype: cMenu });
}
return this.contextMenu;
},
showContextMenuTradematch: function (view, rec, node, index, e) {
e.stopEvent();
e.stopEvent();
debugger;
this.getContextMenu('contextMenuTradematch1').show().setPagePosition(e.getXY());
return false;
},
The easiest way to do this is when you create your Example.ContextMenuTradematch instance - that I'm assuming you do from a itemcontextmenu listener - then you could pass a reference to the grid.
itemcontextmenu: function (grid, record, item) {
// code to create your menu
// probably something like:
if (!grid.contextMenu) {
grid.contextMenu = Ext.create('Example.ContextMenuTradematch', {
ownerGrid: grid
});
}
grid.contextMenu.showBy(item);
}
If onMatchTrade was fired by clicking on an Ext.menu.Item instance then it's signature will be:
onMatchTrade: function (item, e) {
var menu = item.up('menu'),
grid = menu.ownerGrid;
console.log(grid);
}
There was a lot of guessing here. If this is not how you are creating your menu or calling the methods, adding a fiddle with the issue would help.
Here is a fiddle to use as template: https://fiddle.sencha.com/#view/editor&fiddle/24fc
Related
Am new in Ext JS community. Here I want to apply a change event to child component which is 'textfield'.
I have specified the 'onChangeSealNumber' function in the controller. But it's not getting fired.
Can someone help me into it?
I have tried many approaches, however, If I pass anonymous function on change, it will work. But it won't work when we explicitly specify as 'onChangeSealNumber'.
View File
/**
* Search Form Panel View.
* #class 'BulkTransaction.view.searchfrom.SearchForm'
*/
Ext.define('BulkTransaction.view.searchform.SearchForm', {
extend: 'Ext.container.Container',
requires: [
'Common.view.widget.RepeatingWidgetGroup',
'BulkTransaction.view.storagelocation.StorageLocation',
'BulkTransaction.view.searchform.SearchFormController',
],
alias: 'widget.searchform',
controller: 'searchformcontroller',
items: [
{
xtype: 'basepanel',
width: '100%',
reference: 'searchform',
header: false,
items: [
{
width: '100%',
xtype: 'connect-repeating-widget-group',
bind: {
store: '{topSealNumbers}'
},
bindReference: 'topSealNumbers',
widgetConfig: {
xtype: 'textfield',
fieldLabel: BulkTransaction.util.Constants.searchForm.topSealNumbers,
allowBlank: false,
bind: '{topSealNumbers.searchCriteria}',
cls: 'seal-number-field',
listeners: {
change: 'onChangeSealNumber'
}
}
}
]
}
]
});
Controler File
/**
* Controller containing the methods implementing functionality
* related to search form
*/
Ext.define('BulkTransaction.view.searchform.SearchFormController', {
extend: 'Ext.app.ViewController',
alias: 'controller.searchformcontroller',
init: function () {
const me = this;
const viewModel = me.getViewModel();
viewModel.bind({
bindTo: '{topSealNumbers}',
deep: true
}, me.onSearchCriteriaChange, me);
},
/**
* Handle change to the sealnumber details
* #private
*/
onSearchCriteriaChange: function (store) {
const me = this;
let searchCriteriaRecords;
searchCriteriaRecords = store.queryBy(rec =>{
if (!Ext.isEmpty(rec.get('searchCriteria').trim())) {
return rec;
}
});
this.fireEvent('toggleSearchButton', searchCriteriaRecords.length > 0);
},
onSealNumberChange (elm) {
const me = this,
view = me.getView();
}
});
In you controller you need to create a function named onChangeSealNumber something like this
Ext.define('BulkTransaction.view.searchform.SearchFormController', {
extend: 'Ext.app.ViewController',
alias: 'controller.searchformcontroller',
onChangeSealNumber: function(field, newValue, oldValue, eOpts) {
//do something here
},
})
You can try (MyApp - name of your application):
listeners: {change: MyApp.app.getController('SearchFormController').onChangeSealNumber()}
But as for me its not good way to work with controller. More better add into controller (inside init):
init: function (application) {
this.control({
"searchform textfield": {
change: this.onChangeSealNumber
},
});
}
As for identifier I'm not sure because as usually use itemId and name
(like `"#myItemId textfield[name=MyFieldName]"` )
Could you teach me how to call nested methods? Basic idea, i want to have a function inside a class that i can configure from outside by sending another folderSelector with different return path. But when right now i'm trying to do that extjs says to me:
[W] XTemplate evaluation exception: foldersSelector is not a function
Code example:
Ext.define('somepath.Some1', {
extend: 'somepath.SomeParent',
text: 'sometext',
foldersSelector: function(data){
return data.folders;
},
initComponent: function(){
...
this.callParent();
}
renderer: function(data){
bla bla bla / got data from somewhere
...
...
foldersSelector(data);
// with this.foldersSelector result the same!
}
});
You are missing this in your function. You need to call the function from the class object. Something like this:
Ext.define('MyApp.view.MyPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.mypanel',
height: 250,
width: 400,
title: 'My Panel',
defaultListenerScope: true,
listeners: {
render: 'onPanelRender'
},
onPanelRender: function(component, eOpts) {
// call using this
this.folderSelector();
// call using component
component.folderSelector();
},
folderSelector: function(data) {
console.log('Function')
}
});
Fiddle https://fiddle.sencha.com/#view/editor&fiddle/1mpe
In your case, you are in the grid column, you can't call this because that's the grid. You have to get the column.
Ext.define('MyApp.view.MyColumn3', {
extend: 'MyApp.view.SuperColumn',
alias: 'widget.mycolumn3',
id: 'myColumnId',
foldersSelector: function (data) {
console.log('I AM CALLED');
return data + '-SOSO'
},
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
// you have to get the column, there are many ways how to do so
var c = Ext.first('#myColumnId')
return c.foldersSelector(value)
}
// option without the id
renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
// this is the grid
var gridColumns = this.getColumns();
// we know the column index
var c = gridColumns[colIndex];
return c.foldersSelector(value)
}
});
Fiddle: https://fiddle.sencha.com/#view/editor&fiddle/1mpo
I wanted to to delegate the mouseover/mouseout event to my parent node.
Here in the below code when i roll over to the #mycontent > span.bannerContent, i should delegate my mouseover event to the parents child img#bannerImage.
How i can achieve using extjs
HTML code:
<div>
<img id="bannerImage" />
<div id="mycontent">
<span> my dummy content </span>
</div>
EXtJS code
items : [{
xtype: 'image',
id:'bannerview1',
src: 'images/homePage/banner-1.jpg',
height: 500,
width: 1240,
listeners: {
el: {
click: function(el,src) {
var link =src.src;
if(link.indexOf("banner-1.jpg")!= -1){
window.open("main");
}
}
}
}
},
{
xtype: 'box',
id:'label',
html: '<span class="bannerContent"></span> ',
listeners: {
**el: {
mouseover:function(){
},
mouseout:function(){
}**
}
}
}
]
Normally you can pass an event to any observable using relayEvent, but the problem is, that Ext.dom.Element is not observable (does not know fireEvent method). So either you can listen to mouse events on parent div, hook carousel also on box events or if you insist on relaying events, extend Ext.Img such that it fires mouseout and mouseover events itself (and not its 'el') and then hook your carousel on such events.
Ext.define('My.Img',{
extend: 'Ext.Img',
alias: 'widget.myimage',
initComponent: function(){
var me = this;
me.addEvents('mouseover','mouseout');
me.on('render',function(){
me.getEl().relayEvent('mouseover',me);
me.getEl().relayEvent('mouseout',me);
});
me.callParent();
}
});
var myImage = Ext.create('My.Img',{
id:'bannerview1',
height: 500,
width: 1240,
src: '/img/header_01.gif',
listeners: {
mouseover:function(e){
console.log('mouseover image');
},
mouseout:function(e){
console.log('mouseout image');
}
}
});
Ext.create(' ... ',{
...
items : [ myImage,
{
xtype: 'box',
id:'label',
html: '<span class="bannerContent">blablabla</span> ',
listeners: {
render: function(){
this.getEl().relayEvent('mouseover',myImage);
this.getEl().relayEvent('mouseout',myImage);
}
}
}
]
});
Personally I think that such solution is not very straightforward.
In my code I use MVC architecture. My view Component looks like this:
Ext.define('calendar.view.event', {
extend: 'Ext.Component',
alias: 'widget.event',
renderTo: Ext.getBody(),
initComponent:function(){
this.addEvents('eventClick');
this.callParent(arguments);
},
afterRender: function() {
this.mon(this.el, 'click', this.eventClick, this); //mon( item, ename, [fn], [scope], [options] ) - zkratka pro addManagedListener.
this.callParent(arguments);
},
eventClick: function (ev, t) {
var height = this.getHeight();
this.fireEvent('eventClick', this, height, ev);
}
});
Im firing Event on click for controller which is like this:
Ext.define('calendar.controller.eventsChange', {
extend: 'Ext.app.Controller',
views: ['event'],
init: function () {
this.control({
'event': {
eventClick: function (callerObject) {
this.editEvent(callerObject)
}
}
});
},
editEvent: function (callerObject) { //oznaci jako editovatelny
callerObject.get
if(callerObject.hasCls('SpecEv') || callerObject.hasCls('activeEvent'))
{
if (callerObject.hasCls('activeEvent'))
{
callerObject.removeCls('activeEvent');
callerObject.addCls('SpecEv');
this.application.fireEvent('reRender');
}
else
{
console.log(callerObject);
callerObject.addCls('activeEvent');
callerObject.removeCls('SpecEv');
Ext.apply(callerObject, {
resizable: {
pinned:true,
dynamic:true
},
draggable: true,
});
callerObject.setLocalX(0);
var parentWidth = Ext.getCmp('SpecEv').getWidth();
callerObject.setWidth(parentWidth);
}
}
}
});
The problem comes when with
Ext.apply(callerObject, {resizable: {
pinned:true,
dynamic:true
},
draggable: true,
});
When console.log shows me the object after my apply, it says draggable:true and resizable:true. Does anyone know where the problem is?
Thanks for reponses.
It can't works, because your code only set configuration properties, which are handled only when component is initializing. So when you set these properties on already constructed object nothing happen. Component resizability and draggability will not be initialized automatically after setting these properties.
You can try use Ext.Component initResizable and initDraggable methods. But these methods are internal and undocumented.
callerObject.initResizable({
pinned:true,
dynamic:true
});
callerObject.initDraggable();
Also you can try setup Ext.util.ComponentDragger and Ext.resizer.Resizer for your existing component manually.
In my Grid, when I click on the Action button (the delete and edit button shown in the code below), I need to pop open a window without alerting the user with a Alert message;
In the following code I am using a HANDLER handler: buttonClicked and trying to access the row value i clicked from a different function below
buttonClicked :function (){...}
I don't know how to do this, can someone please help me ?
Can i access the row I clicked and display its name from the Controller class ?
CODE SNIPET
Ext.define('CountryAppTest.view.user.Gridview', {
extend: 'Ext.grid.Panel',
initComponent: function() {
this.store = 'store';
this.columns = [{
xtype: 'ac',
items: [{
icon: 'lib/extjs/examples/restful/images/delete.png',
handler: buttonClicked
}]
}, {
text: "username",
dataIndex: 'username'
}];
this.viewConfig = {
forceFit: true
};
this.callParent(arguments);
},
buttonClicked: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
Ext.Msg.alert("Info", "name " + rec.get('username'));
}
});
Add the parameters (grid, rowIndex, colIndex) into your buttonClicked declaration.