ExtJS get value from sibling element - javascript

I am using extjs 3.4
I have panels added dynamically to parent panel.
I would like to catch value of iterator (i) on click.
Value of this iterator is saved in hidden element:
xtype: 'hidden',
cls: 'hidden-ID',
value: i
so basically on click I should be able to find this sibling (perhaps by class name or type?).
But I really don't know how - I've alredy tried to find parent, but from parent I wasn't able to find children.
Example is here
Code:
Ext.onReady(function () {
var eleCatDisplay2 = new Ext.Panel({
renderTo: Ext.getBody(),
height: 350
});
for (i = 0; i < 10; i++) {
eleCatDisplay2.add(new Ext.Panel({
layout: 'hbox',
border: false,
style: {
marginTop: '10px'
},
items: [{
xtype: 'displayfield',
flex: 1,
value: 'rowNum__' + i.toString()
}, {
xtype: 'hidden',
cls: 'hidden-ID',
value: i
}, {
xtype: 'panel',
flex: 0.3,
border: false,
html: '<div>click to send</div>',
listeners: {
'render': function (panel) {
panel.body.on('click', function () {
//here I would like to catch value of i
alert('test');
});
}
}
}]
}));
}
eleCatDisplay2.doLayout();
});

You can also store value in some custom property of the panel:
Ext.onReady(function () {
var eleCatDisplay2 = new Ext.Panel({
renderTo: Ext.getBody(),
height: 350
});
for (i = 0; i < 10; i++) {
eleCatDisplay2.add(new Ext.Panel({
layout: 'hbox',
border: false,
style: {
marginTop: '10px'
},
items: [{
xtype: 'displayfield',
flex: 1,
value: 'rowNum__' + i
}, {
xtype: 'hidden',
cls: 'hidden-ID',
value: i
}, {
xtype: 'panel',
flex: 0.3,
border: false,
html: '<div>click to send</div>',
somePropertyName: i,
listeners: {
'render': function (panel) {
panel.body.on('click', function () {
console.log(panel.somePropertyName);
});
}
}
}]
}));
}
eleCatDisplay2.doLayout();
});

Solution (on display field I've add cls: 'display-cat-name'):
var cNM = Ext.getCmp(this.up('.hbox-parent').select('.display-cat-name').elements[0].id).value;
var catId = this.up('.hbox-parent').select('.hidden-ID').elements[0].value;

Related

ExtJS - Add listener to title

I have a small panel with title and body.
var dashboardPanel1 = Ext.create('Ext.Panel', {
renderTo: Ext.getBody(),
collapsible: true,
margin: '0 0 50 0',
layout: {
type: 'table',
// The total column count must be specified here
columns: 3
},
defaults: {
// applied to each contained panel
bodyStyle: 'padding:20px',
border: 0
},
title: 'Key settings',
items: [{
html: '<img src="https://i.imgur.com/n7gOYrE.png" style="width: 20px; height: 20px">',
}, {
html: '|Your key is active|',
}, {
html: '|Expiring date: 27.04.2018|',
}],
});
How can I attach a listener to a title?
So, when I click on Key settings, it will be some action performed.
You can also trigger click event using [Element.on()](https://docs.sencha.com/extjs/6.2.0/classic/Ext.dom.Element.html#method-on).
The on method is shorthand for addListener. Appends an event handler to this object.
For example:
el.on("click", function(){
//do something...
//
}, this);
I this FIDDLE, I have created a demo using your code and make some modification. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create('Ext.Panel', {
renderTo: Ext.getBody(),
collapsible: true,
margin: '0 0 50 0',
layout: {
type: 'table',
// The total column count must be specified here
columns: 3
},
defaults: {
// applied to each contained panel
bodyStyle: 'padding:20px',
border: 0
},
title: '<span class="mytitle">Key settings</span>',
items: [{
html: '<img src="https://i.imgur.com/n7gOYrE.png" style="width: 20px; height: 20px">',
}, {
html: '|Your key is active|',
}, {
html: '|Expiring date: 27.04.2018|',
}],
listeners: {
afterrender: function (panel) {
Ext.get(panel.el.query('span.mytitle')[0]).on('click', function (e) {
alert(e.target.innerText)
}, panel);
}
}
});
}
});
Solution:
Replace
title: 'Key settings',
with custom header:
header: {
title: 'Custom header title',
listeners: {
click: function(h, e) {
var tm = new Ext.util.TextMetrics(h);
if (e.getX() < tm.getWidth('Custom header title')) {
Ext.Msg.alert('Information', 'Do some action!');
}
}
}
}
Working example:
var dashboardPanel1 = Ext.create('Ext.Panel', {
renderTo: Ext.getBody(),
collapsible: true,
margin: '0 0 50 0',
layout:
{
type: 'table',
// The total column count must be specified here
columns: 3
},
defaults:
{
// applied to each contained panel
bodyStyle: 'padding:20px',
border: 0
},
//title: 'Key settings',
header: {
title: 'Custom header title',
listeners: {
click: function(h, e) {
var tm = new Ext.util.TextMetrics(h);
if (e.getX() < tm.getWidth('Custom header title')) {
Ext.Msg.alert('Information', 'Do some action!');
}
}
}
},
items: [
{
html: '<img src="https://i.imgur.com/n7gOYrE.png" style="width: 20px; height: 20px">',
},
{
html: '|Your key is active|',
},
{
html: '|Expiring date: 27.04.2018|',
}],
});
Notes:
The example is tested with ExtJS 4.2. Title width is calculated with Ext.util.TextMetrics.

