Adding buttons to a view from its controller in ExtJS 4.1 - extjs

I've the following code:
// wlpt.js
Ext.onReady(function() {
Ext.application({
name: 'WLPT',
appFolder: 'app',
controllers: ['MenuPanel'/*, 'Employees'*/],
launch: function() {
WLPT.application = this;
},
autoCreateViewport: true
});
});
//viewport.js
Ext.define('WLPT.view.Viewport', {
extend:'Ext.container.Viewport',
id:'viewport',
requires:[
'WLPT.view.Header',
'WLPT.view.MenuPanel'
],
layout: 'fit',
initComponent: function() {
this.items = {
layout: 'border',
items: [{
region: 'north',
xtype: 'headerview',
height: 80
},{
region: 'west',
id: 'westernPanel',
xtype: 'menupanelview',
width: 200,
collapsible: true
},{
xtype: 'panel',
title: 'Center Panel',
region: 'center'
}]
};
this.callParent();
}
});
// controller/MenuPanel.js
Ext.define('WLPT.controller.MenuPanel', {
extend: 'Ext.app.Controller',
currentYear: 0,
views:['MenuPanel'],
refs:
[{
selector: '.menupanel',
ref: 'menuPanel'
},{
selector: '#centerPanel',
ref: 'centerPanel'
}],
init: function() {
var d = new Date();
this.currentYear = d.getFullYear();
this.control({
'#btnEmployee': {
click: this.btnEmployeeClicked
}
});
this.callParent(arguments);
rolevalue = 10;
if (rolevalue == 10) {
// user is member of administration group
this.addAdminButtons();
}
},
addAdminButtons:function() {
console.log('addAdminButtons');
**this.getMenuPanelView().add({
xtype:'button',
scale: 'large',
text: 'Projects',
itemId: 'btnProject'
});**
}
});
// view/MenuPanel.js
Ext.define('WLPT.view.MenuPanel', {
extend: 'Ext.panel.Panel',
alias: 'widget.menupanelview',
bodyPadding: 2,
title: 'Menu Panel',
layout: {
type:'vbox',
align:'stretch'
},
items: [{
xtype:'label',
height: 10
}],
autoShow: true,
initComponent: function() {
this.callParent(arguments);
}
});
My problem is that the controller doesn't add the button on the view. I get the followig error:
Uncaught TypeError: Object function h(){return
this.constructor.apply(this,arguments)||null} has no method 'add'
What am I doing wrong?
Thanks for your help in advance

You need to add a reference to your menupanel. assign your menupanel an itemId: menupanel and in your controller you can reference it can reference it with: #menupanel. I noticed that you have .menupanel as the selector which I'm not sure is completely correct.
I also noticed that your are doing this.getMenuPanelView() which not correct as you don't have a reference to menuPanelView in your controller.
TIP:
Also you could use your browser's debugging tool(Google Chrome is my favorite) and add break points in your code to easily evaluate your code.

Related

Sencha ExtJS: radiofields unselected

