Add 1 container in 2 Panels - extjs

Is it possible to add one container in two different panels? I tried doing something like this
var container = Ext.create('Ext.container.Container', {
//container content
});
var panel1 = Ext.create('Ext.form.Panel', {
//panel1 content
items : [container]
});
var panel2 = Ext.create('Ext.form.Panel', {
//panel2 content
items : [container]
});
But it adds the container only in the second Panel
Here is a Fiddle

It depends a little bit on your use case.
If you feel fine rendering the container two times you can just pass the config of the container to your panels:
var container = {
//container content
items: {
xtype: 'displayfield',
value: 'container content'
}
};
var panel1 = Ext.create('Ext.form.Panel', {
//panel1 content
renderTo: Ext.getBody(),
title: 'panel1',
items: container
});
var panel2 = Ext.create('Ext.form.Panel', {
//panel2 content
renderTo: Ext.getBody(),
title: 'panel2',
items: container
});
For reusing the instance and placing the same instance two times on different positions in the dom i see no way of achieving that. I even think its not doable at all, but maybe someone else can teach me how to do it in a clean and cozy way ;)

var container = {
items: [{
xtype: 'button',
text : 'select',
handler: function() {
alert(this.up('form').getTitle()+ " clicked");
}
}]
};
var panel1 = Ext.create('Ext.form.Panel', {
//panel1 content
renderTo: Ext.getBody(),
title: 'panel1',
items: container
});
var panel2 = Ext.create('Ext.form.Panel', {
//panel2 content
renderTo: Ext.getBody(),
title: 'panel2',
items: container
});
container is rendered on both panels.

Related

How to create multiple instances of a class in extjs

I create a class of Button and I want that button will appear on number of selection in checkbox. Right now button is appearing only one even though I selected multiple checkbox.
So far I done
I creating button class.
Added into an array
Placing this array in items of panel.
Button class
Record = Ext.extend(Ext.Container,{
initComponent: function(){
var p=this;
p.bodyPadding = 5;
p.margin = '5 5 0 3';
p.layout = 'anchor';
p.items = [{
xtype: 'button',
text : 'Hello
}];
Record.superclass.initComponent.apply(this, arguments); }});
Adding into array in function :
getRecords: function () {
var RecItems[];
recLength = Ext.getCmpBy('Rec').length
var clsName;
clsName = new Record (),
for(var i=0;i<recLength; i++){
var item = Ext.create(clsName,{
});
RecItems.push(item);
}
return RecItems;
}
Calling this in panel
{xtype:'panel',
title : "Records",
bodyStyle: 'background: #dfe8f6;border:#dfe8f6;',
autoScroll: true,
region: 'center',
layout:{
type: 'anchor',
pack: 'start',
align: 'stretch'
},
items: p.getRecords()
}

Dynamically change the value of items parameter in ExtJS 3.0

I have two menus (myMenu1 and myMenu2) and one window (myWin). How can I dynamically change the menu that is displayed in the window.
I need a code that will dynamically change the value of items in myWin.
var myMenu1 = new Ext.Toolbar({
width: 700,
items: [{
xtype: 'tbbutton',
text: 'Add',
icon: 'add_icon.gif',
handler: displayFormWindow
}]
});
var myMenu2 = new Ext.Toolbar({
width: 700,
items: [{
xtype: 'tbbutton',
text: 'Delete',
icon: 'del_icon.gif',
handler: displayFormWindow
}]
});
var myWin = new Ext.Window({
id: 'myWin',
height: 450,
width: 710,
// items: myMenu1
// items: myMenu2
});
Simply add the menus: myWin.add(myMenu1, myMenu2);
API is here: http://docs.sencha.com/ext-js/3-4/#!/api/Ext.Window-method-add
try with extend your windows and then add custom method
here is sample code
myWindow = new Ext.extend(Ext.Window,{
constructor:function(config){
// add your code here
myWindow.superclass.constructor.call(this);
},
addMethod: function(){
// add your code here
myWindow.superclass.show.call(this);
},
deleteMethod: function(){
// add our code here
myWindow.superclass.show.call(this);
}
});

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.

Extjs: Reuse the same grid in TabPanel

