Nested initComponent not working - extjs

I have a window(Ext.window.Window) in which I have pane in card layout. I am adding grid dynamically to the panels item as:
Ext.define('Example.view.ProcessInfoLayout',{
extend: 'Ext.window.Window',
requires: [
'Ext.layout.container.Card',
'Example.view.SubProcessController',
'Example.view.Info'
],
xtype: 'app--processinfolayout',
controller: 'main-content-subprocesscontroller',
layout: 'fit',
initComponent: function(){
this.callParent();
this.header = {
titlePosition: 0,
items:[{
xtype: 'button',
text: 'Resubmission',
glyph: 'xf0e2#FontAwesome',
tooltip: 'Resubmit',
listeners: {
click: 'ResubmissionClick'
}
}]
};
console.log('thisw')
this.items = []
this.add({
xtype: 'panel',
frame: false,
border: false,
itemId: 'v6panel',
layout: {
type:'card',
deferredRender: true
},
defaultListenerScope: true,
bbar: ['->',
{
itemId: 'card-prev',
text: '« Previous',
handler: 'showPrevious',
disabled: true
},
{
itemId: 'card-next',
text: 'Next »',
handler: 'showNext'
}
],
items: [],
initComponent: function() {
var me = this;
me.callParent();
me.store = Ext.getStore('app-main-store-' + me.up('app-main-processinfolayout').processData.id);
if (!me.store) {
me.store = Ext.create('Example.store.ProcessInfo', {
storeId: 'app-main-store-' + me.up('app-main-processinfolayout').processData.id,
room: me.up('app-main-processinfolayout').processData.id
});
me.store.proxy.url = Ext.String.format(me.store.proxy.url,
me.up('app-main-processinfolayout').processData.id);
}
me.store.on('load', function(store, records, successful, eOpts) {
console.log('####')
me.fireEvent('refreshProcessInfoLayoutView', me, records);
});
},
listeners:{
beforerender: function(obj) {
console.log('Hey Australia')
obj.store.load();
},
refreshProcessInfoLayoutView: 'refreshProcessInfoLayoutView',
scope: 'this'
},
refreshProcessInfoLayoutView: function(obj, records) {
console.log('thise')
console.log(records[0].data.processes)
if (records[0].data.v6_processes) {
for (elem in records[0].data.processes) {
var subprocessInfo = {
xtype: 'app-main-cycle-info',
processId: records[0].data.processes[elem],
itemId: 'card-' + elem
};
obj.add(subprocessInfo);
}
}
},
showNext: function () {
this.doCardNavigation(1);
},
showPrevious: function (btn) {
this.doCardNavigation(-1);
},
doCardNavigation: function (incr) {
var me = this;
var l = me.getLayout();
var i = l.activeItem.id.split('card-')[1];
var next = parseInt(i, 10) + incr;
l.setActiveItem(next);
me.down('#card-prev').setDisabled(next===0);
me.down('#card-next').setDisabled(next===this.down('#v6panel').store.getCount() - 1);
}
})
}
})
It prints console log upto thisw . After that it gives error as...Uncaught TypeError: me.items.insert is not a function. What I am doing wrong. Please suggest.

Don't do this.callParent(); in your initComponent before specifying this.header and this.items. Do it after. This is because once you've called this.callParent(); your component is instantiated, therefore trying stuff like this.items = [] just screws things up.
Also, instead of:
this.items = [];
this.add({stuff});
do:
this.items = [{stuff}];

When dealing with nested items and initComponent functions, you can use the xhooks config so that callParent() can work properly :
Ext.define('Example.view.ProcessInfoLayout', {
// ...
xhooks: {
initComponent: function(){
this.callParent();
// ...
this.add({
xtype: 'panel',
// ...
items: [],
initComponent: function() {
// ...
}
});
}
}
});
Have a look at the Ext.Component constructor method.

Related

Trying to create a custom Panel with ExtJS