hbox nested in vbox not shows ExtJS

I'm using ExtJS 3.3.2 and I have a panel with some panels nested in vbox and hbox. The problem is easy: My data from items inside hbox are not showing, I tried modifying weight and height but it never shows up. Looking at the code (F12), I see the data is created, but the panels have a very tiny size.
var i = 0;
jsonResp.forEach(function(currentItem) {
i++;
var panel = new Ext.Panel({
id: 'superpanel'+i,
layout: 'vbox',
height: 50,
frame: true,
collapsible: true,
items: [{
xtype: 'panel',
id: 'jsonObject'+i,
layout: 'hbox',
frame: true,
align: 'stretch',
items:[{
id: 'codigo'+i,
xtype: 'panel',
html: currentItem.codigo
},{
id:'nombre'+i,
xtype: 'panel',
html: currentItem.nombre
},{
xtype: 'panel',
html: currentItem.estado.toString()
}]
},{
xtype: 'panel',
id: 'aviso'+i,
html: "Error"
}]
})
Ext.getCmp("contenedor").add(panel);
});
Ext.getCmp("contenedor").doLayout();
I want to create this:
What is wrong? I tried it with width/height and flex but it doesn't work.
width: "100%" and flex can be used to resolve this issue.
Here is how I resolved it.
Ext.onReady(function () {
var viewport = new Ext.Viewport({
items: [{
xtype: "panel",
title: "Test one",
width: 500,
height: 800,
id: "contenedor",
autoScroll: true
}]
});
//delay for adding dynamic content
setTimeout(function () {
var parentPanel = Ext.getCmp("contenedor");
for (var i = 0; i < 10; i++) {
var panel = new Ext.Panel({
id: 'superpanel' + i,
layout: 'vbox',
height: 100,
frame: true,
collapsible: true,
items: [{
xtype: 'panel',
id: 'jsonObject' + i,
layout: 'hbox',
frame: true,
align: 'stretch',
flex: 3,
width: '100%',
items: [{
id: 'codigo' + i,
flex: 1,
xtype: 'panel',
html: 'Demo html 1'
}, {
id: 'nombre' + i,
xtype: 'panel',
flex: 1,
html: 'Demo html 2'
}, {
xtype: 'panel',
flex: 1,
html: 'Demo html 3'
}]
}, {
xtype: 'panel',
id: 'aviso' + i,
html: "Error",
width: "100%"
}]
});
parentPanel.add(panel);
}
parentPanel.doLayout();
}, 2000);
});
Fiddle is created with ExtJS 3.4.1.1. Sadly there is no 3.2.2 version available on sencha fiddle. But this should work with 3.2.2.
Example Fiddle (with ExtJS 3.4.1.1): https://fiddle.sencha.com/#view/editor&fiddle/28ql

Explicitly Calling initComponent of extJS Class

