Extjs Cloning a panel - extjs

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!

Related

How to properly define properties in ExtJS custom class

I am attempting to create a reusable title bar for our grids. This will require a couple of properties which can be set when the grid title bar is used. The problem I am running into is that the property is undefined when I attempt to use it.
I looked at how ExtJS appears to do this and saw that they set up their properties in the config block. So I tried that with no luck. I have also tried removing the config block and adding the property with the same result.
Ext.define('ERM.view.mastersite.GridTitleBar', {
extend: 'Ext.TitleBar',
xtype: 'gridtitlebar',
margin: '0 0 20 0',
shadow: true,
cls: 'x-big',
style: {
border: 'solid lightgrey 2px'
},
config: {
addNewToolTip: 'test',
},
items: [{
xtype: 'button',
iconCls: 'md-icon-add-circle',
text: 'Add',
align: 'right',
tooltip: this.parent.addNewToolTip,
}],
});
I'm expecting the tool tip to show "test" by default, or if the default is overridden, I'm expecting it to show the overridden string.
Edit
Second attempt based on the answers below.
Ext.define('ERM.view.mastersite.GridTitleBar', {
extend: 'Ext.TitleBar',
xtype: 'gridtitlebar',
margin: '0 0 20 0',
shadow: true,
cls: 'x-big',
style: {
border: 'solid lightgrey 2px'
},
config: {
addNewToolTip: 'test',
},
initialize: function () {
const me = this;
me.items = [{
xtype: 'button',
text: 'Add',
iconCls: 'md-icon-add-circle',
tooltip: me.getAddNewToolTip(),
}];
this.callParent();
},
});
if you are using modern toolkit use initialize method instead of initComponent
You're correctly defining the property. Your problem is the way you are accessing it.
At the time of building the items construct, the this context is whatever has loaded the file - probably the boot loader. Strangely enough, that won't have your new property.
In order to access properties of your new class/object, you need to define the items construct after the object is created. One good location for that is in the initComponent method.
Ext.define('ERM.view.mastersite.GridTitleBar', {
// in here, the 'this' context is whatever loaded the file.
...
config: {
addNewToolTip: 'test',
},
...
initComponent: function() {
// In here, like most methods in ExtJS, the 'this' context is the owning instance.
this.items = [{
xtype: 'button',
...
// Oh, and it's a good idea to use the accessors for config variables
tooltip: this.getAddNewToolTip()
}]
// don't forget to call the parent.
this.callParent(arguments);
});

(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.

How to working with treepicker in extjs 4.1.1

I try to create treepicker but i can't done with that http://jsfiddle.net/UKFVd/
Here is my code
var Panel = Ext.create('Ext.panel.Panel', {
bodyPadding: 5,
width: 300,
height: 100,
title: 'Filters',
items: [ {
xtype: 'treepicker',
name: 'list_id',
fieldLabel: 'Task List',
labelWidth: 60,
displayField: 'text',
store: store
}],
renderTo: Ext.getBody()
});
i check error is TypeError: k is undefined How to working with treepicker thanks
You need to include:
Ext.ux.TreePicker
if you have not.
The code in the fiddle you posted is perfectly fine, however, on the left side under External Resources, add the full URL path to TreePicker.js, and try again, and it will work.
Here is a working fiddle rev: http://jsfiddle.net/UKFVd/6/
Tree picker is not an out of box component that ships with extjs, you have to add it to your web page as an additional resource.
here is a page showing examples:
http://extjs.dariofilkovic.com/

Adding panels using button handler in Sencha Touch

I need a little help, I am building an app in Sencha Touch and I need to change the docked items within a container when a button is pressed. I assume this is the best way to alter the content within the app (i.e. switching between pages).
So far I have the following code -
var App = new Ext.Application({
name: 'Test',
useLoadMask: true,
launch: function () {
// Toolbar
Test.views.toolbar = new Ext.Toolbar({
id: 'toolbar',
title: 'Friend Pay'
});
// Content
Test.views.content = new Ext.Panel({
id: 'content',
layout: 'fit',
dockedItems: [{
cls: 'copy',
html: '<h2>Copy block</h2>'
}, {
xtype: 'button',
id: 'buttonPanel',
html: 'Request Payment',
handler: function () {
// Link to newBlock panel
}
}]
});
// Content
Test.views.newBlock = new Ext.Panel({
id: 'content',
layout: 'fit',
dockedItems: [{
cls: 'copy',
html: '<h2>Test 2</h2>'
}]
});
// Container
Test.views.container = new Ext.Panel({
id: 'container',
layout: 'fit',
dockedItems: [Test.views.toolbar, Test.views.content]
});
// Viewport - Entire screen
Test.views.viewport = new Ext.Panel({
fullscreen: true,
scroll: 'vertical',
items: [Test.views.container]
});
}
});
What function is required within the function() tag for the button handler to change the dockedItem within the container to be newBlock rather than content.
Many thanks for help in advance.
addDocked and removeDocked.
Test.views.viewport.removeDocked( Test.views.content )
Test.views.viewport.addDocked( Test.views.newBlock )
It seems a little odd you are adding content into dockedItems though, maybe you ment to add them to the normal items collection?
Either way, checkout everything available for Ext.Panel in the main api docs to familiarise yourself with the standard component functions.

Resources