Please consider two modal windows that refer to the common container with the group of radiofield in the below fiddle.
https://fiddle.sencha.com/#view/editor&fiddle/3e45
Initially, the first radio R1 is correctly checked in containers of both windows. However, checking any radiofield on one of the windows unselects all the radiofield items on another window.
Two windows contain independent instances of the container, so it's unclear how they can affect each other. This behavior is not happening with any other elements (e.g. checkboxes), only radios.
Any ideas are very much appreciated.
Put/wrap your radio fieldset in form panel, in this case it will keep the value (yourForm.getValues()):
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('fsContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.fsContainerHandler'
});
Ext.define('fsContainer', {
extend: 'Ext.form.Panel', // ---== Extending form now. ==---
xtype: 'xFSContainer',
sfx: '',
controller: 'fsContainerHandler',
items: [{
xtype: 'fieldset',
title: 'myFieldset',
reference: 'fsRef',
flex: 1,
items: [{
xtype: 'radiofield',
checked: true,
name: 'myRadio',
boxLabel: 'R1'
}, {
xtype: 'radiofield',
checked: false,
name: 'myRadio',
boxLabel: 'R2'
}, {
xtype: 'radiofield',
checked: false,
name: 'myRadio',
boxLabel: 'R3'
}]
}]
});
Ext.define('mainContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.mainContainerHandler',
singleton: true,
onButton1Click: function () {
var win = this.getView().window1;
win.show();
},
onButton2Click: function () {
var win = this.getView().window2;
win.show();
}
});
Ext.define('mainContainer', {
extend: 'Ext.container.Container',
width: 400,
height: 400,
controller: 'mainContainerHandler',
window1: null,
window2: null,
initComponent: function () {
this.window1 = Ext.create('window1');
this.window2 = Ext.create('window2');
this.callParent(arguments);
},
items: [{
xtype: 'button',
text: 'Window 1',
reference: 'btn1',
handler: mainContainerHandler.onButton1Click,
scope: mainContainerHandler
}, {
xtype: 'button',
text: 'Window 2',
reference: 'btn2',
handler: mainContainerHandler.onButton2Click,
scope: mainContainerHandler
}]
});
Ext.define('window1', {
extend: 'Ext.window.Window',
title: 'Window1',
modal: true,
width: 400,
height: 400,
closeAction: 'hide',
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
reference: 'theContainer'
}]
});
Ext.define('window2', {
extend: 'Ext.window.Window',
title: 'Window2',
modal: true,
width: 400,
height: 400,
closeAction: 'hide',
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
reference: 'theContainer'
}]
});
Ext.create('mainContainer', {
renderTo: document.body
});
}
});

Error on event listener in view.

file custom.js
Ext.define('BookApp.view.Customs', {
extend: 'Ext.container.Container',
requires:['BookApp.controller.MainController'],
xtype: 'customs',
controller: 'main',
viewModel: {
type: 'main'
},
layout: {
type: 'border'
},
items: [{
xtype: 'panel',
bind: {
title: '{name}'
},
region: 'west',
html: '<ul>...</ul>',
width: 250,
split: true,
tbar: [{
text: 'Button',
handler: 'onClickButton'
}]
},{
region: 'center',
xtype: 'tabpanel',
items:[{
title: 'Tab 1',
html: '<h2>Content ...</h2>'
}]
}]
});
I have controller MainController
Ext.define('BookApp.controller.MainController', {
extend: 'Ext.app.Controller',
requires: [
'Ext.MessageBox'
],
//alias!!!!
alias: 'controller.main',
onClickButton: function () {
Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
},
onConfirm: function (choice) {
if (choice === 'yes') {
console.log('ALALA')
}
}
});
but when i click on button with property :
tbar: [{
text: 'Button',
handler: 'onClickButton'
}]
Error :
Uncaught TypeError: undefined is not a function
Have a look at http://docs.sencha.com/extjs/5.0/application_architecture/view_controllers.html
All that was wrong was that you were extending Ext.app.Controller instead of Ext.app.ViewController
Here is a slightly simplified version excluding the viewModel binding
//app.js
Ext.application({
name: 'BookApp',
launch: function() {
Ext.create('BookApp.view.Customs', {
fullscreen: true
});
}
});
....
controller/MainController.js
Ext.define('BookApp.controller.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
onClickButton: function() {
Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
},
onConfirm: function(choice) {
if (choice === 'yes') {
console.log('ALALA');
}
}
});
.....
view/view.Customs.js
Ext.define('BookApp.view.Customs', {
extend: 'Ext.container.Container',
xtype: 'customs',
controller: 'main',
renderTo: Ext.getBody(),
items: [{
xtype: 'panel',
title: 'testPanel',
region: 'west',
html: '<ul>...</ul>',
width: 250,
split: true,
tbar: [{
text: 'Button',
handler: 'onClickButton'
}]
}, {
region: 'center',
xtype: 'tabpanel',
items: [{
title: 'Tab 1',
html: '<h2>Content ...</h2>'
}]
}]
});
Demo: https://fiddle.sencha.com/#fiddle/gdu

How to add accordian items dynamically?

