I have a Window class like this:
Ext.define('EMS.tf.alerts.alerts.view.AlertWindow', {
extend: 'Ext.window.Window',
alias: 'widget.ems-alerts-window',
height: 220,
width: 600,
alertTpl: undefined,
autoScroll: true,
selectedRecord: undefined,
title: undefined,
atext: undefined,
// #private
initComponent: function() {
var me = this;
Ext.apply(me, {
tpl: me.alertTpl,
listeners: {
show: function() {
Ext.create('Ext.Container', {
renderTo: 'alertContainer',
itemId: 'buttonContainer',
items : [{
xtype: 'button',
cls: 'ackbtn',
text : 'Acknowledge',
name: 'ackButton',
itemId: 'renderbutton'
},{
xtype: 'button',
cls: 'attchmntbtn',
text : 'Attachment',
name: 'attButton',
itemId: 'renderattachmntbutton'
}]
});
}
},
title: me.title
});
me.callParent();
}
});
I want to get reference to button "Attachment" using itemId "renderattachmntbutton". How to do this?
I tried windowobject.down('#renderattachmntbutton') but still it didn't work. I can get reference to the items placed before init function but not like this. Any idea on what needs to be done to get reference to this button?
That button is not an item (a child) of the window but of the button container. If you want to find it with down then you need to grab a reference to the container and call down on that.
Instead of
windowobject.down('#renderattachmntbutton') // WRONG
call
buttoncontainer.down('#renderattachmntbutton') // Correct
Try this
Ext.ComponentQuery.query('[itemId=renderattachmntbutton]')[0]
The itemId can be used with the getComponent() call on parent items, like container and panels. If you change your itemId on your container to just an id property. You can then get to your child items like so:
Ext.getCmp('buttonContainer').getComponent('renderattachmntbutton');
This is just one possible way, there are others!
You could try
windowobject.down('[itemId=renderattachmntbutton]') ;
Related
Suppose we have defined a component (e.g. FieldSet) that we'd like to reuse in the single app (e.g. display/use it in 2 different modal windows.) This FieldSet has a reference, which we use to access it. The goal is to have these 2 windows contain independent fieldsets, so we can control and collect the inputs from each one separately.
Here's the sample fiddle that demonstrates the problem. As soon as any function triggers any lookupReference(...) call, Sencha issues the warning for "Duplicate reference" for the fieldset. It correctly creates two distinct fieldset components (by assigning different ids) on each window, but fails to properly assign/locate the references. As a result, any actions on one of these windows' fieldsets would be performed on the "unknown" one (probably on the first created one), messing up the UI behavior.
I see how it is a problem for Sencha to understand which component to use when operating on the reference, but there should be a way to reuse the same component multiple times without confusing the instances. Any help is greatly appreciated.
According to the docs on ViewController:
A view controller is a controller that can be attached to a specific view instance so it can manage the view and its child components. Each instance of the view will have a new view controller, so the instances are isolated.
This means that your use of singleton on your ViewController isn't correct, as it must be tied to a single view instance.
To fix this, I'd recommend making some modifications to your Fiddle, mainly removing the singleton: true from your VC class, accessing the views through lookup, and getting their VC's through getController to access your func method.
Ext.application({
name: 'Fiddle',
launch: function () {
/**
* #thread https://stackoverflow.com/questions/67462770
*/
Ext.define('fsContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.fsContainerHandler',
// TOOK OUT singleton: true
func: function () {
var x = this.lookupReference('fsRef');
alert(x);
}
});
Ext.define('fsContainer', {
extend: 'Ext.container.Container',
xtype: 'xFSContainer',
controller: 'fsContainerHandler',
items: [{
xtype: 'fieldset',
title: 'myFieldset',
reference: 'fsRef'
}]
});
Ext.define('mainContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.mainContainerHandler',
singleton: true,
onButton1Click: function () {
var win = this.getView().window1;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
},
onButton2Click: function () {
var win = this.getView().window2;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
}
});
Ext.define('mainContainer', {
extend: 'Ext.container.Container',
width: 400,
controller: 'mainContainerHandler',
window1: null,
window2: null,
initComponent: function () {
this.window1 = Ext.create('window1');
this.window2 = Ext.create('window2');
this.callParent(arguments);
},
items: [{
xtype: 'button',
text: 'Window 1',
reference: 'btn1',
handler: mainContainerHandler.onButton1Click,
scope: mainContainerHandler
}, {
xtype: 'button',
text: 'Window 2',
reference: 'btn2',
handler: mainContainerHandler.onButton2Click,
scope: mainContainerHandler
}]
});
Ext.define('window1', {
extend: 'Ext.window.Window',
title: 'Window1',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.define('window2', {
extend: 'Ext.window.Window',
title: 'Window2',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.create('mainContainer', {
renderTo: document.body
});
}
});
I want to remove the active tab from sencha ext.
Assume that am into controller file of the view.
Note: I have used remove() as well as destroy().
destroy() function works fine but tab header is not getting removed.
coseResultTab() {
this.getView().destroy();
}
Before Clicking on Cancel button:
After Clicking on Cancel button
You should destroy the active tab in your tabpanel, eg:
Controller
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
destroyTab: function() {
this.getView().down('tabpanel').getActiveTab().destroy();
}
});
View
Ext.create('Ext.Panel', {
width: 400,
height: 400,
renderTo: document.body,
title: 'Panel',
id: 'myPanel',
controller: 'myview',
items: [{
xtype: 'tabpanel',
items: [{
title: 'Foo',
items: [{
xtype: 'button',
text: 'Destroy!',
handler(btn) {
Ext.getCmp('myPanel').getController().destroyTab();
}
}]
}, {
title: 'Bar',
items: [{
xtype: 'button',
text: 'Destroy!',
handler(btn) {
Ext.getCmp('myPanel').getController().destroyTab();
}
}]
}]
}]
});
Fiddle
I enhanced the answer from Matheus to meet the requirement a bit more:
not destroying the entire tab, but only the content
setting the button handler without the use of getController (please try not to use this, as it is considered bad practice by Sencha)
removed the outer panel which only added a title
Fiddle
You can also remove it using the tab bar using closeTab() which pretty much just runs a tabs.remove(tabRefOrObj);
https://docs.sencha.com/extjs/6.5.3/modern/Ext.tab.Bar.html#method-closeTab
So I have a following View that extends the Ext.panel.Panel
Ext.define('SomeView', {
extend: 'Ext.panel.Panel',
alias: 'someview',
title: 'Some View',
closable: true,
initComponent: function () {
this.itemId = 'someView';
this.callParent(arguments);
},
layout: {
type: 'vbox',
align: 'stretch'
},
items: [
{
xtype: 'container',
layout: 'hbox',
items: [
{
xtype: 'container',
itemId: 'someContainer',
tpl: '<h2>{someProperty}</h2>',
flex: 1
},
// other code omitted for brevity
});
I initialize the view like this.
var panel = Ext.create('someview', {
someProperty: 'Some Value'
});
After the view is shown the parameter that I pass to someProperty is shown as well. But the thing is, I want to change someProperty after the view is shown. Can I do that? and if yes, how ? I mean I can change it like this
panel.someProperty = 'Some New Value';
but the view does not get effected itself.
You will want to add a member function to your panel class to do the actual work of updating what is shown on the screen:
setSomeProperty: function(prop) {
this.down('#someContainer').update({someProperty: prop});
}
var confirmWindow = Ext.create('Ext.window.Window', {
title: 'Selected Item List',
autoHeight: true,
width: 500,
layout: 'fit',
modal: true,
items: [{
xtype: 'panel',
bodyPadding : 5,
items: [{
xtype: 'textfield',
id : 'freightFee',
fieldLabel: 'Freight Fee ',
name : 'freight' // I need this value, when I click the button
}]
}],
bbar: ['->', {
xtype: 'buttongroup',
items: [{
text: "test",
handler: function () {
// I want to get the textfield value (freightFee)
var freightFee = Ext.getCmp('freightFee').getValue(); // error :Ext.getCmp('freightFee') is undefined
}
}]
}
});
I have a window like above, and I want to get the text inputbox value when I click the button.
I tried,
var freightFee = Ext.getCmp('freightFee').getValue();
but error message say,
Ext.getCmp('freightFee') is undefined
anybody know this?
thank you!
Don't use getCmp ever! It's very expensive and unnecessary. Check out up/down methods to locate elements parents/childrens http://docs.sencha.com/ext-js/4-0/#!/api/Ext.Element-method-down
In your case something like that should work:
handler: function(button) {
var tf = button.up('window').down('#freightFee');
}
I am new to extjs in general, specially to 4 version:
I have created a class:
Ext.define('MyPanel', {
extend:'Ext.panel.Panel',
views: ["MyPanel"],
config: {
width: 200,
height: 300,
title: "HELLO"
},
constructor:function(config) {
this.initConfig(config);
return this;
},
alias: 'widget.MyPanel'
});
Next, I want to call this class in form of XTYPE in a tabPanel items:[]:
I did like this:
items: [{
title: 'Kontakt',
id: 'kontaktTab',
closable:true,
closeAction: 'hide',
layout: 'fit',
items:[{
xtype: "MyPanel"
}]
No luck yet, all I get is :
Cannot create an instance of unrecognized alias: widget.MyPanel"
You must think, what a noob....
;-)
Someone please help!!!
When you are defining your view (MyPanel), why have you set views property?
Ext.define('MyPanel', {
extend:'Ext.panel.Panel',
alias: 'widget.MyPanel'
views: ["MyPanel"], <------ Why do you need this???
config: {
width: 200,
height: 300,
title: "HELLO"
},
constructor:function(config) {
this.initConfig(config);
return this;
}
});
And when you are making use of the new view, you need to specify it in requires. Here is an example:
Ext.define('MyApp.view.Viewport',{
extend: 'Ext.container.Viewport',
layout: 'border',
requires: [
'MyPanel' <--- This will ensure that this view file needs to be loaded
],
.
.
.
items: [{
title: 'Kontakt',
id: 'kontaktTab',
closable:true,
closeAction: 'hide',
layout: 'fit',
items:[{
xtype: "MyPanel"
}]
Hrm, have you tried lowercasing your alias. I thought aliases were always stored and fetched lowercase, but not sure about it
Ah, hehe, I completely overlooked something:
with an 'alias' you are creating a new class reference in the ExtJS class list. So by adding the alias like you did above, you can instantiate it by calling
var newMyPanel = Ext.create('widget.MyPanel');
However, if you are adding an instance with a xtype specifier you have to omit the widget part and just do:
var myContainer = Ext.create('Ext.panel.Panel',{
items: [{
xtype: 'MyPanel'
}]
});
With the above code, Ext will look for class with the alias 'widget.MyPanel'.
Apart from this, I think your constructor is a bit funky looking. The constructor should not return itself (like you would do in a Perl constructor for instance)
This is enough:
constructor: function() {
this.callParent(arguments);
// Your own code here
}
Cheers and let me know if it helps
Rob
all u have to do is declare it like that :
var panel1 = Ext.create('Ext.app.myPanel',{title : 'panel 1',height:350});//title and hight are optionals if u have already defined them
and then use it like this:
...
items : [panel1 ]
...
and you may need to require it :
Ext.require([
, 'Ext.app.myPanel'
]);
and put the mypanel.js an app folder
hope this helps