ExtJS 4.2 attach event in view to other views - extjs

I have a view with the following in my initComponent:
initComponent: function() {
var me = this;
Ext.applyIf(me, {
buttons: [
{
text: 'Guardar',
action: 'commit',
glyph: Glyphs.SAVE
}
],
items: [{
xtype: 'shiftpattern.window.formcode',
height: 50
},
{
xtype: 'shiftpattern.window.grid',
flex: 1
},
{
xtype: 'shiftpattern.window.formpattern',
height: 180
}
]
});
// here i need to listen to the grid's selectionchange event
me.on('selectionchange', me.onGridSelectionChange, me);
me.callParent(arguments);
},
onGridSelectionChange: function(grid, records) {
console.log('daysoff grid selection');
var me = this,
record = records[0];
}
I know that I can do that inside a controller, but in this case this view has it'w own behavior and I can reuse it in my sections of my application.
Is there a way to insert a selector to me.on('selectionchange', me.onGridSelectionChange, me);
Any clue on how to do that?

Just solved it:
me.on('selectionchange', me.onGridSelectionChange, me);
has to go after:
me.callParent(arguments);

Related

extjs proper way to replace main center panel

In ExtJS, on a menu toolbar button, I am trying to remove the current panel in my center window, then recreate it with the new selection. I do not understand the proper way to do this. So far when I click the menu item, it removes whatever is currently there successfully, then it will add the new panel successfully. The problem is the 2nd time I hit the button I get the following error:
REGISTERING DUPLICATE COMPONENT ID 'mainportalID'.
I realize its telling me I already used this ID, but then what would be the correct way to remove the current panel, and replace with a new one?
Here is my view controller:
selectMenuButton: function (button, e) {
console.log('select menu button section was hit')
console.log(button);
console.log(e);
var optionString = button.text;
var myDetailsPanel = Ext.getCmp('navview');
console.log(myDetailsPanel);
var count = myDetailsPanel.items.items.length;
if (count > 0) {
myDetailsPanel.items.each(function (item, index, len) {
myDetailsPanel.remove(item, false);
});
}
myDetailsPanel.add({
xtype: optionString
});
}
var myStore = Ext.create('ExtApplication1.store.PositionsStore');
var gridSummary = Ext.create('Ext.grid.Panel', {
store: myStore,
width: 600,
title: 'my first grid',
columns: [
{
text: 'AcctNum',
dataIndex: 'AcctNum',
width: 100
},
{
text: 'AcctShortCode',
dataIndex: 'AcctShortCode',
flex: 1
},
{
text: 'Exchange',
dataIndex: 'Exchange',
width: 200
}
]
});
This is my view
Ext.define('ExtApplication1.view.main.MainPortal', {
extend: 'Ext.panel.Panel',
xtype: 'mainportal',
alias: 'widget.mainportal',
id: 'mainportalID',
html: 'user... this is the main portal window',
autoScroll: true,
bodyPadding: 10,
items: [
gridSummary
]
});
adjusted panel
Ext.define('ExtApplication1.view.main.MainPortal', {
extend: 'Ext.panel.Panel',
xtype: 'mainportal',
alias: 'widget.mainportalAlias',
reference: 'gridtextfield',
//id: 'mainportalID',
html: 'user... this is the main portal window',
autoScroll: true,
bodyPadding: 10,
items: [
gridSummary
]
});
adjusted view controller
onComboboxSelect: function (combo, record, eOpts) {
console.log('new listener was hit');
//return selected Item
var selectedValue = record.get('ClientName');
var selectedCID = record.get('ClientID');
//find the grid that was created
var me = this;
console.log(me);
var xxx = this.lookupReference('gridtextfield');
debugger;
//debugger;
var mainPortalView = Ext.getCmp('mainportalID');
var targetGrid = mainPortalView.down('grid');
//find the store associated with that grid
var targetStore = targetGrid.getStore();
//load store
targetStore.load({
params: {
user: 'stephen',
pw: 'forero',
cid: selectedCID
}
//callback: function (records) {
// Ext.each(records, function (record) {
// console.log(record);
// });
// console.log(targetStore);
//}
});
},
added listeners to MainPortal.js
var myStore = Ext.create('ExtApplication1.store.PositionsStore');
var gridSummary = Ext.create('Ext.grid.Panel', {
store: myStore,
width: 600,
title: 'my first grid',
columns: [
{
text: 'AcctNum',
dataIndex: 'AcctNum',
width: 100
},
{
text: 'AcctShortCode',
dataIndex: 'AcctShortCode',
flex: 1
},
{
text: 'Exchange',
dataIndex: 'Exchange',
width: 200
}
],
listeners: {
destroy: function () {
debugger;
}
}
});
Ext.define('ExtApplication1.view.main.MainPortal', {
extend: 'Ext.panel.Panel',
xtype: 'mainportal',
alias: 'widget.mainportalAlias',
//id: 'mainportalID',
itemId: 'mainportalID',
html: 'user... this is the main portal window',
autoScroll: true,
bodyPadding: 10,
items: [
gridSummary
],
listeners: {
destroy: function () {
debugger;
}
}
});

