Setting active items in sencha touch container - extjs

I am new in developing with sencha touch 2 , i have a container that contains a list of merchants
my container has the following code
Ext.define('WL.view.tablet.Container2', {
extend: 'Ext.Container',
xtype: 'tabletContainer2',
config: {
layout: 'card',
items: [
{
xtype: 'merchants',
docked: 'left',
width: 320,
style: 'border-right: 2px solid #000'
},
{
xtype: 'container',
cls: 'tabletSplash',
flex: 1
}
]
}
});
I want to show a list of merchants products along side with the merchants list when any of the merchants in the list is tapped, the two lists will be displayed side by side
i tried to use the following code to achieve that
var products = Ext.widget('products');
Ext.widget('tabletContainer').setActiveItem(products);
but it isn't working as expected for me , any ideas on how to set an active item inside my container?

I am not sure what products or tabletContainer are in your code but if you want to add any view to certain view with card layout, here is what I would do:
var prods = Ext.getCmp("WL.view.tablet.Products");
Ext.getCmp("tabletSplashId").animateActiveItem(prods, {type: 'slide', direction: 'left', duration : 500});
where tabletSplashId is ID of container in which you want to set this view.

Related

Dynamically creating over 1k components in ExtJS

Im recieving from server a JSON containg info about 'colaboradores', for each colaborador i'm creating a panel, like this
var objChildren=[];
responseObj.map((colaborador)=>{
var newColab =Ext.create({
xtype: 'panel',
height: 425,
margin: 10,
width: 350,
border: true,
bodyBorder: false,
bodyCls: 'panelColab',
items: [
{
xtype: 'panel',
items: [
{
xtype: 'image',
baseCls: 'image-cropper',
style:{
backgroundColor:'white',
backgroundImage: 'url('colaborador+imageUrl+')'
}
}
//more nested items
]
}]
})
objChildren.push(newColab);
})
Ext.getCmp('PanelColab').removeAll();
Ext.getCmp('PanelColab').add(objChildren);
The problem is when this responseObj has like, 1k+ colaboradores, the browser informs me that one page is making my browser slower, and asks me if i want to stop the page from loading (I'm using firefox).
This approach is correct for this quantity of components?
Increasing the quantity of components may slow down the page.
You should use DataView with store containing 1k records instead of creating a 1k components.
DataView Example

(ExtJS 4.2.2) Can't get tab that wasn't been active

I have container
items: [{
xtype: 'container',
layout: 'card',
flex: 1,
itemId: 'tab-container',
deferredRender: false,
items: [ {
xtype: 'panel',
layout: 'fit',
dockedItems: [routessearch],
items: [routes]
}, {
xtype: 'panel',
layout: 'fit',
forceLayout: true,
dockedItems: [routessearch],
items: [routesSubs]
}]
}]
When page loaded I can get first tab because it is already active. But I can't get second tab because it hasn't been created.
I tried to use deferredRender:false and forceLayout:true (like in code sample), but it doesn't working.
In ExtJs you should interact with components and not with the dom directly.
So when you replace var elements = document.querySelectorAll(query); with Ext.ComponentQuery.query(query); you get an array of the matching components and you can interact with them.
From the Sencha documentation of Ext.ComponentQuery:
Provides searching of Components within Ext.ComponentManager
(globally) or a specific Ext.container.Container on the document with
a similar syntax to a CSS selector. Returns Array of matching
Components, or empty Array.
So after the component query Ext.ComponentQuery.query('#tab-container > panel') you have all inner panels.
With second = components[1] you have a reference to the second.
Now you can interact with the component.
But when you need also access to the dom of the component you get it by second.getEl().dom.
So the complete code looks like.
Ext.create('Ext.container.Container', {
renderTo: Ext.getBody(),
width: 200,
height: 200,
layout: 'card',
itemId: 'tab-container',
deferredRender: false,
items: [{
title: 'P1'
}, {
title: 'P2'
}],
listeners: {
boxready: function () {
var components = Ext.ComponentQuery.query('#tab-container > panel');
var second = components[1];
var el = second.getEl();
var dom = el.dom;
// code to interact with the component or with the dom
}
}
});
See the code in action in the Sencha Fiddle.

Multiple Instances of Custom Component in Extjs 4.2

I have a grid panel named "Teilgewerke". I am able to use it as an item of a panel like
{
xtype:'panel',
layout: {
type: 'hbox',
align: 'stretch'
},
items:[
{
//xtype: 'teilgewerkegrid',
id:'feinplanungPanelTeilgewerkeGrid',
flex: 2
},
{
xtype: 'panel',
flex: 1
}
]
}
But now when I try to use it inside another panel, it throws following error:
Uncaught TypeError: Cannot read property 'isComponent' of undefined
I found this question on Stackoverflow which is pointing to exact same problem. I tried the solution given in above link, by putting items as
initComponent: function() {
this.items = [
{
xtype:'panel',
flex: 5,
border: false,
padding: '0 20 0 20',
items:[
{
xtype: 'text',
text: 'Teilgewerke für Aufbau an beteiligte Gruppen senden.',
}
]
},
Ext.create('PfalzkomApp.view.TeilgewerkeGrid', {
padding: '0 20 0 20',
id:'aufbauTabTeilgewerkeGrid',
flex: 90
}),
{
xtype: 'panel',
border: false,
padding: '0 20 0 20',
flex: 5
}
]
this.callParent();
}
But I still have same issue. Can someone point out my mistake?
The issue you have should be that there is no xtype:'text' predefined in Sencha ExtJS. Please select one of textfield, label, container.
Please do strictly enforce correct indentation throughout your code, or else it will be unreadable soon. Furthermore use the most readable approach for component instantiation, as described below:
If you want to instantiate a custom component, you do it like you instantiate a Sencha component: Using xtype.
In the component you define, you give the component an xtype name:
Ext.define('My.custom.Component',{
xtype:'teilgewerke'
and when you create it, you require the component (so the file is loaded and the xtype is registered with ComponentManager), and then use that very xtype in your items definition:
Ext.define('MyApp.view.Component',{
extend:'Ext.panel.Panel',
requires:['My.custom.Component'],
initComponent: function() {
var me = this;
Ext.apply(me,{
items:[{
xtype:'teilgewerke'
}]
});
me.callParent(arguments);
}
});
Please be aware that all custom components you want to instantiate more than once should NEVER contain any absolute id; only the relative itemId; and they should not use absolute getCmp, only relative down(), up(), nextSibling(), previousSibling().
Solution to this problem which I found was to dynamically insert my custom component into the item array of the view(in which I wanted to add).
So in the after render of my view(in which I want to add my custom component), I did this:
var view = Ext.getCmp('aufbauTab');
view.insert(
view.items.length,
{
xtype: 'teilgewerkegrid',
padding: '0 20 0 20',
id:'aufbauTabTeilgewerkeGrid',
flex: 90
}
);
And it worked perfectly fine.

Ext JS Image in Viewport

I need some help in inserting an image in 'north' panel of Viewport.
The prob is, upon page load, size of north region is set to default: 20px. As a result, only some portion of image is visible. I want it to be adjusted as per the image height.
But as I click on split panels, it adjusts as per the size of image (seems some rendering problem at load?)
following is the ext js code.. Using Ext Js 5.0
Ext.create('Ext.container.Viewport', {
renderTo: Ext.getBody(),
layout: 'border',
items: [
{
region: 'north',
html: '<img src="..." alt="" />',
border: false,
margin: '0 0 0 0',
},{
region: 'center',
xtype: 'tabpanel', // TabPanel itself has no title
activeTab: 0, // First tab active by default
items: {
title: 'Contents',
html: 'The first tab\'s content. Others may be added dynamically'
}
}
]
});
Thanks in advance!
First problem is that when you use border layout, few items are required:
Any Container using the Border layout must have a child item with region:'center'. The child item in the center region will always be resized to fill the remaining space not used by the other regions in the layout.
Any child items with a region of west or east may be configured with either an initial width, or a Ext.layout.container.Box.flex value, or an initial percentage width string (Which is simply divided by 100 and used as a flex value). The 'center' region has a flex value of 1.
Any child items with a region of north or south may be configured with either an initial height, or a Ext.layout.container.Box.flex value, or an initial percentage height string (Which is simply divided by 100 and used as a flex value). The 'center' region has a flex value of 1.
See the doc for more info.
So I would change your panel to hbox, set the main container with flex: 1 and add some logic to make sure that when you load the images the container's layout is updated to fix it's height.
Code below, hope it helps:
Ext.create('Ext.container.Viewport', {
renderTo: Ext.getBody(),
layout: 'vbox',
items: [
{
border: false,
margin: '0 0 0 0',
items : [{
xtype : 'image',
src : 'http://cdn.sencha.io/img/touch2/Sencha-SDK-Tools-icon.png',
listeners : {
boxready : function (component) {
component.getEl().on('load', function(){
component.ownerCt.updateLayout();
});
}
}
}],
layout: {
type: 'anchor'
}
},{
flex: 1,
xtype: 'tabpanel', // TabPanel itself has no title
activeTab: 0, // First tab active by default
items: {
title: 'Contents',
html: 'The first tab\'s content. Others may be added dynamically'
}
}
]
});

Extjs Cloning a panel

panel({}) and all its contents like grid, form and want to render that exact clone to another panel is there a way to do it..is it possible to do it with panel.getEl() or is there any other way...please help
The sra's answer is incorrect. Ext's cloneConfig does exactly what you want it to. http://docs.sencha.com/ext-js/4-1/#!/api/Ext.Component-method-cloneConfig
The following code renders two of the "same" panels to the body.
var panel = Ext.create('Ext.Panel', {
width: 500,
height: 300,
title: "HBoxLayout Panel",
layout: {
type: 'hbox',
align: 'stretch'
},
renderTo: document.body,
items: [{
xtype: 'panel',
title: 'Inner Panel One',
flex: 2
},{
xtype: 'panel',
title: 'Inner Panel Two',
flex: 1
},{
xtype: 'panel',
title: 'Inner Panel Three',
flex: 1
}]
});
var clone = panel.cloneConfig();
I must admit that the old answer was not entirely correct. Cloning of Componments is available since ExtJS2 and can be done via cloneConfig(overrides) which is a instance-method.
This will return a clone of the current instance with the applied overrides (if set). A clean clone will require you to use correct configurations, meaning no instances are created within the config. Here are some information bout this For more details read the Sencha guides
Old answer (only valid if the components to clone configs contains instances instead of plain configurations)
No, there is no buildin way to do this. And you should not try it. Consider to wrap the panel in a function that returns a instance of it (a simple sort of factory).
Edit
Something like this:
Factory.Panel = function (config) {
var defaults = {
labelWidth: 80,
labelAlign: 'left',
layout: 'form',
width: 720,
autoHeight: true,
header: false,
bodyStyle: 'padding:10px 15px;'
};
var cfg = Ext.apply({}, config, defaults);
var cmp = new Panel(cfg);
return cmp;
}
You can add as much function params as you like. This would be a clean way to do it. You just can clone simple object like a record. Note that Factory is a Namespace!

Resources