How to get the items object without the tabs in a TabPanel? - javascript

I would like to loop through items of a TabPanel without the Tabs (which are not defined in the class, but are added by the framework dynamically).
here is the relevant code :
Ext.define('MyTabPanel', {
extend: 'Ext.tab.Panel',
config:{
height: '50px',
autoDestroy : true,
items: [
{
xtype: 'item',
},{
xtype: 'item',
}
]
}
});
When I loop through the items with the each function, it also loops through the tabs :
ext-item-1
ext-tabbar-1
ext-item-2
ext-item-3
ext-tabbar-2
ext-item-4
Is there a function to omit these hidden sneaky tabs ?
Thanks !

Try using the getInnerItems method to receive only items which are not docked to the tabpanel or floating.
var items = tabPanel.getInnerItems();
Also see this fiddle

Related

Ext.toolbar.Toolbar with overflowHandler scroll to end

Is there any property/config to say that the toolbar, when its overflowting to the right should scroll to the last item? I have a vertical toolbar. And it should scroll to the last item on the right
My config looks like:
var toolbar = Ext.create('Ext.toolbar.Toolbar', {
cls: 'toolbar',
dock: toolbarDock,
border: false,
overflowHandler: 'scroller',
items: [this.toolbar]
});
You should add parameter like enableOverflow as true to use overflowHandler.
Check sencha documentation enableOverflow

How to add an item to ext js panel on click of the panel?

