how to reuse the same item in multiple tab so that when that item change, other tab will reflect the changes
i try this code but the label in first tab not shown:
var label = Ext.create('Ext.form.Label', {
text : 'mylabel'
});
Ext.onReady(function() {
Ext.create('Ext.tab.Panel', {
width : 200,
height : 200,
renderTo : Ext.getBody(),
items : [{
title : 'tab1',
items : [label, {
xtype : 'button',
handler : function() {
label.setText('changed from tab1');
}
}]
}, {
title : 'tab2',
items : [label, {
xtype : 'button',
handler : function() {
label.setText('changed from tab2');
}
}]
}]
});
});
i'm sorry, what i mean is to use the label globally(like global variable) so that the same instance of label can be displayed and changed from every tab
you can define your label component:
Ext.define('MyLabel', {
extend: 'Ext.form.Label',
alias: 'widget.mylabel',
text : 'mylabel'
});
the alias property is an alias for the class name (in this case MyLabel) and that is why you can use "mylabel" as an xtype
in this way you can reuse the component, like this
var panel = Ext.create('Ext.tab.Panel', {
width : 200,
height : 200,
renderTo : Ext.getBody(),
items : [{
title : 'tab1',
items : [{
xtype: 'mylabel',
itemId: 'item1'
}, {
xtype : 'button',
handler : function(button) {
panel.down('#item2').setText('changed from tab1');
}
}]
}, {
title : 'tab2',
items : [{
xtype: 'mylabel',
itemId: 'item2'
}, {
xtype : 'button',
handler : function(button) {
panel.down('#item1').setText('changed from tab2');
}
}]
});
You can't do exactly what you want here. You see, when you create a label, it has underlying DOM, and naturally that DOM can only exist in one place (so it can't show the same thing on both tabs).
If there is a component that you are wanting to show on both tabs, it seems like it is "higher up" from a data hierarchical perspective. Perhaps it belongs outside the tab panel?
If the label truly belongs in both tabs and should be "the same", you are either going to need to fake it or manually move it between the tabs.
Option 1: Fake It
You can get the most code reuse here by creating a custom Label class, like laurac posted. You still need to keep the label text in sync, so you are going to need to update one when the other's text is changed:
var label1 = Ext.create('Ext.form.Label', {
text : 'mylabel'
});
var label2 = Ext.create('Ext.form.Label', {
text : 'mylabel'
});
Ext.onReady(function() {
Ext.create('Ext.tab.Panel', {
width : 200,
height : 200,
renderTo : Ext.getBody(),
items : [{
title : 'tab1',
items : [label1, {
xtype : 'button',
handler : function() {
label1.setText('changed from tab1');
label2.setText('changed from tab1');
}
}]
}, {
title : 'tab2',
items : [label2, {
xtype : 'button',
handler : function() {
labe2.setText('changed from tab2');
labe1.setText('changed from tab2');
}
}]
}]
});
});
Clearly that doesn't feel to "clean".
Option 2: Manual Control
This might be hacky, but slightly less hacky than option 1. Basic idea is to move the label between to two tabs when they are activated:
var label = Ext.create('Ext.form.Label', {
text : 'mylabel'
});
Ext.onReady(function() {
Ext.create('Ext.tab.Panel', {
width : 200,
height : 200,
renderTo : Ext.getBody(),
items : [{
title : 'tab1',
items : [{
xtype : 'button',
handler : function() {
label.setText('changed from tab1');
}
}],
listeners: {
scope: this,
activate: function(panel) {
panel.insert(0, label);
panel.doLayout();
}
}
}, {
title : 'tab2',
items : [{
xtype : 'button',
handler : function() {
label.setText('changed from tab2');
}
}],
listeners: {
scope: this,
activate: function(panel) {
panel.insert(0, label);
panel.doLayout();
}
}
}]
});
});
Note: I haven't started using Ext4 yet, so some of the code I added might need to be changed for Ext4 (I think maybe doLayout went away?).
Anyway, those are the only two ways I can think of to solve your problem.
Good luck!
Related
I'm using getRowClass function for custom grid row styling. In a panel component I have 2 similar grids which should have the same getRowClass logic. I would like to define the function body in the controller binded to the parent component. Below I placed some test code that illustrates the problem. In the example getRowClass is set to point to color function defined in the main controller, however this function cannot be seen in this scope. I don't have much experience in extJS and I don't know how to solve this kind of scope problems, any help will be appreciated.
Ext.define('Test.controller', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
color : function(row,index){
return 'green-row';
}
});
Ext.onReady(function() {
win = new Ext.Window({
title:'Test',
layout:'fit',
width:400,
closeAction:'close',
target : document.getElementById('buttonId'),
plain: true,
controller: 'main',
items: [{
xtype: 'grid',
store: Ext.create("testApp.store.Objects"),
selType: 'checkboxmodel',
columns : [{
text : 'Column1',
dataIndex : 'Column1'
},{
text : 'Column2',
dataIndex : 'Column2'
},{
text : 'Column3',
dataIndex : 'Column3'
}],
viewConfig : {
getRowClass : 'color'
}
}]
});
Ext.create('Ext.Button', {
renderTo: Ext.getElementById('buttonId'),
text: 'Click Me',
listeners: {
click: function() {
win.show();
}
}
});
});
All config objects are only relevant at instantiation time of a class and don't have any effect afterwards.
You can resolve you issue like this:
listeners : {
afterrender: function(p){
p.getView().getRowClass = this.up('window').getController().color;
}
}
I am creating a toolbar in my code below. What I'm wondering is how to place these inside a panel?
var toptoolbar = Ext.create('Ext.toolbar.Toolbar', {
id: 'ttool',
width: '100%',
items: [
{ text : 'MetaCenter',
menu : {
items: [
{ text : 'Wiki' },
{ text : 'JIRA' },
{ text : 'SVN' },
{ text : 'Sharepoint',
menu : {
items: [
{text : 'text 1'},
{text : 'text 2'}
]
}
}]
}
}
]
});
What I want to do is something like:
Ext.create.('Ext.panel.Panel', {
id: 'panel',
tbar: { //code to create the toptoolbar }
....
EDIT:
What I want to have is a very extensive drop down menu with sub menus on a toolbar, I'm trying to avoid putting all of that code to create that toolbar inside of my application. Instead I want to be able to call it from a variable (or better yet, a class?). Kind of like abstraction/encapsulation.
Is this a standard way of component instantiation or are there more-efficient methods?
Cheers!
Check out the ExtJS docs for dockedItems, they give exactly this scenario as an example: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.panel.Panel-cfg-dockedItems
You can define the toolbar in the initComponent method of the panel.
Ext.define('MyApp.view.MyPanel', {
extend: 'Ext.panel.Panel',
height: 250,
width: 400,
title: 'My Panel',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
dockedItems: [
{
xtype: 'toolbar',
dock: 'top'
}
]
});
me.callParent(arguments);
}
});
I am trying to add a tabpanel as an item in the panel but it does not work as expected.
I have defined tabpanel as a separate view as below.
Ext.define("WU.view.WUTabPanel", {
extend: "Ext.tab.Panel",
alias: "widget.wuTabPanel",
config: {
tabBar: {
docked: 'bottom'
},
items: [
{
title: 'Home',
iconCls: 'home',
html: 'Home Screen',
},
{
title: 'Send Money',
iconCls: 'favorites',
html: 'Contact Screen',
}
]
},
});
This is my main view where I am trying to add the tabPanel inside the Panel.
Ext.define('WU.view.WUHomePage', {
extend : 'Ext.Panel',
requires : [ 'Ext.Toolbar', 'Ext.TitleBar', 'Ext.dataview.List', 'Ext.Ajax', 'Ext.data.proxy.Ajax' ],
xtype : 'homePage',
alias : 'widget.wuHomePageView',
config : {
fullscreen : true,
title : 'MainMenu',
// iconCls : 'mainMenuhome',
disabledCls : 'mainMenuhome',
items : [
{
xtype : 'titlebar',
title:'Main Menu',
items : [ {
text : 'Back',
ui:'back',
id : 'homePageBack',
align : 'left',
handler : function(btn) {
console.log('HomePaga >> Back to Login');
this.up('homePage').fireEvent('backButtonCommand', this,'homePage');
}
} ]
},
{
xtype : 'list',
id : 'mainList',
title : 'Sample',
height : '100%',
},
itemTpl : '<div class = mainList>'
'<div class = listArrowImage><img class= mArrowImage src={arrow}></img></div>'
</div>',
},
{
xtype: 'wuTabPanel',
},
],
},
});
When the mainPage is rendered,the tab bar is not appeared in the bottom and leave the hollow space in the bottom.
Is there any issue with the configuration? Any better ideas on how to achieve this part? In my application,
there are 7-8 views and all have same tabbar in the bottom.
Thanks.
You seem to be trying to put a titlebar, height 100% list, and tabpanel into one fullscreen component. The titlebar is fine I'm sure (if it is a docked toolbar), but your list is trying to take up all the height and leaving none for the tabpanel. Remember a tabpanel is not a tabbar, it's both. If you want the bottom bar to control all the main views hen set your list as one of the tabpanel items.
Hello, I'm developing a project using Ext Js that needs to edit a line in a grid. I'm trying to use a plugin I found in Ext's documentation, plugins: [Ext.create ('Ext.grid.plugin.RowEditing')] but when I click on the line, update and cancel options appear on the grid, but the cell is not editable, does anyone know what's going on?
The example in the documentation with the plugin is this: http://docs.sencha.com/ext-js/4-0/#!/example/restful/restful.html
My code so far:
Ext.define('GridEditavel',{
extend : 'Ext.grid.Panel',
title: 'Grid Editavel',
store: 'GridStore',
dockedItems : [ {
xtype : 'toolbar',
items : [ {
xtype: 'button',
text : i18n['vds.botao.nova.coluna'],
icon : Webapp.icon('add1.png'),
iconAlign : 'top',
handler : function() {
var gridView = Ext.ComponentQuery.query("gridpanel")[1];
Ext.Msg.prompt('Message', 'Enter a column number:', function(
btn, text) {
if (btn == 'ok' && text != null) {
var column = Ext.create('Ext.grid.column.Column', {
text : text
});
gridView.headerCt.insert(gridView.columns.length,
column);
gridView.getView().refresh();
} else {
Ext.Msg.alert('Alert', 'Enter a column number!');
}
});
}
} ]
} ],
columns: [{
header : 'Nome',
dataIndex : 'nome',
flex : 0.8
}],
plugins : [ Ext.create('Ext.grid.plugin.RowEditing') ]});
You need to set the editor property in the columns. Example:
columns:[{
header:'Nome',
dataIndex:'nome',
flex:0.8,
editor:'textfield'
}]
You can also use a config object for the editor, like this:
columns:[{
header:'Nome',
dataIndex:'nome',
flex:0.8,
editor:{
xtype:'combo',
store:'somestore'
}
}]
I am developing an application using ExtJs, one of the features is to edit a record already saved. There is a grid where I select the line that I want to edit, and a panel appears with the information to be edited. But one of the attributes that can be edited is another object of my system, called a configuration, and this configuration has an id, which is loaded when you edit the registry. The problem is that when I click on the icon of the grid that lets you edit, the first time the id is retrieved, the second the id does not appear anymore, and the third time displays the following error:'
Uncaught TypeError: Cannot read property 'id' of undefined Grid.js:36
Ext.define.columns.items.handler Grid.js:36
Ext.define.processEvent
Ext.define.processEvent Table.js:755
fire ext-debug.js:8583
Ext.define.continueFireEvent Observable.js:352
Ext.define.fireEvent Observable.js:323
Ext.override.fireEvent EventBus.js:22
Ext.define.processItemEvent Table.js:844
Ext.define.processUIEvent View.js:475
Ext.define.handleEvent View.js:404
(anonymous function)
Ext.apply.createListenerWrap.wrap
My code is (when I click edit icon):
icon : Webapp.icon('editar.png'),
tooltip : 'Editar',
handler: function(view, rowIndex, colIndex, item, e) {
var record = Ext.getStore('EstacaoStore').getAt(rowIndex);
var form = Ext.create('PanelNovaEstacao');
record.set('modoIgnorar', record.data.modoIgnorar);
record.set('latitude', record.data.latitude);
record.set('longitude', record.data.longitude);
record.set('reiniciar', record.data.reiniciar);
record.set('configuracaoCombo', record.data.configuracao.id);
record.set('ativar', record.data.ativar);
record.set('tipoColetor', record.data.tipoColetor);
form.loadRecord(record);
Ext.create('Ext.window.Window', {
title : 'Cadastro',
layout : 'fit',
modal : true,
width : 500,
height : 350,
items : [ form ]
}).show();
And 'PanelNovaEstacao' code is:
Ext.define('PanelNovaEstacao', {
extend : 'Ext.form.Panel',
title : 'Painel',
initComponent : function() {
var combo = Ext.create('ComboBoxConfiguration', {
name : 'configuracao'
});
Ext.apply(this, {
bodyPadding : '10 0 0 10',
items : [ {
xtype : 'hiddenfield',
name : 'id'
}, {
xtype : 'hiddenfield',
name : 'numeroSerieAntigo'
}, {
xtype : 'numberfield',
fieldLabel : 'Número de série',
name : 'numeroSerie',
minValue : 0,
allowBlank : false
}, combo
{
xtype: 'numberfield',
fieldLabel: 'Latitude',
name: 'latitude'
}, {
xtype: 'numberfield',
fieldLabel: 'Longitude',
name: 'longitude'
},{
xtype: 'radiogroup',
fieldLabel : 'Estado',
items : [ {
boxLabel : 'Ativo',
inputValue : true,
checked: true,
name : 'ativar'
}, {
boxLabel : 'Inativo',
inputValue : false,
name : 'ativar'
} ]
}, {
xtype : 'checkbox',
fieldLabel : 'Modo ignorar',
name : 'modoIgnorar'
}, {
xtype : 'checkbox',
fieldLabel : 'Reiniciar',
name : 'reiniciar'
}, {
xtype : 'button',
text : 'Salvar',
textAlign : 'center',
action : 'salvar'
} ]
});
this.callParent(arguments);
}
});
ComBoxConfiguration code:
Ext.define('ComboBoxConfiguration', {
extend : 'Ext.form.ComboBox',
store : 'ConfiguracaoStore',
fieldLabel : 'Configurações',
displayField : 'id'
});
Anyone know what might be happening ??
Thanks!
This line is likely causing the issue: record.set('configuracaoCombo', record.data.configuracao.id);
The data that is coming back from the proxy does not have a configuracao property, so accessing it evaluates to undefined, at which point trying to access the sub-property id will lead to the error you are seeing.
Take a look at the data in the EstacaoStore and what's being returned by the store's proxy (or however you load it). You'll likely find a problem there.
When I click in line and run the code:
var record = Ext.getStore('EstacaoStore').getAt(rowIndex);
console.log(record);
The object that return is: (configuracao is synonymous to configuracaoEstacao)