Cannot get the object of a tabpanel

I have a grid in the center region of a border layout. When a specific item is clicked in the grid, I need to change the center region to display a tab panel. I am having trouble getting the tabpanel object.
In the ctrlpanel file, on the grid listener, I am using componentQuery to get the tabpanel('ccmain') object. It returns undefined.
I was using componentQuery to get 'ccmain' in the centerpanel file(lays out center region) successfully, but when I moved this code to the ctrlpanel file(one of the items in centerpanel) it fails. ComponentQuery no longer returns the tabpanel 'ccmain'. ComponentQuery does return the centerpanel or the viewport. I attemped to do centerpanel or viewport.down to find 'ccmain', but that also returns undefined. If you can tell me how to get the tabpanel or what I am doing wrong, I would appreciate it. Thanks for your time.
ctrlPanel.js
Ext.define('ServcSol.view.CtrlPanel',{
extend: 'Ext.Panel',
alias: 'widget.ctrlPanel',
xtype: 'ctrlPanel',
itemId: 'ctrlPanel',
requires:[
'ServcSol.store.FacilityStore'
],
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'panel',
height: 750,
title: 'Control Panel',
items: [
{
xtype: 'gridpanel',
padding: '20 20 5 20',
store: 'WorkHistoryStore',
height: 590,
width: '100%',
border: true,
columns: [
{
width: 110,
dataIndex: 'wrkhistDate',
text: 'Due Date'
},
{
width: 100,
dataIndex: 'wrkType',
text: 'Work Type'
}
],
listeners : {
itemclick: function(dv, record, item, index, e)
{
if(record.get('wrkType') == 'Test')
{
var tabPanel = Ext.ComponentQuery.query('ccmain')[0];
console.log('tabPanel is: ', tabPanel);
var tabIndex = tabPanel.items.findIndex('id', 'hazard');
var center = Ext.ComponentQuery.query('centerpanel')[0];
center.getLayout().setActiveTab(tabIndex);
}
ccmain.js
Ext.define('ServcSol.view.ccMain', {
extend: 'Ext.tab.Panel',
itemId: 'ccmain',
alias: 'widget.ccmain',
xtype: 'ccmain',
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'facility'
},
{
xtype: 'hazListing'
},
{
xtype: 'hazard'
},
{
xtype: 'testFormRP'
},
{
xtype: 'testFormDC'
}
]
});
this.callParent(arguments);
}
});
One of the reasons can be that ccmain is not instantiated as only instantiated components can be found by ComponentQuery.query. Then, even if ccmain would be found you cannot set its active item that way. Easiest is to assign tabs itemIds and then call setActiveTab:
tabPanel.setActiveTab(itemIdOfTheTab)

Extjs conditional configuration of initComponent

I'm quite new to Extjs and I can't figure this out:
I have a Container that requires a panel. Is there a way to dynamically initialise a component? This is my view:
Ext.define('Hello.view.index.Resume', {
extend: 'Ext.container.Container',
requires: [
'Hello.view.index.ValuesChart',
],
initComponent: function() {
this.leftZone = [{
margin: '0 0 5 0',
ui: 'hello-toggable',
xtype: 'hello_index_characteristics'
}];
Ext.apply(this, {
items: [{
xtype: 'container',
items: [{
xtype: 'hello_index_valueschart',
}, {
// ....
}]
}]
});
this.callParent();
}
});
The hello_index_valueschart panel has an initComponent function that defines several items:
initComponent: function() {
Ext.apply(this, {
border:false,
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'tbspacer',
width: 15
},
'->',
{
xtype:'button',
customproperty: this.id,
text:'I am a text',
tooltip: 'Hi there'
},
{
xtype:'button',
customproperty: this.id,
text:'I am another text',
tooltip: 'Hi here'
}
]
}]
})
}
Is there a way to dynamically pass the items to this panel? I mean for example: if a condition is verified in the controller pass an array items1 otherwise pass array items2.
A quick thought:
you can use the afterrender event on the panel, then add the components based on a condition in the controller. Something like:
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
onPanelAfterRender: function(component, eOpts) {
if(this.someCondition()) {
component.add( { ... });
}
},
someCondition: function() {
return true;
}
init: function(application) {
this.control({
"#mypanel": {
afterrender: this.onPanelAfterRender
}
});
}
});

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');
}
});