There is probably a better way to do this and please provide guidance for me as to how to achieve it if possible but I was wondering if there was a way, on a Tab Click, to explicitly call that containers initComponent function? That is, the container that lives inside of that Tab Panel.
I currently have an initComponent in said panel that loads a Grid Panel with several Property Grids. The store changes when the user clicks a button on another Tab to update said panels store,so I'd like to call the initComponent again to refresh the Property Grids with the newly updated store.
Here is a code snippet of the other Tabs button that programatically switches tabs:
buttons: [{
text: 'Configure',
handler: function() {
// Get name of role
var roleList = Ext.getCmp('chefRoleRunListInformationGrid');
if (roleList.getSelectionModel().hasSelection()) {
var roleName = roleList.getSelectionModel().getSelection();
roleName = roleName[0]['raw'][0];
// Get Role Setup form
Ext.getCmp('chefRoleSetupFormPanel').getForm().setValues({
roleName: roleName
});
}
var chefTabPanel = Ext.getCmp('chefTabPanel');
chefTabPanel.setActiveTab(1);
var chefRoleRunListInformationStore = Ext.getStore('chefRoleRunListInformationStore');
var chefRequiredCookbooksGrid = Ext.getCmp('chefRequiredCookbooksGrid');
var roleRunListInfoGrid = Ext.getCmp('chefRoleRunListInformationGrid');
roleRunListInfoGridColumns = roleRunListInfoGrid.columns;
chefRequiredCookbooksGrid.reconfigure(chefRoleRunListInformationStore);
}
}]
After the chefTabPanel.setActiveTab(1), I'd like to call the initComponent function if possible to reload that tab with the new store.
Here is my code for the container that lives in said Tab:
Ext.define('chefCreateAndPinRolesLayoutContainer', {
extend: 'Ext.panel.Panel',
layout: 'fit',
items: [{
xtype: 'container',
layout: {
type: 'hbox',
align: 'stretch'
},
items: [{
xtype: 'container',
flex: 1,
layout: {
type: 'vbox',
align: 'stretch'
},
border: 1,
items: [{
xtype: 'container',
flex: 1,
layout: 'fit',
items: [
Ext.create('chefRequiredCookbooksGridPanel')
]
}, {
xtype: 'container',
flex: 1,
layout: 'fit',
items: [
Ext.create('chefRoleSetupFormPanel')
]
}]
}, {
xtype: 'container',
flex: 1,
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'container',
flex: 1,
layout: 'fit',
items: [
Ext.create('chefOptionalCookbooksGridPanel')
]
}, {
xtype: 'container',
flex: 1,
layout: 'fit',
items: [
Ext.create('chefAttributeGridContainer')
]
}]
}]
}],
initComponent: function() {
var me = this;
var chefRCS = Ext.create('chefRequiredCookbooksStore');
var requiredCookbooksStore = Ext.getStore('chefRequiredCookbooksStore');
var chefAttributesGridContainer = Ext.getCmp('chefAttributesGridContainer');
requiredCookbooksStore.load({
scope: this,
callback: function(records, operation, success) {
requiredCookbooksStore.data.each(function(item, index, totalItems) {
var cookbookName = item['raw'][0];
var cookbookVersion = item['raw'][1];
var attributesGrid = Ext.create('Ext.grid.property.Grid', {
width: 450,
id: cookbookName,
source: {
"Cookbook": cookbookName,
"Version": cookbookVersion
},
viewConfig: {
scroll: 'false',
style: {
overflow: 'auto',
overflowX: 'hidden'
}
}
});
chefAttributesGridContainer.add(attributesGrid);
chefAttributesGridContainer.doLayout();
});
}
});
me.callParent(arguments);
}
});
Any ideas?
Your initComponent code isn't doing anything that needs to be in there. So why not just extract it into an initStore method and then just call it as you would any other method from the initComponent and when you change tabs.
Another suggestion unrelated to the question: avoid using Ext.getCmp it will lead to very tight coupling and bad architecture.

Error when binding Ext.grid.Panel to Ext.Panel

