I added a loadmask to a panel and I want the spinner to be displayed each time stores associated with the loadmask are loaded. The panel is a large tooltip and the stores are loaded each time a point is visited in a line chart. Thus, when I hover over a point, I'm expecting a load message to appear for a short period of time before I see the contents in the panel. What I'm getting is an empty panel however. If I remove the code that I have which adds the load mask (the initComponent function), it works (without the load message though). How would I use the loadmask in this manner as opposed to explicitly calling the setLoading() method for each panel?
Here's the code:
tips:
{
...
items:{
xtype: 'panel',
initComponent: function(){
var loadMask = new Ext.LoadMask(this, {
store: Ext.getStore('CompanyContext')
});
},
id: 'bar-tip-panel',
width: 700,
height: 700,
layout: {
type: 'accordion',
align : 'stretch',
padding: '5 5 5 5'
},
items:...
}
}
config object isn't the proper place to override initComponent method. What you should do is to define a subclass of Panel, and override the method there.
Ext.define('MyPanel', {
extend: 'Ext.panel.Panel',
xtype: 'mypanel',
initComponent: function() {
this.callParent(arguments); // MUST call parent's method
var loadMask = new Ext.LoadMask(this, {
store: ...
});
},
});
Then, you can use xtype mypanel in your tips configuration.
Related
I have created a view (a panel) with 3 subpanels ...
When the view loads , I want a function to run in viewController and based on its outcome , I want subpanel 1 to be visible(subpanel2 to be invisible) or subpanel2 to be visible(subpanel1 to be invisible)
How can I accomplish this ?
You are looking for card layout. It is already implemented. So you don't have to implement again. Just tell it witch panel gonna be active it will do all layout things itself. Checkout this api doc.
May be the Accordion layout can help you:
This is a layout that manages multiple Panels in an expandable accordion style such that by default only one Panel can be expanded at any given time
Here's a full example, it's quite straight forward:
Fiddle
Ext.define('FooController', {
extend: 'Ext.app.ViewController',
alias: 'controller.foo',
init: function(view) {
var child = Math.random() < 0.5 ? 'p1' : 'p2';
view.setActiveItem(this.lookupReference(child));
}
})
Ext.define('Foo', {
extend: 'Ext.container.Container',
layout: 'card',
controller: 'foo',
items: [{
title: 'P1',
reference: 'p1'
}, {
title: 'P2',
reference: 'p2'
}]
});
Ext.onReady(function() {
new Foo({
renderTo: document.body,
width: 200,
height: 200
});
});
Give itemId to all three panel and then fireEvent.
Listener of view
listeners:{
show: function(){
me.fireEvent('showHidePanel');
}
}
define showHidePanel method in Controller and in that method get panel by using down() with item id and hide/show panel by using hide()/show() method.
Disclaimer: I am relatively new to ExtJS (version 5.01). I am hoping to reach some ExtJS experts to point me in the right direction:
I am getting an error when specifying an initComponent method within an items config. The code below generates the error:
"Uncaught TypeError: Cannot read property 'items' of undefined"
The error disappears when the 'initComponent' function of the north-child panel is commented out. I have the feeling I missed something on initialization order.
Q: How can I specify an initComponent method of a child item within the items configuration?
Ext.define('MyApp.view.TestView', {
extend: 'Ext.panel.Panel',
title: 'Parent',
height: 300,
layout: 'border',
items: [{
xtype: 'panel',
region: 'north',
title: 'North Child',
/* Problematic function: If commented, it works */
initComponent: function(){
console.log("test north child");
this.callParent(arguments);
}
}],
initComponent: function(){
console.log("Test parent");
this.callParent(arguments);
}
});
Short answer: You can't define initComponent on a child, because you can't do anything there that can't be done anywhere else.
InitComponent is executed when an instance of the component 'MyApp.view.TestView' is created (you only defined it here, using Ext.define). It can be created using Ext.create('MyApp.view.TestView',{, or by creating another view that has this component added as an item, or by deriving another component (extend:'MyApp.view.TestView').
All the child components are also created when 'MyApp.view.TestView' is created, so the initComponent function on the child would be superfluous, because the child cannot be created without the parent, so the initComponent of the parent can be used for everything that you want to do in the child's initComponent.
If you need sth. to be calculated before the items can be addded, you would proceed as follows:
Ext.define('MyApp.view.TestView', {
extend: 'Ext.panel.Panel',
title: 'Parent',
height: 300,
layout: 'border',
initComponent: function(){
var me = this,
tf = Ext.getCmp("someTextField"),
myTitle = (tf?tf.getValue():'');
Ext.applyIf(me,{
items: [{
xtype: 'panel',
region: 'north',
title: myTitle,
}]
});
this.callParent(arguments);
}
});
Please refer to the docs what exactly Ext.applyIf does (and how it differs from Ext.apply, because that function also comes handy sometimes).
I am using version 4.2.
I currently have a view which extends a panel. On this panel there is a button which displays a modal window. The controller code when the button is clicked is below (which I pulled from the extjs docs):
displaySearch : function(btn) {
var panel = Ext.create('Ext.window.Window', {
title: 'Hello',
height: 200,
width: 400,
layout: 'fit',
modal : true,
items: {
...
}
}).show();
}
I want a View I already have created to be rendered INSIDE the modal window I just defined.
How do I do that?
If you have defined an alias (xtype) for that view, let's say it is 'myview', then you just add it to items like this:
var panel = Ext.create('Ext.window.Window', {
title: 'Hello',
height: 200,
width: 400,
autoShow:true,
layout: 'fit',
modal : true,
items: [{
xtype:'myview'
}]
});
Also, you don't need to call show() on the created window, it is enough if you configure autoShow:true.
I have an MVC architecture, but when I try to make another TabPanel insite an existing one, I get this in the browser:
el is null
el = el.dom || Ext.getDom(el); ext-all-debug.js (line 12807)
From what I understand, it seems that the new TabPanel can't find the needed div for it to render. Anyway, here is the controller:
Ext.define('FI.controller.MainController', {
extend: 'Ext.app.Controller',
id: 'mainController',
views: ['MainTabPanel', 'UnitsTabPanel', 'SummariesTabPanel'],
mainTabPanel : {},
unitsTabPanel : {},
summariesTabPanel : {},
init: function(){
console.log("main controller is init");
console.log(this);
this.control({
'mainTabPanel':{
afterrender: this.onCreate
}
});
this.mainTabPanel = Ext.widget('mainTabPanel');
},
onCreate: function(){
console.log("main tab panel is created");
console.log(this);
this.unitsTabPanel = Ext.widget('unitsTabPanel');
this.summariesTabPanel = Ext.widget('summariesTabPanel');
}
});
This is the MainTabPanel:
Ext.define("FI.view.MainTabPanel", {
extend: 'Ext.tab.Panel',
renderTo:'container',
alias: 'widget.mainTabPanel',
enableTabScroll: true,
items:[{
title:'Units',
html: "<div id='units'></div>",
closable: false
},
{title: 'Summaries',
html: "<div id='summaries'></div>",
closable:false
}
]
});
And this is the SummariesTabPanel(the one with problems):
Ext.define("FI.view.SummariesTabPanel", {
extend: 'Ext.tab.Panel',
renderTo: 'summaries',
alias: 'widget.summariesTabPanel',
enableTabScroll: true
});
The problem is with the SummariesTabPanel. If I don't create it, the UnitsTabPanel gets rendered. For some reason, it can't find the summaries div.
Can you please tell me what is wrong?
The SummariesTabPanel renders to the "units" div according to your last snippet of code, is that correct? If not, replace renderTo: 'units' with renderTo: 'summaries'.
Edit
Since it was not the case, you may take a look ath this piece of Ext 4 Panel documentation (here: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.panel.Panel-cfg-html ) that says that the html content isn't added until the component is completely rendered. So, you have to wait for the afterrender event of the tab (not the tabpanel, as you do now) before you can actually get the DOM element.
If you instantiate this Panel
{title: 'Summaries',
html: "<div id='summaries'></div>",
closable:false
}
and store the pointer to it into a separate variable, you could listen to its afterrender event and try again.
A workaround to this could be using an existing element of the page (that is, a static html fragment) instead of adding it via the Panel's html config option.
Why are you doing this that way? If you want to have a nested panels - just define them inside one another. Don't use renderTo
Ext.define("FI.view.SummariesTabPanel", {
extend: 'Ext.tab.Panel',
alias: 'widget.summariesTabPanel'
});
Ext.define("FI.view.MainTabPanel", {
extend: 'Ext.tab.Panel',
alias: 'widget.mainTabPanel',
enableTabScroll: true,
items:[{
xtype: 'summariesTabPanel'
title:'Units',
closable: false
}
]
});
simple question for you today...
This works:
var carousel = Ext.create('Ext.Carousel', {
fullscreen: 'true',
//load in views view clean instantiation using
// the widget.alias's defined in each view... yea
// For some reason, putting flex on these components... oh...
// Have to call directly in by just the xtype since these are just
// references..
items: [
{
xtype: 'Main'
},
{
xtype: 'CommentList'
}
]
This does NOT work:
var tabpanel = Ext.create('Ext.TabPanel', {
fullscreen: 'true',
tabBarPosition: 'bottom',
defaults: {
styleHtmlContent: true
},
//load in views view clean instantiation using
// the widget.alias's defined in each view... yea
// For some reason, putting flex on these components... oh...
// Have to call directly in by just the xtype since these are just
// references..
items: [
{
xtype: 'Main',
title: 'The Main',
iconCls: 'user'
},
{
xtype: 'CommentList',
title: 'Comments',
iconCls: 'user'
}
]
});
As you can see, they are pretty much the same except one is a TapPanel (with the required default configs added) and the other is a carousel.
Everything else is exactly the same.... This is in the app.js of my Sencha Touch 2.0 app designed following the MVC architecture.
The result of the not-working TabPanel is that I only see the first view (Main) and no tab-bar appears in the bottom of the screen.
Any ideas what my problem might be?
I am not sure if this is an issue but in my code the line is:
Ext.create("Ext.tab.Panel", {
Not:
Ext.create('Ext.TabPanel', {
Fullscreen should be fullscreen: true instead of fullscreen: 'true'. You could also add this code to make them switch:
cardSwitchAnimation: {type: "fade", duration: 1000},
layout: "card",
Didn't test it, but it worked for me (got it from a snippet of my own code)