I have view like this :
Ext.define('Example.demo.CycleInfo', {
extend: 'Ext.panel.Panel',
requires:[
'Ext.layout.container.Accordion'
],
xtype: 'cycleinfo',
title: 'All Data',
defaults: {
frame: true,
bodyPadding: 5
},
initComponent: function() {
data = this.data
Ext.apply(this, {
items: [{
layout: 'accordion',
frame: true,
bodyPadding: 5,
items: [{
xtype:'structure'
},
{
title: 'Requests',
html: 'Empty'
}]
}]
});
this.callParent();
}
});
Here there are two accordian (one included item and other Requests) they are static .. I want based on this.data value(contains length) It should have accordian in the inner items. How should I do it.
If you want to add more panels to your main container with accordion layout, this should work:
Ext.define('Example.demo.CycleInfo', {
extend: 'Ext.panel.Panel',
requires:[
'Ext.layout.container.Accordion'
],
xtype: 'cycleinfo',
title: 'All Data',
defaults: {
frame: true,
bodyPadding: 5
},
initComponent: function() {
me = this;
Ext.apply(me, {
items: [{
layout: 'accordion',
frame: true,
bodyPadding: 5,
items: [{
title: 'Testing...',
html: 'This is a test panel'
},{
title: 'Requests',
html: 'Empty'
}]
}],
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
ui: 'footer',
items: ['->',{
text: 'Add panel',
handler: function() {
this.up().up().down('panel').add({
title: 'New Panel',
html : 'New Content'
})
}
}]
}]
});
this.callParent();
}
});
Ext.create('Example.demo.CycleInfo',{
renderTo: Ext.getBody(),
width: 500,
height: 500
});
Ext.define('CycleInfo', {
extend: 'Ext.panel.Panel',
requires:[
'Ext.layout.container.Accordion'
],
xtype: 'cycleinfo',
title: 'All Data',
width : 400,
height : 500,
defaults: {
frame: true,
bodyPadding: 5
},
layout: 'accordion',
initComponent: function() {
this.tbar = [{
text : 'Add Panel To Accordion',
handler : function(){
this.add({
xtype:'panel',
html: 343434
});
},
scope:this
}];
this.callParent();
}
});
Ext.create('CycleInfo',{renderTo:Ext.getBody()});
In your case you must change **xtype** in initComponent all is well

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

Why do I get "TypeError: item.onAdded is not a function" when adding component to container?

I am trying to create a framework UI that creates container contents based on configs, and I get an error "TypeError: item.onAdded is not a function".
This does not happen in my smaller test app, but it does happen in our actual app. Can't figure out why.
Here is some partial code.
Ext.define('atlas.screen.Viewport', {
extend: 'Ext.container.Viewport',
alias: 'widget.atlas.Viewport',
autoScroll: true,
layout: 'fit',
requires: [
'base.framework.MainAppView',
'base.framework.MainAppNavigation'
],
items: [{
// MainAppView requires providing config with items to populate the north,
// west, and center regions.
xtype: 'mainAppView',
westItems: [{
xtype: 'mainAppNavigation'
}]
}]
});
Ext.define('base.framework.MainAppView', {
extend: 'Ext.container.Container',
alias: 'widget.mainAppView',
requires: ['base.util.CommonBaseUtil'],
autoScroll: true,
layout: 'border',
westItems: null,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'container',
itemId: 'appWestContainer',
region: 'west',
width: 85,
items: me.westItems,
hidden: true,
listeners: {
afterrender: CommonBaseUtil.showHide
}
}]
});
me.callParent(arguments);
},
applyWestItems: function(westItems) {
this.down('#appWestContainer').add(westItems);
}
});
Ext.define('base.framework.MainAppNavigation', {
extends: 'Ext.container.Container',
alias: 'widget.mainAppNavigation',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'button',
itemId: 'myButton',
text: 'test'
}]
});
me.callParent(arguments);
}
});
It was one of my favorite BS ExtJS issues, "extends" VS "extend". You would think Sencha Cmd could catch this.

Resources