I want to add a button into a panel to the exact position where I clicked.
SO I have tried like as follows, this the structure of my Ext.widget element
Ext.widget({
xtype : 'mz-form-widget',
itemId: 'shopableImage',
anchor: "100%",
defaults: {
xtype: 'textfield',
listeners: {
controller: '',
change: function (cmp) {
controller = cmp;
cmp.up('#shopableImage').updatePreview();
}
}
},
items: [
{
xtype: "tacofilefield",
itemId: "imageUploadButton",
text: "Upload images"
},
{
xtype: 'panel',
width: 350,
height: 350,
itemId:'container',
id:'container',
bodyStyle:{"background":"url('http://www.easyvectors.com/assets/images/vectors/vmvectors/jeans-girl-vector-27.jpg')","border":"1px solid #eee"},
listeners: {
click: {
element: 'el', //bind to the underlying el property on the panel
fn: function(a,b,c,d){
console.log(a.browserEvent.clientX - b.offsetLeft);
console.log(a.browserEvent.clientY - b.offsetTop);
console.log(c);
this.down('#container').addItem({"xtype":"button","text":"+"});
}
},
dblclick: {
element: 'body', //bind to the underlying body property on the panel
fn: function(){ console.log('dblclick body'); }
}
}
}
The following line throwing me error.
this.down('#container').addItem({"xtype":"button","text":"+"});
UPDATE
this.down('#container')
is returning null.
Please give me your suggestions regarding this?
There are two problems here, one is causing the error and another is a potential time bomb:
addItem does not exist, the correct method name is add
You use id's on components and that is a very bad practice, however, it does not the immediate cause of the error

Using Base Navigation view for multiple views only reference the first one

I am working on a sencha touch mobile app, and I ham having a problem. I will try to include as much details as possible.
I have a TabPanel containing 2 items: home view and contact view.
Ext.define('myapp.view.Main', {
extend: 'Ext.TabPanel',
requires: [
'myapp.view.Home',
'myapp.view.Contacts'
],
config: {
fullscreen : true,
tabBar: {
docked: 'bottom',
defaults: {
flex: 1
},
layout: {
pack: 'center'
}
},
layout: {
type: 'card',
animation: {
type: 'slide'
}
},
items: [
{ xtype: 'homeView' },
{ xtype: 'contactsView' }
]
}
});
I want to have the same navigation view for each item. The navigation view has a button that push another view.
For that I have created a BaseNavigationView.js
Ext.define('myapp.view.BaseNavigationView', {
extend : 'Ext.navigation.View',
xtype : 'baseNavigationView',
config : {
navigationBar : {
items : [ {
xtype : 'button',
text : 'My Info',
align : 'right',
id : 'myInfoButton',
ui : 'small'
}
]
},
}
});
And in the 2 views (Home and Contacts) I use
extend: 'myApp.view.BaseNavigationView'
In order to have the navigation view for both.
Until now everything is working fine.
Now for the controller, I want to add a tap event on the MyInfo button and push the myInfoView when tapped in the corresponding view.
In the controller I added to the Control section:
'#myInfoButton' : {
tap : 'onMyInfoButton'
}
and the handler:
onMyInfoButton: function(self, e, eOpts) {
//Create a new instance of the
if (!this.myInfoView) {
this.myInfoView= Ext.create('myApp.view.myInfoView');
}
//Get the parent navigation view and push the view
self.up('baseNavigationView').push(this.myInfoView);
}
When I run the application, Both the Home and Contact View are correctly showing the navigation view with the 'myInfoButton'.
The problem
When I click on the myInfoButton from the "Home" view, the "myInfoView" is pushed correctly with the back button.
However if I switch to the "Contacts" Tab and click on the myInfoButton , The "myInfoView" is pushed is Pushed in the "Home" tab and not the "Contacts" tab. so in the contacts tab nothing happens and I have to go back to the Home tab to see the pushed view.
So it is like self.up('baseNavigationView') is always referencing the navigation view of the Home and not the contact even when the button in the contact view is clicked.
How can I solve this issue?
Thanks a lot for any help.

items not loading in sencha touch 2

i have a sencha touch application that uses a tabpanel, a beta version of this application loads all items of the tabpanel and displays it.
with so many items, switching between tabs became slower
for optimization my idea is to load items only when a certain panel is activated after showing a loading mask.
i was able to make it work on first click but when i switch to the same tab another time it's not being filled or at least items are not being showed.
no exceptions are thrown.
Ext.application({
name : 'Sencha',
launch : function() {
var root = contents;
var children = root._listOfContentChild;
var mainPanel = Ext.create('components.NavigationPanel',
{
iconCls : 'more',
listeners: {
activate: function() {
mainPanel .setMasked({
xtype: 'loadmask',
message: 'Loading...'
});
setTimeout(function() {
loadItems(root,children); // returns my items
mainPanel .setItems(items);
mainPanel .setMasked(false);
}, 300);
} } });
var settingsPanel = Ext.create('components.NavigationPanel', {
title : 'Settings',
iconCls : 'settings',
});
view=Ext.Viewport.add({
xtype : 'tabpanel',
deferredRender:true,
tabBarPosition : 'bottom',
activeItem:settingsPanel,
items : [mainPanel,settingsPanel ]
});
}
});
overview:
my application is working correctly if all items are filled at the beginning before pressing on tabs
my problem is when i have a huge number of items and i press on their corresponding tab. it hangs for 1,2 secs.
a person using this application will think that he didn't press correctly on the tab and it will look so slow.
my approach is to load a mask on tab press just for 1 sec, this will make my tab respond automatically when pressed, then i add my items. this idea worked only for the first click, when i switch to another tab and back to the original nothing is being showed (except for the loading mask)
i tried mainPanel.add instead of mainPanel.setItems. i faced another problem, now in the next tap on the panel,my items are shown but without the loading mask as if i'm loading the items at the beginning before pressing.
I figured out the solution. Check the below code.
Hope that helps you!
Code :
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'Sencha',
launch: function() {
//var root = contents;
//var children = root._listOfContentChild;
var mainPanel = Ext.create('Ext.Panel', {
iconCls : 'more',
id:'mpanel',
styleHtmlContent:true,
listeners: {
painted: function() {
mainPanel.removeAll();
mainPanel.add({
masked:{
xtype:'loadmask',
id:'lmask',
}
});
setTimeout(function() {
Ext.getCmp('lmask').hide();
Ext.getCmp('mpanel').add({ xtype:'textfield',label:'Name',required:true });
}, 300);
}
}
});
var settingsPanel = Ext.create('Ext.Panel', {
title : 'Settings',
iconCls : 'settings',
});
view=Ext.Viewport.add({
xtype : 'tabpanel',
deferredRender:true,
tabBarPosition : 'bottom',
activeItem:settingsPanel,
items : [mainPanel,settingsPanel ]
});
}
});
Sample output :

ExtJS 3 using the methods of a registered component

I extended a tabpanel and registered it like such:
DVI.DviDashboard = Ext.extend(Ext.TabPanel, {
initComponent: function(){
Ext.apply(this, {
activeTab: 0,
items: [item1, item2]
});
DVI.DviDashboard.superclass.initComponent.call(this);
}
});
Ext.reg('dviDashboard', DVI.DviDashboard);
When rendered, I have a tabpanel with two tabs, item1 and item2. I would like to programatically add new tabs through the TabPanel's add() method. I am unclear how to access the tabpanel's methods however after extending.
(Stolen #amol's answer)
It'll be as simple as calling .add on the instance.
In the following example, you may want to check out how I access the instance through this from the change of scope. You may want to read up more about the event handling by checking out this manual
Example code: jsfiddle
var DVI = {};
DVI.DviDashboard = Ext.extend(Ext.TabPanel, {
initComponent: function() {
Ext.apply(this, {
activeTab: 0,
items: [{
title: 'Tab 1',
html: 'Tab 1'
}, {
title: 'Tab 2',
html: 'Tab 2'
}],
buttons: [{
text: 'Add Tab',
handler: function() {
var content = 'Tab '+(this.items.getCount()+1);
this.add(new Ext.Panel({
title: content,
html: content
}));
this.setActiveTab(this.items.getCount()-1);
},
//This 'this' is referring to your tabpanel, and by doing so,
//the 'this' in your button's handler function is in fact the object
//that you've set here, which is, the tabpabel itself.
scope: this
}]
});
DVI.DviDashboard.superclass.initComponent.call(this);
}
});
Ext.reg('dviDashboard', DVI.DviDashboard);
var dviDashboard = new DVI.DviDashboard({
renderTo: Ext.getBody()
});
Your instance of DVI.DviDashboard is a TabPanel, so you can treat it as such:
var dashboard = new DVI.DviDashboard();
dashboard.add(otherTab);
UPDATE:
Make sure you call tabPanel.doLayout() after adding a new tab, so that the tab gets rendered and laid out. Ext waits for you to call doLayout() in case you want to add tabs in batch fashion.
This is the code used to add the tab:
function buildDecisionMatrix() {
var db = new DVI.DviDashboard();
db.add({
title: 'New Tab',
xtype: 'grid',
iconCls: 'tabs',
html: 'Tab Body',
closable: true
}).show();
db.doLayout();
}
When I execute the function, the DOM shows the tab created but the tab is not displayed. Perhaps I am calling the doLayout() method on the wrong thing?
I was creating the DviDashboard using xtype like this:
tabPanel = {xtype: dviDashboard}
The function I wrote to add tabs to this panel originally looked like this:
function buildDecisionMatrix() {
var db = new DVI.DviDashboard();
db.add({
title: 'New Tab',
xtype: 'grid',
iconCls: 'tabs',
html: 'Tab Body',
closable: true
});
db.doLayout();
}
Problem was doLayout() was not rebuilding the panel with the tab. So I modified the creation of the tabPanel with an id:
tabPanel = {xtype: dviDashboard, id: 'dviDashboard'}
So I was able to get the tabPanel as a component. Then the function I build to add the tab was modified like so:
function buildDecisionMatrix() {
//var db = new DVI.DviDashboard();
var db = Ext.getCmp('dviDashboard')
var newDb = db.add({
title: 'New Tab',
xtype: 'grid',
iconCls: 'tabs',
html: 'Tab Body',
closable: true
});
db.doLayout();
dv.setActiveTab(newDb);
}
And this worked. Thanks to all that responded.

Categories

Resources