Extjs tabpanel with big complex objects or dynamically loaded objects - object

I have some problem with complex objects on tabpanel.
I have 2 complex objects with stores, windows, grids, trees and etc. Here is the beginning of the object:
Ext.define('Ext.app.DocumentsContainer', {
extend: 'Ext.container.Container',
initComponent: function(){
var documentsStore = Ext.create('Ext.data.Store', {
And I have tabpanel with 2 panels(one for each object).
full code of viewport with tabpanel:
Ext.create('Ext.container.Viewport', {
layout: 'border',
padding: '5',
items: [
{
xtype: 'container',
region: 'north',
height: 50
},
{
xtype: 'tabpanel',
activeTab: 0,
region: 'center',
width: 100,
items: [
{
xtype: 'panel',
title: 'Documents',
layout: 'border',
items: Ext.create('Ext.app.DocumentsContainer'),
},{
xtype: 'panel',
title: 'Transmittals',
layout: 'border',
items: [Ext.create('Ext.app.TransmittalsContainer')],
}]
}
],
});
When I testing my page, a have a problem, because somehow data from one object dysplays in grid in another object, or doesnt dysplay at all.
But both objects working correctly one at a time.
I think, I can fix it by dynamically loading objects when tab is opened, but dont know how can I do it.
Any suggestions?

Without knowing the internals of your two components Ext.app.DocumentsContainer and Ext.app.TransmittalsContainer one cannot reliably answer your question. Perhaps you assign the same ID to two different internal components - that's most often the reason for mixed up data.
Secondly, Frederic is right - you're overnesting your components. Both panels inside the tabpanel are unnecessary because you can put your components directly into the tabpanel as illustrated by Frederic. However, if you insist to keep your panels, try changing the layout to fit because that layout-type handles single-item-components (sized the single component to fit into the parent frame).

You are overnesting the tabpanel. The tabpanels items will automatically stretch their content. So it might just work for you.
Do this instead. Change DocumentContainer to pe panel (so it can have a title. )
Ext.define('Ext.app.DocumentsContainer', {
extend: 'Ext.panel.Panel',
initComponent: function(){
var documentsStore = Ext.create('Ext.data.Store', {
And change you tabpanel to this. I also deleted the width on your center region. center regions fills out the rest of the border layouts space automatically.
Ext.create('Ext.container.Viewport', {
layout: 'border',
padding: '5',
items: [
{
xtype: 'container',
region: 'north',
height: 50
},
{
xtype: 'tabpanel',
activeTab: 0,
region: 'center',
items: [
Ext.create('Ext.app.DocumentsContainer', {title:'Documents'}),
Ext.create('Ext.app.TransmittalsContainer', {title:'Transmittals'})
]
}
],
});
Also. as Stefan mentioned. Never ever use id´s in your ExtJS4 code. They are evil and will freck your result up eventually. itemId or just simple Ext.DomQuery is the way to do it.

Related

Pass render args to next route

I am developing a NodeJS app using Express 3.0 with Swig as my template engine. What I would like to accomplish is the passing of render arguments to the next route. I want to this because I have certain site components which exist on every single page of my site (sidebar, navbar, footer, etc). Each and every one of these components has widgets and links that toggle on and off. Right now I am doing the following to toggle these widgets:
response.render('network.html', {
activeTab: 'network',
username: request.session.username,
bread_current: 'Network',
page_title: 'Your Network',
page_subtitle: 'Mordrum',
widgets: {
navbar: {
chats: {
enabled: true,
color: 'blue',
icon: 'chatbubble'
}, messages: {
enabled: true,
color: 'red',
icon: 'mail'
}, users: {
enabled: true,
color: 'green',
icon: 'person'
}
}
}
})
There is a lot of arguments there (within the widgets object) that I end up repeating numerous times within my code (once for each route). I was wondering if there is a way to pass args to the next route.
If the data is static (it doesn't change over the course of running your app), use app.locals to store it. Any data stored in there will automatically become available to any templates:
app.locals.widgets = {
navbar: {
chats: {
enabled: true,
color: 'blue',
icon: 'chatbubble'
}, messages: {
enabled: true,
color: 'red',
icon: 'mail'
}, users: {
enabled: true,
color: 'green',
icon: 'person'
}
}
};
If the data does change, use res.locals instead. Any data stored there will also be available for any templates, but only during the lifetime of a single request. Any middleware can also access it (and change it if necessary).
The express way of doing this is to set them on res. Presumably you have a Widget1 middleware. That will set res.widget1.options and then call next(). Then another middleware will set res.widget2.options, and so on.

Sencha Touch: how to implement a left menu with layout right

I'm new using Sencha Touch 2, and I've started developing a Tablet App. I'm using Sencha Architect for design and write the code, and my app has a card layout with "left-side" and "right-side". On the left I have a main menu with some buttons. This menu is all time on the left. On the right side, I want to change the views depending what menubutton was clicked and where the user want to go (It will have more than 3 levels navigation after every button click).
My problem now is "How to change the views?". Until now, I had a Navigation.View on the right, and I has using this.getPanelFrame().push(view); method. I have problems with toolbars when a load something into navegation.view, and I know how to create views and push, but after thant I dont know how to load this views again.
I Link too an image where you can the structure of my components. My main doubt is: do I have to use a navigation.view as a "frame" to load inside other views? How to change an load others? Any alternatives?
Thanks a million"
CONTROLLER
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
panelFrame: '#PanelFrame'
},
control: {
"button#btnclientes": {
tap: 'onBtnclientesTap'
},
"#btnpedidos": {
tap: 'onBtnpedidosTap'
}
}
},
onBtnclientesTap: function(button, e, options) {
var view = Ext.create("MyApp.view.ClientesListView");
this.getPanelFrame().push(view);
},
onBtnpedidosTap: function(button, e, options) {
var view = Ext.create("MyApp.view.ClientesNewView");
this.getPanelFrame().push(view);
}
});
why dont you create a container in the right side.
and then in the items: call each view with the xtype
{
xtype: 'container',
items: [
{
xtype: 'view1',
id: 'Cview1',
hidden:true,
},
{
xtype: 'view2',
id: 'Cview2',
hidden:true,
},
{
xtype: 'view3',
id: 'Cview3',
height:'auto',
hidden:true,
}]
and then in the handler of the button you just hide the other views and show your selected view like:
{
xtype: 'button',
handler:function(){
Ext.getCmp('Cview1').hide();
Ext.getCmp('Cview2').hide();
Ext.getCmp('Cview3').show();
}
}

sencha touch: Tab with no icon

Is it possible to create a item in a tabbar-ed card layout, that has no tab?
I want to create a message overlay that stretches from screen top to the tab bar and doesn't cover the tab bar. When i do this by adding an item to the panel everything works fine except a blank icon is created on the tabbar. Is there a way to prevent this icon from being created?
you can create the new item with hidden: true config option
Ext.define('App.view.settings.SettingsContainer', {
extend: 'Ext.tab.Panel',
xtype: 'settingsContainer',
requires : [
...
],
config: {
tabBar: {
docked: 'top'
},
tab: {
title: 'Settings',
iconCls: 'user'
},
items: [{
xtype: 'settingsAccountContainer'
}
, {
xtype: 'changeCompanyView',
hidden: true
}]
}
});
changeCompanyView is created, but no tab icon is visible.
It could be activated by
settingsContainer.setActiveItem(1);
Cheers, Oleg
This should work. Add the overlay to the child item and not the tab panel.
childPanelItem.add(
Ext.create('Ext.Panel',
{
xtype:'panel',
html:'Demo',
top:0,
left:0,
right:0,
bottom:0
}
)
);
If you add to the child panel the icon will not appear on the tab bar.

extj4 grid doesn't fit in container panel

I have a grid with data, contained in a panel which also hold a title and a smaller summary grid.
the panel has layout fit and therefore the title and first grid, which is the summary grid, are displayed just fine. But the grid in question has more records than can be shown on the screen and its component height is not adjusted to the size of the panel which always fits with the height of the browser window.
What I would like to have is that the grid component's height, like the panel, is adjusted to its parent so that the scrollbar inside the grid body will show up.
My code is similar to this (initComponent is of an extension to Ext.panel.Panel):
(header in this code means the summary grid)
initComponent: function (config) {
var config = {
border: false,
hidden: false,
hideMode: "display",
padding: '5',
layout: "fit"
}
Ext.apply(this, Ext.apply(this.initialConfig, config));
this.callParent(arguments);
title = Ext.create("Ext.panel.Panel", {
html: '<h2>title</h2>',
padding: '5',
border: false
});
// the stores for the grids are created here
var storeHdr = DataStoreFactory.CreateStore("GetHeaderP", DataStoreFactory.fieldsCollection.Default);
var storeBdy = DataStoreFactory.CreateStore("GetBodyP", DataStoreFactory.fieldsCollection.Default);
var grdHeader = Ext.create("Ext.grid.Panel", {
store: storeHdr,
columns: getHeaderColumns(),
columnLines: true,
autoHeight: false,
autoWidth: false,
enableHdMenu: false,
enableColumnMove: false,
enableColumnResize: false,
disableSelection: true,
trackMouseOver: false,
sortable: false
});
var grdBody = Ext.create("Ext.grid.Panel", {
id: id,
store: storeBdy,
columns: getBodyColumns(),
columnLines: true,
autoHeight: false,
autoWidth: false,
autoScroll: true,
scroll: "vertical",
enableColumnMove: false,
enableColumnResize: false,
enableHdMenu: false,
trackMouseOver: false,
disableSelection: true
});
},
var headerGridContainer = Ext.create("Ext.panel.Panel", {
layout: "fit",
border: false,
items: [grdHeader]
});
var bodyGridContainer = Ext.create("Ext.panel.Panel", {
layout: "fit",
border: false,
items: [grdBody]
});
this.add(title);
this.add(headerGridContainer);
this.add(bodyGridContainer);
storeHdr.load();
storeBdy.load();
this.doLayout();
}
I hope someone can help me with this. Thanks in advance
edit - screenshots how it is and how it should be. Realtime Data is removed or blotted out, since it is private and doesn't matter for the problem.
this is how it is
this is how it should be
You're using layouts in a wrong way. First, your main container has layout 'fit' which supposed to be used when you have single item inside - http://docs.sencha.com/ext-js/4-0/#!/api/Ext.layout.container.Fit - and you have few items.
Second, try to avoid over-nesting. You're wrapping your grids into panels and then put these panels inside container. Is there a reason for that?
Please post a screenshot of what you have and what you want to have and we will help you figure out layouts that you need to use for this.
Update:
Try to use layout: 'hbox' in your main container. And specify flex: 1 for the main (bottom) grid if you want it to fill the rest of the screen. Son basically you would have something simliar to this (in you main container):
{
layout: 'hbox',
..
items: [{
xtype: 'panel', // header
height: 100,
},
{
xtype: 'grid', // first grid
height: 200
},
{
xtype: 'grid', // second grid
flex: 1
}]
}

Problem with layouts

My goal is to make somethink like this:
There is viewport with border layout. "Container" and "center" both have "fit" layout. The "Panel" has 'vbox' layout and has three elements. The grid has one row when loaded the first time. I want all the grid to catch all the height and the button panels on top and in the bottom of it. If I don't specify the height of the grid or "container" or "Panel", I don't see anything.
How can I make it work?
Remove the excess panels and make the grid panel itself the center region of the border layout. The "button panels" should be toolbars of the grid panel:
new Ext.Viewport({
layout: 'border',
items: [
{
region: 'center',
xtype: 'grid',
// ... other required grid properties, like 'store' and 'columns'
tbar: [
// Top toolbar. Items are Ext.Button instances.
{
text: 'Button 1'
},
{
text: 'Button 2'
}
],
bbar: [
// Bottom toolbar. Items are Ext.Button instances.
{
text: 'Button 3'
},
{
text: 'Button 4'
}
]
}
]
});
The problem is that grids and elements will want to use the least amount of vertical space possible unless you set a fixed height on them. The best solution is to use a min-height style to allow the grid to grow as long as it wants but always be at least some minimum value.
It would be helpful if you posted some code. If the panel has a tbar and bbar and it's only items is a gridpanel then you could give the gridpanel a flex (I think any number will work)and you probalbaly want the layoutConfig to be align : 'stretch' . In a vbox layout if a child's flex is not provided it will use the original height of the child.
Panel({
layout: {
type: 'vbox',
align: 'stretch'
},
tbar: {},
bbar: {},
items : [{
xtype:'grid',
flex: 1
}]
})

Resources