Can't find out why its isn't working..
I'm trying create a custom panel for multiple uses.
Is it the way? Or am i totally wrong.
I'm a beginner in ExtJS, so i'll be happy to a little explain..
thanks
(i'm trying to run this code on the fiddle to see the immediate result - )
Ext.application({
name: 'Fiddle',
launch: function () {
var custom = Ext.define('Ext.BET', {
renderTo: Ext.getBody()
});
}
});
Ext.define('Ext.BET', {
extend: 'Ext.panel.Panel',
alias: 'widget.bet',
constructor: function (cnfg) {
this.callParent(arguments);
this.initConfig(cnfg);
},
config: {
collapsible: true,
frame: true,
bodyStyle: 'background-color: #FFFFFF',
layout: {
type: 'hbox'
},
items: [{
xtype: 'textfield',
textarea: focus,
id: 'tbx'
}, {
xtype: 'button',
id: 'btn'
}, {
xtype: 'button',
id: 'search'
}]
},
afterRender: function () {
var btn = Ext.getCmp('btn');
var tbx = Ext.getCmp('tbx');
var btn2 = Ext.getCmp('search');
var totalWidth = btn2.getWidth() + btn.getWidth() + tbx.getWidth();
this.setWidth(totalWidth);
},
onRender: function() {
this.callParent(arguments);
}
});
You should use Ext.create instead of Ext.define.Refer this fiddle.

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

Config Proprety in Extjs-6 Picker doese not work perfectly

I'm developing an application using Extjs-6. I extend a viewclass from a Ext.form.field.Picker as follow:
Ext.define('Fiddle.MyCombo', function(){
var me;
var initComponent = function()
{
me = this;
Ext.apply(me, {});
me.callParent(arguments);
};
var createPicker = function ()
{
var textfield = {
xtype: 'textfield',
width: '100%',
border: false,
listeners: {
change: function(component, newValue)
{
me.setStr(newValue);
}
}
};
var panel = new Ext.panel.Panel({
rtl: true,
minWidth: 300,
floating: true,
items: [textfield]
});
Ext.Msg.alert('Attension', 'Init Value is : ' + me.getStr());
return Ext.widget(panel);
};
return {
extend: 'Ext.form.field.Picker',
alias: 'widget.mycombo',
initComponent: initComponent,
createPicker: createPicker,
config: {
str: ''
}
};
});
I use this class as follow:
Ext.define('Fiddle.Main', {
extend: 'Ext.panel.Panel',
width: 400,
height: 200,
title: 'Its me!',
items: [{
xtype: 'mycombo',
name: 'item1'
}, {
xtype: 'mycombo',
name: 'item2'
}]
});
When I open first mycombo(item1) and type some word in textfield input, and then open second mycombo item(items2), in createPicker function I alert str value of item, and it show the item1's value.
Why it show item1's str value?
Where is wrong?
My Sample fiddle is here.

Extjs Uncaught TypeError on loading items in form panel

I want to add some form items from a json array to a form panel. But I'm getting this error "Uncaught TypeError: this.getView(...).getStore is not a function". But this function is declared inside the controller below. I don't now how to fix it.
View:
Ext.define('myApp.viewForm', {
extend: 'Ext.form.Panel',
xtype: 'form',
controller: "form,
viewModel: {
type: "form"
},
title: 'form',
bodyPadding: 10,
autoScroll: true,
defaults: {
anchor: '100%',
labelWidth: 100
},
reconfigure: function(data) {
var me = this;
Ext.each(data, function(item, index) {
console.log(item) ;
me.add(item);
});
}
});
// create form and add store
var form = Ext.create('myApp.view.Form', {
renderTo: Ext.getBody(),
store: new myApp.store.Forms()
});
// Mocking the loading of data and firing of 'metachange' event
var mockData = {
"data": [{
"name": "ff",
"xtype": "textfield",
"allowBlank": false,
"fieldLabel": "labelText1"
}, {
"name": "fsdsdf",
"xtype": "textfield",
"allowBlank": false,
"fieldLabel": "labelText2"
}]
};
form.getStore().fireEvent('metachange', form.getStore(), mockData);
Controller:
Ext.define('myApp.view.FormController', {
extend: 'Ext.app.ViewController',
alias: 'controller.form',
init: function(application) {
this.getView().getStore().on("metachange", this.handleStoreMetaChange, this);
},
handleStoreMetaChange: function(store, meta) {
this.getView().reconfigure(meta.data);
}
});

show window in tabpanel

I am working on extjs4, my case is:
Extjs mvc is used to build my application, viewport is the toppest container of my application, west region is a tree, center region is a tabpage container, when click the tree item, a new page with certain content will be created. then in this page, I popup a model window, this model window just mask the page, not the whole viewport, so that I can still click the tree item to open another new page.
I have achieved this, but there is a problem, if I have already open a model window in a tab, and I switch to a another tab then return back, the model window is hidden, but I still want that window to show if I haven't closed it. Can anyone help me, is there a better way except using ifram in tabpage?
app.js:
Ext.application({
name: 'SysOpv',
appFolder: '/Js/AppSysOpv/app',
autoCreateViewport: true,
controllers: [
'Category',
'Band'
]
});
Viewport:
Ext.define('SysOpv.view.Viewport', {
extend: 'Ext.container.Viewport',
layout: 'fit',
initComponent: function() {
this.items = {
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
height: 80,
items: [
{ xtype: 'component', html: 'setup' }
]
}],
layout: {
type: 'hbox',
align: 'stretch'
},
items: [{
width: 250,
xtype: 'categorytree'
}, {
id: 'maintabpanel',
flex: 1,
xtype: 'tabpanel'
}]
};
this.callParent(arguments);
}
});
Tree View:
Ext.define('SysOpv.view.category.Tree', {
extend: 'Ext.tree.Panel',
alias: 'widget.categorytree',
title: 'setup',
rootVisible: false,
useArrows: true,
hideHeaders: true,
columns: [{
flex: 1,
xtype: 'treecolumn',
text: 'Name',
dataIndex: 'name'
}],
store: 'Category',
initComponent: function() {
this.callParent(arguments);
}
});
Window View:
Ext.define('SysOpv.view.edit.Band', {
extend: 'Ext.window.Window',
alias: 'widget.editband',
title: 'Setup',
layout: 'fit',
constrain: true,
modal: true,
initComponent: function() {
this.items = [{
xtype: 'form',
bodyPadding: 10,
items: [{
xtype: 'textfield',
name: 'name',
fieldLabel: 'Name'
}]
}];
this.buttons = [{
text: 'Save',
action: 'save'
}, {
text: 'Cancel',
scope: this,
handler: this.close
}];
this.callParent(arguments);
}
});
Tree Controller:
Ext.define('SysOpv.controller.Category', {
extend: 'Ext.app.Controller',
models: [ 'Category' ],
stores: [ 'Category' ],
views: [ 'category.Tree' ],
init: function() {
this.control({
'categorytree': {
itemdblclick: this.onTreeItemdblclick
}
});
},
onTreeItemdblclick: function (tree, record, item, index, e, eOpts) {
var mainTabs = Ext.getCmp('maintabpanel');
var tabId = record.get('id');
if (mainTabs) {
var checkTab = mainTabs.getComponent(tabId);
if (checkTab) {
mainTabs.setActiveTab(checkTab);
} else {
var controller;
var list;
switch (tabId) {
case '0101':
list = Ext.widget('listband');
break;
}
if (list)
{
var tabPage = mainTabs.add({
id: record.get('id'),
title: record.get('name'),
closable: true,
layout: 'fit',
items: [ list ]
});
mainTabs.setActiveTab(tabPage);
}
}
}
}
});
Module Controller:
Ext.define('SysOpv.controller.Band', {
extend: 'Ext.app.Controller',
models: [ 'Band' ],
stores: [ 'Band' ],
views: [ 'list.Band', 'edit.Band' ],
init: function() {
this.control({
'listband button[action=edit]': {
click: this.onEdit
}
});
},
onEdit: function(button, e, eOpts) {
var edit = Ext.widget('editband');
var list = button.up('gridpanel');
if (list.getSelectionModel().hasSelection()) {
var record = list.getSelectionModel().getLastSelected();
// I use renderTo here but have no effect,
// so I search in the google find a way to show the window in tab,
// and not mask all the viewport.
button.up('#0101').add(edit);
edit.down('form').loadRecord(record);
edit.show();
} else {
console.log('Not selected');
}
}
});
Below is example solution:
Ext.create('Ext.TabPanel', {
renderTo: 'container',
items: [
{
title: 'Tab 1',
itemId: 'tab1',
items: [
{ xtype: 'button', text: 'Show window', handler: function(){
var tab = this.up('#tab1'); // Find tab
var win = Ext.widget('editband'); // Find window
this.up('tabpanel').showWindow(tab, win);
} }
]
},
],
showWindow: function(tab, w){
tab.add(w);
tab.popup = w;
w.on('close', function() { // clean up after window close
delete this.popup;
}, tab, { single: true });
w.show();
},
listeners: {
tabchange: function(panel, tab) {
if (tab.popup !== undefined) { // show window after tab change
tab.popup.show();
}
}
}
});
Basically I've created event handler for tabchange event in which I re-show window.
Working sample: http://jsfiddle.net/aCxYU/1/

Resources