in a Extjs application I have a Grid and a Tabs line over it. Content of the Grid depends on the selected Tab.
Say tabs has Jan-Feb-Mar-... values. Clicking of the Tab I would reload grid's store
Question: is it possible to avoid duplicating of the 12 grid components in favor to have one shared instance?
Thanks
Disclaimer: searching at the sencha's forum, google, stackoverflow was not successful :(
It is, but it would require more effort than it is worth. Just create a prototype for your component, so that you can create new instances really quickly.
I haven't tried this myself, but I imagine that you could create a TabPanel with empty tabs and size the TabPanel so that only the tab strip is visible. Under that (using the appropriate layout, border, vbox, etc.) create your GridPanel and use the TabPanel's activate event to reload the grid based on the currently-active tab.
Hope the following implementation meet your needs
1. Create your custom grid and register it
2. place it tab panel
As the grid is created using xtype, it would not create 12 instances when you change tabs.
Application.PersonnelGrid = Ext.extend(Ext.grid.GridPanel, {
border:false
,initComponent:function() {
Ext.apply(this, {
store:new Ext.data.Store({...})
,columns:[{...}, {...}]
,plugins:[...]
,viewConfig:{forceFit:true}
,tbar:[...]
,bbar:[...]
});
Application.PersonnelGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
this.store.load();
Application.PersonnelGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
});
Ext.reg('personnelgrid', Application.PersonnelGrid);
var panel = new Ext.TabPanel({
items:[{
title:'Jan',
items: [{xtype:'personnelgrid'}]
}, {
title: 'Feb',
items: [{xtype:'personnelgrid'}]
}
....
{
title: 'Dec',
items: [{xtype:'personnelgrid'}]
}]
})
Since this is the only place discussed about this until now, I share what I just found.
The trick is use dockedItems in ExtJs 4 (Not sure either grid can be added into tbar in ExtJs 3)
When changing the active tab, only body will be change but not the docked item. Just set the grid height equal to the body during boxready and resize so that we can't see the body anymore.
This is the code for ExtJs 4.2 MVC that also make use of refs.
Ext.define('app.controller.Notification', {
extend: 'Ext.app.Controller',
views: ['notification.List'],
stores: ['Notification'],
models: ['Notification'],
refs: [{
ref: 'pnlNotif',
selector: 'pnlNotif'
}, {
ref: 'notifList',
selector: 'notifList'
}],
init: function () {
this.control({
'dbPnlNotif': {
added: this.pnlNotifAdded,
boxready: this.calcNotifListSize,
resize: this.calcNotifListSize,
tabchange: this.pnlNotifTabChange
}
});
},
pnlNotifAdded: function (pnlNotif) {
pnlNotif.add({ title: '1', html: '1' });
pnlNotif.add({ title: '2', html: '2' });
pnlNotif.add({ title: '3', html: '3' });
},
calcNotifListSize: function (pnlNotif) {
// calc the notification list height to make sure it use the whole body
// This way we can use only one instance of list to display for each tabs
// because the list is rendered as dockedItems
var height = pnlNotif.getHeight();
var headerHeight = pnlNotif.getDockedItems()[0].getHeight();
var tabBarHeight = pnlNotif.getDockedItems()[1].getHeight();
height = height - headerHeight - tabBarHeight;
if (this.getNotifList().getHeight() !== height) {
this.getNotifList().setHeight(height - 1);// - 1 to include border bottom
}
},
pnlNotifTabChange: function (pnlNotif, newTab) {
// do something to filter the list based on selected tab.
}
});
Ext.define('ML.view.Notification', {
extend: 'Ext.tab.Panel',
alias: ['widget.pnlNotif'],
title: 'Notification',
dockedItems: [{
xtype: 'notifList'
}]
});
Ext.define('ML.view.notification.List', {
extend: 'Ext.grid.Panel',
alias: 'widget.notifList',
dock: 'top',
store: 'Notification',
initComponent: function () {
this.columns = [
...
];
this.callParent(arguments);
}
});
Try this
var gridJanName = Ext.create('Ext.grid.Panel', {
enableColumnHide: false,
autoScroll:true,
store: storeJanNameGroup,
border:true,
stripeRows: true,
columnLines:false,
loadMask: true,
tbar:tbgridTools,
margin: '1 1 1 1',
pageSize: 100,
maxWidth:700,
features: [groupFeature],
selModel: {
mode: 'MULTI'
},
columns: [
{xtype:'rownumberer',width:50},
{dataIndex:'id', hidden:true},
//etc
]
});
var gridFebName = Ext.create('Ext.grid.Panel', {
enableColumnHide: false,
autoScroll:true,
store: storeJanNameGroup,
border:true,
stripeRows: true,
columnLines:false,
loadMask: true,
tbar:tbgridTools,
margin: '1 1 1 1',
pageSize: 100,
maxWidth:700,
features: [groupFeature],
selModel: {
mode: 'MULTI'
},
columns: [
{xtype:'rownumberer',width:50},
{dataIndex:'id', hidden:true},
//etc
]
});
//
//etc grid
//
var JanPanel = Ext.create('Ext.panel.Panel', {
title:'Jan',
bodyPadding: 5,
Width:780,
layout: {
type: 'hbox',
align: 'stretch'
},
items: [gridJanName]
});
var FebPanel = Ext.create('Ext.panel.Panel', {
title:'Feb',
bodyPadding: 5,
Width:780,
layout: {
type: 'hbox',
align: 'stretch'
}
//,items: [gridFebName]
});
var MarPanel = Ext.create('Ext.panel.Panel', {
title:'Mar',
bodyPadding: 5,
Width:780,
layout: {
type: 'hbox',
align: 'stretch'
}
//,items: [gridMarName]
});
//etc
var eachMonthstabs = Ext.create('Ext.tab.Panel', {
minTabWidth: 130,
tabWidth:150,
//Width:750,
scroll:false,
autoHeight: true,
id:'timestabs',
enableTabScroll:true,
items: [
{
xtype:JanPanel
},
{
xtype:FebPanel
},
{
xtype:MarPanel
}
///etc
]
});
For me good solution was to use a left toolbar called lbar with list of buttons and a single grid instead of tabpanel

Resetting event handlers in ExtJS

I have a page where there are multiple records. Each record has a button to open a dialog box to create a name. The name then creates a related record in the database and updates the source record.
There is a single dialog box instantiated and I want to show the dialog box, get the result and return it to the correct record.
The code below works once but doesn't work the second time. I can see the the Create button gets clicked but the event doesn't got caught.
Many thanks for your help.
TrailNamePresenter.prototype.onCreateTrailClick = function (trailSegment, combo, personalRouteId) {
if (!this.createTrailWindow) {
this.createTrailWindowPanel = new CreateTrailFormPanel();
this.createTrailWindow = new Ext.Window({
title: 'Create Trail',
closable: true,
closeAction: 'hide',
plain: true,
items: [this.createTrailWindowPanel],
id: 'createtrailwindow'
});
}
this.createTrailWindowPanel.on('createTrail', this.getCreateTrailHandler(personalRouteId, trailSegment, combo), null, {single:true});
this.createTrailWindow.show();
};
TrailNamePresenter.prototype.getCreateTrailHandler = function(personalRouteId, trailSegment, currentTrailCombo) {
var thisPersonalRouteId = personalRouteId;
var thisPresenter = this;
var thisCurrentTrailCombo = currentTrailCombo;
var thisTrailSegment = trailSegment;
return function(newTrailName) {
thisPresenter.mapEditorService.createPersonalTrail(newTrailName, thisPersonalRouteId, thisPresenter.getCreateTrailServiceHandler(thisCurrentTrailCombo, thisTrailSegment));
};
};
CreateTrailFormPanel = Ext.extend(Ext.form.FormPanel, {
initComponent: function() {
Ext.apply(this, {
id: 'createtrailpanel',
width: 500,
frame: true,
bodyStyle: 'padding: 10px 10px 0 10px;',
labelWidth: 50,
defaults: {
anchor: '95%',
msgTarget: 'side'
},
items: [
{
id: 'crt_trailnamefield',
xtype: 'textfield',
fieldLabel: 'Trail Name'
}
],
buttons: [{
text: 'Create',
handler: this.getCreateClickHandler()
},{
text: 'Cancel',
handler: function(b, e){
Ext.getCmp('createtrailwindow').hide();
}
}]
});
this.addEvents('createTrail');
CreateTrailFormPanel.superclass.initComponent.apply(this, new Array());
}
});
CreateTrailFormPanel.prototype.getCreateClickHandler = function() {
var thisPanel = this;
return function() {
var trailNameField = Ext.getCmp('crt_trailnamefield');
alert('click');
thisPanel.fireEvent('createTrail', trailNameField.getValue());
};
};
In ExtJS, when you have components that will belong to a parent. I would suggest using itemID, otherwise the ability of reuse of the component across your web application is reduced because id acts similarly to a singleton. Also on the action, you have {single:true} which will remove the listener after the first trigger. IF you remove that, it may solve your issue

Resources