I am new to extJS. I want to bind a Ext.grid.Panel to Ext.Panel (yes, I really want that!). This is what I've tried -
Var Panel = new Ext.Panel({
title: 'Test',
id: 'Panel',
items: [Grid]
});
Var Grid =
{
xtype: 'grid',
columns: [
{ header: 'Resort', dataIndex: 'resort' },
{ header: 'Arrival', dataIndex: 'arrival' },
{ header: 'Accompanying Guest(s)', dataIndex: 'guest', flex: 1 }
]
};
Now I want to open Panel in a Ext.Window
var win2 = new Ext.Window({
layout: 'fit',
width: 900,
height: 600,
closeAction: 'hide',
plain: true,
items: [Panel]
});
b.getEl().on('click', function () {
win2.show();
});
This ends in an error - Uncaught TypeError: Cannot read property 'events' of undefined
But when I change the Panel as below, its working fine-
var Panel = new Ext.Panel({
title: 'Test',
id: 'Panel',
items:
[
{
xtype: 'grid',
columns: [
{ header: 'Resort', dataIndex: 'resort' },
{ header: 'Arrival', dataIndex: 'arrival' },
{ header: 'Accompanying Guest(s)', dataIndex: 'guest', flex: 1 }
]
}
]
});
What went wrong in my previous code?
Of course it doesn't work. You're essentially doing this:
var y = x + 1;
console.log(y); // Why isn't y 2?
var x = 1;
Either you have to define your grid before you use it in items as below :
var Grid = {
xtype: 'grid',
columns: [{
header: 'Resort',
dataIndex: 'resort'
}, {
header: 'Arrival',
dataIndex: 'arrival'
}, {
header: 'Accompanying Guest(s)',
dataIndex: 'guest',
flex: 1
}]
};
var Panel = new Ext.Panel({
// title: 'Test',
id: 'Panel',
items: [Grid]
});
Or else one more option is (When you have grid in different js file you can go with listeners as done below ) :
var Panel = new Ext.Panel({
// title: 'Test',
id: 'Panel',
items: [],
listeners: {
render: function(pnl) {
pnl.add(Grid);
}
}
});
var Grid = {
xtype: 'grid',
columns: [{
header: 'Resort',
dataIndex: 'resort'
}, {
header: 'Arrival',
dataIndex: 'arrival'
}, {
header: 'Accompanying Guest(s)',
dataIndex: 'guest',
flex: 1
}]
};
var win2 = new Ext.Window({
layout: 'fit',
width: 500,
height: 400,
closeAction: 'hide',
plain: true,
items: [Panel]
});
b.getEl().on('click', function() {
win2.show();
Below is the fiddle to represnt same
Demo

ExtJS 4: How do I Re-render Ext.Component iframe?

How can I re-render this Ext.Component when a combo box option is selected?
var searchForm = Ext.create('Ext.form.Panel', {
width: 320,
style: 'margin: 20px',
renderTo: 'SearchPanel',
style: {
position: 'fixed',
top: '0px',
left: '865px'
},
items: [{
xtype: 'combo',
width: 300,
labelAlign: 'right',
fieldLabel: 'Subject Area',
store: subjectAreaStore,
valueField: 'id',
displayField: 'value',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
selectOnFocus: true,
value: 'Account',
listeners: {
select: function (combo) {
cmp.autoEl.src = '/' + combo.getValue() + '/2nd Iteration.htm';
alert(cmp.autoEl.src);
cmp.render(); // this does not work!
}
} // listeners
}]
});
// create the cmp
var cmp = Ext.create('Ext.Component', {
title: 'Data Models',
style: {
width: '100%',
height: '750px'
},
autoEl : {
tag : 'iframe',
src : '/Account/2nd Iteration.htm'
},
renderTo: 'models'
});
Update: 10/23/2012:
This isn't working yet:
listeners: {
select: function (combo) {
cmp.autoEl.src = '/' + combo.getValue() + '/2nd Iteration.htm';
var the_iframe = cmp.getEl().dom;
the_iframe.contentWindow.location.reload();
}
} // listeners
I would suggest a different approach to creating the iframe. Just use the html property of a component and write the html yourself instead of using the autoel feature (never done this with a component, only a container but it should work the same)...
var cmp = Ext.create('Ext.Component', {
title: 'Data Models',
style: {
width: '100%',
height: '750px'
},
renderTo: 'models',
html: '<iframe src="/Account/2nd Iteration.htm"></iframe>'
});
Then do this in the listener to update it...
listeners: {
select: function (combo) {
cmp.update('<iframe src="/' + combo.getValue() + '/2nd Iteration.htm"></iframe>');
}
}
The render() method only deals with HTML that was created (rendered) by ExtJS. You created that iframe yourself, so you have to control it yourself. You should be able to get the DOM element from the Component like this:
var the_iframe = cmp.getEl().dom;
the_iframe.contentWindow.location.reload();

Categories