I've noticed that tabpanel's beforeremove and panel's beforeclose and close are not firing. On the other hand destroy event is working fine. Are there any workarounds or different events with the same results?
I've reproduced my observation at the example below.
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.TabPanel', {
fullscreen: true,
tabBarPosition: 'bottom',
items: [
{
xtype: 'panel',
title: 'Home',
iconCls: 'home',
html: 'Home Screen',
closable: true,
listeners: {
beforeclose: function () {
console.log('beforeclose');
},
close: function () {
console.log('close');
},
destroy: function () {
console.log('destroy');
}
}
},
{
title: 'Contact',
iconCls: 'user',
html: 'Contact Screen'
}
],
listeners: {
beforeremove: function () {
console.log('beforeremove');
}
}
});
}
});
Just add the example to sencha fiddle in Modern toolkit and open your browser's developer tools.
Also, beforeclose and close are firing fine if the panel is not inside a tabpanel.
Ext.create({
xtype: 'panel',
title: 'Panel Title',
iconCls: 'x-fa fa-html5',
height: 400,
width: 400,
bodyPadding: 12,
html: 'Sample HTML text',
renderTo: Ext.getBody(),
listeners: {
beforeclose: function () {
console.log('beforeclose');
},
close: function () {
console.log('close');
}
}
}).close();
UPDATES
-- It's a framework bug. So probably i'll have to wait for an update.
-- I accepted Marco's answer because it solves my issue. But it's a framework bug that it should be fixed in the next update.
Demo here: https://fiddle.sencha.com/#view/editor&fiddle/29dj
TL;DR listen to "deactivate" and "removed" events.
The user click happens on tab's bar (Ext.tab.Bar) and not on your panel, and the bar is part of Ext.tab.Panel (which extends Ext.Container).
Therefore the method called to close your tab is "onItemRemove" of Ext.tab.Panel, and not "close" of Ext.Panel.
This is the reason why your listeners don't work.
With the demo fiddle you can see all the events being fired by your Ext.Panel and use those events to do what you need.
EDIT
To show a confirmation message before closing here's the fiddle: https://fiddle.sencha.com/#view/editor&fiddle/29hl
Related
Here's a description of my Fiddle
I have defined a Window and a Form Panel
I have created instances of the Window and the Form panel defined above
Added the Form panel to the Window
Called the .show() on the Window to show the window (which
now also includes the form)
The form Panel declaration includes the buttons. But now the buttons do not show up.
Ext.application({
name: 'My Window',
launch: function () {
Ext.define('MyWindow', {
extend: 'Ext.window.Window',
title: 'My Window'//,
// renderTo: Ext.getBody()
});
Ext.define('MyForm', {
extend: 'Ext.form.Panel',
bodyPadding: 5,
width: 350,
// The form will submit an AJAX request to this URL when submitted
url: '',
// Fields will be arranged vertically, stretched to full width
layout: 'anchor',
defaults: {
anchor: '100%'
},
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
name: 'first',
allowBlank: false
}, {
fieldLabel: 'Last Name',
name: 'last',
allowBlank: false
}],
// Reset and Submit buttons
buttons: [{
text: 'Reset',
handler: function () {
this.up('form').getForm().reset();
}
}, {
text: 'Submit',
formBind: true, //only enabled once the form is valid
disabled: true,
handler: function () {
var form = this.up('form').getForm();
if (form.isValid()) {
form.submit({
success: function (form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function (form, action) {
Ext.Msg.alert('Failed', action.result.msg);
}
});
}
}
}]
});
var myWindow = new MyWindow();
var myForm = new MyForm();
myWindow.items.add(myForm);
myWindow.show();
// var myForm = new MyForm();
}
});
Here's the fiddle
This must be related to some documented behavior of the Form or the Window. What could that be?
Also, architecturally, I would like to define these components separately and use them as needed. So is there a design pattern that is better than this?
Any component that is going to contain other components will generally need to have a layout specified. Add layout: 'fit' to your MyWindow config and it should work.
Google ExtJS MVC for guidelines on the recommended way to design ExtJS applications. I also find that the ExtJS 6 examples page can be quite useful. The KitchenSink one is nice because it contains a ton of different examples of small applications built using the MVC design pattern. (Pick an example from that link and then expand the Details pane on the right.)
I want to add a button into a panel to the exact position where I clicked.
SO I have tried like as follows, this the structure of my Ext.widget element
Ext.widget({
xtype : 'mz-form-widget',
itemId: 'shopableImage',
anchor: "100%",
defaults: {
xtype: 'textfield',
listeners: {
controller: '',
change: function (cmp) {
controller = cmp;
cmp.up('#shopableImage').updatePreview();
}
}
},
items: [
{
xtype: "tacofilefield",
itemId: "imageUploadButton",
text: "Upload images"
},
{
xtype: 'panel',
width: 350,
height: 350,
itemId:'container',
id:'container',
bodyStyle:{"background":"url('http://www.easyvectors.com/assets/images/vectors/vmvectors/jeans-girl-vector-27.jpg')","border":"1px solid #eee"},
listeners: {
click: {
element: 'el', //bind to the underlying el property on the panel
fn: function(a,b,c,d){
console.log(a.browserEvent.clientX - b.offsetLeft);
console.log(a.browserEvent.clientY - b.offsetTop);
console.log(c);
this.down('#container').addItem({"xtype":"button","text":"+"});
}
},
dblclick: {
element: 'body', //bind to the underlying body property on the panel
fn: function(){ console.log('dblclick body'); }
}
}
}
The following line throwing me error.
this.down('#container').addItem({"xtype":"button","text":"+"});
UPDATE
this.down('#container')
is returning null.
Please give me your suggestions regarding this?
There are two problems here, one is causing the error and another is a potential time bomb:
addItem does not exist, the correct method name is add
You use id's on components and that is a very bad practice, however, it does not the immediate cause of the error
I have build my project through command line in sencha but after the build the listener event for a particular controller didnt work. The alert that I included in the listener didnt get called. My main issue was that the localStorage.providerName after the label "Tell your friends about" sometimes prints undefined so tried to implement in listener, but the function in listener is not getting called. Any suggestions? Below is the part of code where the event listener doesnt get called.
Ext.define('Myl.view.ShareView', {
extend: Ext.Panel,
id:'shareView',
xtype :'shareView',
alias: 'widget.shareView',
config: {
cls:'mainBackground',
items: [
{
xtype:'toptoolbar',
docked:'top'
},
{
xtype: 'label',
id: 'tellAFriendTopLabel',
// html: 'Tell your friends about '+localStorage.providerName,
padding: 5
},
{
xtype: 'button',
margin: 20,
text: 'Facebook',
ui:'facebook_button',
iconCls:'facebookIconCls',
action : 'facebookButtonPressed'
},
{
xtype: 'button',
margin: 20,
text: 'Twitter',
iconCls:'twitterIconCls',
ui:'twitter_button',
action : 'twitterButtonPressed'
},
{
xtype: 'button',
margin: 20,
text: 'Email',
ui:'email_button',
iconCls:'emailIconCls',
action : 'emailButtonPressed'
},
{
xtype :'footerPanel',
docked:'bottom'
}
]
},
listeners: {
painted: function (element, options) {
alert('test1');
Ext.getCmp('tellAFriendTopLabel').setHtml('Tell your friends about '+localStorage.providerName+'.');
this.fireEvent('initiateShareView');
}
}
});
You have to put your listeners inside config object.
However, I wouldn't recommend this approach because if somebody wants to listen painted event, the new handler will override yours. I'd suggest to do it using 'on' method in 'initialize'.
Take a look at the initialize method of this component: http://docs.sencha.com/touch/2.3.1/source/List.html#Ext-dataview-List
I need to be able to tap/click on the entire toolbar at the bottom of my page and either go to another screen or have a popup.
Why you ask? Because I have a logo for now as my title. Plus this was the easiest way with the least code I could figure out to get a logo at the bottom, that was docked, and did not change as the pages changed. Essentially my toolbar is a link or popup to an "about" page.
Here is what I have that seems to work with buttons.
{
xtype : 'toolbar',
docked: 'bottom',
title: '<img src="logo.png" id="logo" alt=""/>',
handler: function() {
Ext.Msg.alert('About', 'You clicked about');
}
}
I also tried this with no luck.
{
xtype : 'toolbar',
docked: 'bottom',
title: '<img src="logo.png"/>',
listeners: {
tap: function() {
alert("You tapped me");
}
}
}
Thanks,
Donnie
You can just simply do like this:
{
xtype : 'toolbar',
docked: 'bottom',
title: '<img src="logo.png"/>',
listeners: {
initialize: function() {
this.element.on({
tap: function() {
alert("You tapped me");
}
})
}
}
}
Hope it helps :)
I have an ASP.NET MVC application. In the application, I have a page with a button on it. When I click on the button a partial view is rendered in a window (see below). Inside the view I have a combo box and I need to load the combo box after the view is rendered. I tried to call the js right after win.show() but that doesn't work because the textbox used to render combo is inside the partial view. When should I call the js? Any help regarding this will be highly appreciated. Thanks!
var win;
if (!win) {
win = new Ext.Window({
layout: 'fit',
width: 750,
height: 630,
closeAction: 'hide',
plain: true,
autoLoad: {
url: '../SearchJob/SearchPanel'
},
buttons: [{
text: 'Submit',
handler: function () { }
}, {
text: 'Close Me',
handler: function () {
win.hide();
}
}]
});
}
win.show(this);
}
You might add the < script > tag to the end of the partial view. That way the script will not be parsed/executed until the partial view is completely rendered.
Can you use the afterrender event on Ext.Window?
Since you are using autoLoad to load the partial view contents, you have to wait until the window has received the response with the partial view contents and has been updated with the components/markup... so you can listen for the update event of the window's updater...
win.on('render', function(component) {
win.getUpdater().on('update', function(el, response) {
// Load Combo
}, win, {single:true});
});
[EDIT]
Make sure you set the event handler to run only once though... edits are above
var win;
if (!win) {
win = new Ext.Window({
layout: 'fit',
width: 750,
height: 630,
closeAction: 'hide',
plain: true,
autoLoad: {
url: '../SearchJob/SearchPanel'
},
buttons: [{
text: 'Submit',
handler: function () { }
}, {
text: 'Close Me',
handler: function () {
win.hide();
}
}]
});
win.on('render', function(component) {
win.getUpdater().on('update', function(el, response) {
// Load Combo
}, win, {single:true});
});
}
win.show(this);