Define listeners in controller ExtJS

I have got the tabpanel - it's the main form (view).
In this tabpanel I define the different tabs - xtype:'panel'.
So, I have one main(controller) , main view and some tabs views.
The tab's views are referenced in main view.
I want to define listener of activate event of some child's panel in main controller.
How can I do that?
the main controller :
Ext.define('KP.controller.account.apartment.Main', {
extend: 'Ext.app.Controller',
views: ['account.apartment.Main',
'account.apartment.Requisites'
],
models: ['account.apartment.Requisites'
],
stores: ['account.apartment.Requisites'
],
init: function () {
}
});
The main view:
Ext.define('KP.view.account.apartment.Main', {
extend: 'Ext.window.Window',
alias: 'widget.ApartmentData',
height: 566,
width: 950,
activeItem: 0,
layout: {
type: 'fit'
},
autoShow: false,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'tabpanel',
activeTab: 0,
deferredRender: true,
items: [
{
xtype: 'RequisitesApartment'
}
]
}
]
});
me.callParent(arguments);
}
});
The child panel RequisitesApartment (view):
Ext.define('KP.view.account.apartment.Requisites', {
extend: 'Ext.panel.Panel',
alias: 'widget.RequisitesApartment',
id: 'panel_accountrequisites',
height: 350,
width: 1124,
autoScroll: true,
layout: {
type: 'fit'
},
listeners: {
activate: function () {
....load data....
...this listeners I want to push in 'main' controller...
}
},
initComponent: function () {
var me = this;
var grid_store = Ext.create('KP.store.account.apartment.Requisites');
Ext.applyIf(me, {
dockedItems: [
{
xtype: 'gridpanel',
height: 260,
autoScroll: true,
dock: 'bottom',
store: grid_store,
id: 'r_gridFlatParams',
forceFit: true,
columns: [
...some columns....
],
viewConfig: {
}
}
]
});
me.callParent(arguments);
}
});
Register it directly as control within the responsible controller
Here is a example with a working query. For sure you just will need the query, but I think it's a good example. The custom cfg property ident make it easy find each tab. As in the example below you will have specify a tabConfig within each panel and define the ident there.
Ext.create('Ext.tab.Panel', {
width: 400,
height: 400,
renderTo: document.body,
items: [{
title: 'Foo',
tabConfig: {
ident: 'foo'
},
}, {
title: 'Bar',
tabConfig: {
ident: 'bar',
title: 'Custom Title',
tooltip: 'A button tooltip'
}
}]
});
console.log(Ext.ComponentQuery.query('tabpanel tabbar tab[ident=foo]')[0]);
console.log(Ext.ComponentQuery.query('tabpanel tabbar tab[ident=bar]')[0]);
Another way is to use css id's which can be queried like '#my-name' but I recommend to use a custom one as in the example above
Well, I should put this code in 'main'(controller):
this.control({
'ApartmentData tabpanel RequisitesApartment': {
activate: function () {
console.log('hello!');
}
}
});
The problem was in wrong selector , that I used.
The correct selector is :
'ApartmentData tabpanel RequisitesApartment'
There 'ApartmentData'(define like a alias: 'widget.ApartmentData') - is the 'window' xtype -the main form.
tabpanel - panel with tabs in 'window', and 'apartServList'(define like alias: 'widget.RequisitesApartment') - the some panel.
Thanks for sra!
the correct thing to do is to pass a config object to the member function control into controller init function. From Sencha documentation : The control function makes it easy to listen to events on your view classes and take some action with a handler function.
A quick example straight from extjs docs:
Ext.define('MyApp.controller.Users', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
},
onPanelRendered: function() {
console.log('The panel was rendered');
}
});
Hope this helps.
Cheers

Resources