TabPanel Events - javascript

I am working with a Ext Js web with some TabPanels and some tabs, and I want to use some different JQuery on each tab, the problem is that if I attach some JQuery event it gets attached to all the tabs, because they are in the same HTML, thus I want to unbind all JQuery events before opening one tab and also bind the ones I want for it, having the events listening just when the corresponding tab it is opened.
For testing the events I attached the following listener to my tabPanel:
listeners:{
beforetabchange : function(){
Ext.Msg.alert("beforetabchange");
},
beforeshow : function(){
Ext.Msg.alert("beforeshow");
},
activate : function(){
Ext.Msg.alert("activate");
},
deactivate : function(){
Ext.Msg.alert("deactivate");
}
}
So I was expecting many pop ups, but the only one showed is the one corresponding to "beforetabchange" and it is only executed the first time that I open one tab... so there is something I do not get, for example: Should be shown the "activate" pop every time I open a tab? I was expecting so.

I'm unable to understand what you want to do, but i have below code, Might be its help you.
items:[{
xtype: 'tabpanel',
activeTab: 0,
items:[{
title: 'tab1',
id:'divtab1',
autoHeight: true,
items:[{
// your content here
}]
},{
title: 'tab2',
id:'divtab2',
autoHeight: true,
items:[{
// your content here
}]
},{
title: 'tab3',
id:'divtab3',
autoHeight: true,
items:[{
// your content here
}]
}],
listeners: {
'tabchange': function(tabPanel, tab){
if(tab.id=="divtab1")
{
function1();
}
else if(tab.id=="divtab2")
{
function2();
}
else
{
function3();
}
}
}
}]

Related

How can i programmatically click on ext menu item

How can i programmatically click the ext menu checkitem? i have tried below code and it did change the checked. However, the checkbox didn't check. thank you.
extMenuCheckItem.items[0].checked = true;
And this doesn't work either.
extMenuCheckItem.items[0].onClick();
You can try using extMenuCheckItem.items[0].click(); which simulates a click.
Try this:
In your view:
items: [
{
xtype: 'menu',
floating: false,
width: 120,
items: [
{
xtype: 'menuitem',
text: 'Menu Item'
},
{
xtype: 'menucheckitem',
text: 'Menu Item',
listeners: {
checkchange: 'onMenucheckitemCheckChange'
}
}
]
}
]
Controller to capture the action:
onMenucheckitemCheckChange: function(menucheckitem, checked, eOpts) {}
Try extMenuCheckItem.items[0].set('checked', true)
with
extMenuCheckItem.items[0].onClick();
you just call one listener for the MenuItem.
But with
extMenuCheckItem.items[0].click();
you simulate the click on the MenuItem and the click event is fired, so every attached listener will run.

Attach a click listener to a menu item

I'm new to ExtJS so here goes. I'm creating a menu on the fly; the menu is only displayed when I click an element e.g. a button or image. The menu has two items I'd like to be able to execute specific functionality i.e. unique when any of the menu items is clicked.
var menu = Ext.create('Ext.menu.Menu', {
bodyStyle: 'backgroundColor: #FFF;',
renderTo: targetElement,
showSeparator: false,
floating: true,
items: [
{
// When clicked do A
text: 'A',
plain: true,
cls: 'menu-item'
},
{
// When clicked do B
text: 'B',
plain: true,
cls: 'menu-item'
}
]
});
I've tried attaching a click listener to each of the menu items but that doesn't seem to work see snippet below.
{
// When clicked do A
text: 'A',
plain: true,
cls: 'menu-item',
listeners: {
click: function(item, e, eOpts) {
console.log("Foo");
}
}
}
Any ideas?
Use menu.showBy() after the menu is created to appropriately position the floating menu and omit the renderTo config when creating the menu.

How to use events -- what event is triggered when a tab activates a container? (extjs 6.5)

While using the sencha extjs 6.5 framework I had a problem with the events.. What I wish to do is create a store that postpones loading until after a tab is activated. (and reload each time a person goes back to that tab).
Now manual loading isn't hard. However I can't seem to find the trigger that occurs when a tab is activate.
The tabs are defined by the main view (which is shown as main in app.js):
Ext.define('MyApp.view.main.Main', {
extend: 'Ext.tab.Panel',
xtype: 'app-main',
requires: [
'Ext.MessageBox',
'Ext.layout.Fit',
],
controller: 'main',
viewModel: 'main',
defaults: {
tab: {
iconAlign: 'top'
}
},
tabBarPosition: 'left',
items: [
{
title: 'Users',
iconCls: 'x-fa fa-user',
layout: 'fit',
items: [{
xtype: 'usercontainer',
}],
},{
title: 'Home',
iconCls: 'x-fa fa-home',
layout: 'fit',
items: [{
xtype: 'ordercontainer'
}]
},
]
});
The second tab is the one I'm interested in, it has the following definition:
Ext.define('BinkPortalFrontend.view.main.OrderContainer', {
//extend: 'BinkPortalFrontend.view.main.BaseContainer',
xtype: 'ordercontainer',
controller: 'order',
extend: 'Ext.Container',
layout: 'vbox',
listeners: {
activate: function(me, oOpts) {
console.log('activating');
},
enable: function(me, oOpts) {
console.log('enabling');
},
focus: function(me, oOpts) {
console.log('focus');
},
focusenter: function(me, oOpts) {
console.log('focus');
},
focusleave: function(me, oOpts) {
console.log('focus');
},
show: function(me, oOpts) {
console.log('show');
},
}
});
As one can quickly see, I've tried testing all kinds of events. However only the activate event seems to fire -at page load-. What am I doing wrong? I'm not fully seeing which of the many events would be useful (see here)
You may want to listen for the tabchange(tabPanel, newCard, oldCard, eOpts) event on the tabpanel, and then fire your own event on the newCard (and maybe a different one on the oldCard).
I realize this is a very old question with an answer already. But I hope for future people (like myself) who find this, here is another perspective.
The "activate" event is fired on the tab itself when it is activated.
See documentation:
https://docs.sencha.com/extjs/6.5.2/classic/Ext.container.Container.html#event-activate
It doesn't work in your example most likely because you've nested (unnecessarily?) the "OrderContainer" inside another panel called "Home". Home receives the "activate" event correctly every time the user opens the tab, but its' children (like OrderContainer, who is doing the listening) do not.
So my suggestions are either:
Rearrange your logic so the "home" component is the one who is listening to the "activate" event and doing whatever loading you want to do.
Remove the "Home" panel entirely, and just use the orderContainer directly.
If you only have the "Home" there to provide a title and icon, you can add those to OrderContainer instead via tabConfig property:
items: [
{
xtype: 'ordercontainer'
tabConfig: {
title: 'Home',
iconCls: 'x-fa fa-home'
}
}
]

How to make HTML render properly into ExtJS tabs?

I am developing a simple JavaScript-based plugin architecture which allows for any JavaScript control from any framework (jQueryUI, ExtJS, etc). to be plugged into and reused on any web page. My plugins below happen to use ExtJS 4.
The first plugin renders fine in the first tab. However, since the second tab hasn't yet rendered when the page loads, the second plugin (also a grid) is first rendering to the document body, and then it renders properly (the HTMLElement/div is moved) inside the tab when the tab is selected. I'd like the plugin content to be hidden prior to rendering inside the tab. Also, when it it does render [when the tab is selected], horizontal scrollbars don't show unless I resize a column.
Any ideas how to fix this?
Ideas: use something other than contentEl; leverage various ExtJS config options; change my architecture.
Here is the plugin code:
(function(MyNamespace) {
var gridDataStore = ...
MyNamespace.Plugin.Chart = MyNamespace.Plugin.extend({
return {
initialize: function() {
// ...
},
render: function() {
var stockGrid = Ext.create('Ext.grid.Panel', {
autoRender: true,
autoShow: true,
store: gridDataStore,
header: false,
stateId: 'stateGrid',
columns: [
{text: 'Symbol', width: 75, sortable: true, dataIndex: 'symbol'},
{text: 'Description', width: 200, sortable: true, dataIndex: 'description'},
{text: 'Quantity', width: 75, sortable: true, dataIndex: 'quantity'},
{text: 'Last Price', width: 85, sortable: true, dataIndex: 'last_price'}
],
viewConfig: {
stripeRows: true,
enableTextSelection: true
}
});
return stockGrid.getEl().dom;
}
};
}
})(MyNamespace);
And here's code using the plugin:
var chart = new MyNamespace.Plugin.Chart();
var anotherPlugin = new MyNamespace.Plugin.Another();
var stocksWindow = Ext.create('Ext.Window', {
title: 'Stocks',
width: 600,
height: 450,
layout: 'fit',
items: [
Ext.create('Ext.tab.Panel', {
activeTab: 0,
items: [{
title: 'Chart',
autoScroll: true,
contentEl: chartPlugin.render() // RENDER FIRST PLUGIN IN FIRST TAB
},{
title: 'Something Else',
autoScroll: true,
contentEl: anotherPlugin.render() // RENDER SECOND PLUGIN IN SECOND TAB
}]
})
]
});
I can add it to an invisible container, but it feels dirty doing so:
var container = document.createElement('div');
document.getElementsByTagName('body')[0].appendChild(container);
container.style.visibility = 'hidden';
var stockGrid = Ext.create('Ext.grid.Panel', {
...
renderTo: container
...
});
Here's an example
Here are a few problems with your code.
What you are calling plugins are not plugins, they are just subclasses of Ext.grid.Panel. A plugin is something that adds functionality to an Ext.Component, but that is not what Stocks is doing. It's just what we call a preconfigured class.
Here's what I would do, just make MyNamespace.Plugin.Stocks be a subclass of Ext.grid.Panel, you can now easily pass those as the items of a Ext.tab.Panel. Make sure you rename it, it's not a plugin.
By giving your widget subclasses the alias: 'widget.stock-grid', you can create them using just an object definition, without having to instantiate them, the framework will take care of rendering it only when needed (the tab is activated)
Ext.create('Ext.tab.Panel', {
activeTab: 0,
items: [{
title: 'Stocks',
autoScroll: true,
xtype: 'stock-grid'
},{
title: 'Orders',
autoScroll: true,
xtype: 'stock-grid'
}]
})
When using managed layouts, you cannot just simply copy a node into another container, because the node you copied in there won't have a managed layout.
Here's a modified version of your code that is written more like Ext-JS intended it. http://jsfiddle.net/NVfRH/10/
You can look into the generated HTML and you'll notice that the grid under orders only renders when you activate that tab.
You should also notice that your grids weren't properly sizing themselves to fill the window, my code fixes that since they are correctly placed in the layout pipeline and obey the fit layout.
Remaining Problems
Your grids are sharing a store, notice that when you sort one, the other gets sorted, so you can't have them with different sorting.
You were using a stateId, but then you were creating two instances with the same stateId, all stateIds must be unique
And lastly, I must ask, were you really relieved when Chad Johnson changed his name to Chad Ochocinco? :)

Ext JS empty ItemSelector when loaded for the second time

i'm a newbie with ExtJS, i'm using ExtJS 4.0.7 and what they call MVC, just getting use to the code, so, i was taking a look to the examples, and there is one that works perfect for what i'm trying to do, the "MultiSelect and ItemSelector" example, more specific, the ItemSelector, that is the one i'm using, it use some kind of library named "ux", that is show for example i think, but the ItemSelector is ok form me, i don't want to change or add nothing to the component, so, what i do is, create a Window with a Form in it, and within the form an ItemSelector, the ItemSelector use a remote store cuz i load the data from the database, everything works perfect, i can see the data in the ItemSelector and use the component, the problem is when i close the window and open it again, the ItemSelector is just empty, no error, no warning, nothing that point to a problem, just an empty ItemSelector, this is my code:
//My window definition
Ext.define('Sigep.view.ProjectForm', {
extend: 'Ext.Window',
uses: ['Ext.ux.form.ItemSelector'],
id:"projectFormWindow",
title: 'New Project',
autoHeight:true,
width: 700,
modal:true,
layout: 'fit',
initComponent: function() {
var win = this;
var studentStore = Ext.create('Sigep.store.StudentsStore');
this.items = [
{
xtype:"form",
id: 'projectForm',
bodyPadding: 10,
border:false,
autoHeight:true,
postUrl:baseURL+'projects/save',
defaults: {
border:false
},
fieldDefaults: {
labelAlign: 'left',
labelWidth: 110,
msgTarget: 'side'
},
items:[
{
xtype:'tabpanel',
plain:true,
activeTab: 0,
height:260,
margin: '10 0 0 0',
defaults:{
bodyStyle:'padding:10px'
},
items:[{
title:'Autor(es)',
defaults: {
allowBlank:false
},
defaultType: 'textfield',
items:[
{
xtype: 'itemselector',
name: 'project[authors][]',
id: 'itemselector-field',
anchor: '100%',
labelWidth: 90,
width:600,
height:210,
fieldLabel: 'ItemSelector',
imagePath: baseURL+'extjs/ux/images/',
store: studentStore,
displayField: 'fullName',
valueField: 'userId',
maxSelections:2,
buttons: ['add', 'remove'],
delimiter:null
}
]
}]
}
]
}
];
this.buttons= [{
text: 'Save',
handler:function(){
win.close();
}
},{
text: 'Cancel',
handler:function(){
win.close();
}
}];
studentStore.load();
this.callParent();
}
});
///////////////////////////////////////////////
//In a click event of a button
var win = Ext.create('Sigep.view.ProjectForm');
win.show();
//////////////////////////////////////////////
//The Store definition
Ext.define('Sigep.store.StudentsStore', {
extend: 'Ext.data.Store',
fields: ['userId', 'fullName'],
proxy: {
type: 'ajax',
url:baseURL+'accounts/students',
reader: {
type: 'json',
root: 'results'
}
}
});
I also tried setting autoLoad:true to the store, but it doesn't work neither, so, As you can see, all is very simple, the first time i open the window, everything works ok, but when i close and open again, the ItemSelector is empty, i tried with every event i can try already, and nothing work, with the FireBug, after the window is show, i execute something like this
//if i execute this code after the window is show, the item selector is filled with the data
var item = Ext.getCmp("projectFormWindow").down('#itemselector-field');
var store = item.store;
item.bindStore(store);
this code reload the itemselector after the window is show, so i tried in the show event, but it doesn't work, if i put a button in the window and in the handler this 3 lines, the ItemSelector is loaded ok. the funny is that ItemSelector extend MultiSelect, and if i change the xtype to multiselect, it works great, just perfect, but what about the ItemSelector, i was looking inside the definition code and i think is something like in the second load the toField is not getting created, but i don't know how to deal with this,
so, exist a workarround for this? a way to make it work? hope you can help me guys
thanks
I was looking into the Ext js forum, someone gave a solution, i don't know if it is the best but it works for me,
studentStore.load(function(){
win.down('#itemselector-field').bindStore(studentStore);
});
now, it is working as i wanted
hope it can help others
In my Forms initComponent method I added a listener for beforerender
initComponent: function () {
var me = this;
Ext.applyIf(me, {
listeners: {
beforerender: {
fn: me.onFormBeforeRender,
scope: me
}
}
});
me.callParent(arguments);
},
onFormBeforeRender: function(abstractcomponent, options) {
// where store is created globally like this var store = Ext.create('TIP.store.CommodityStore');
store.load(function(){
Ext.getCmp("commoselector").bindStore(store);
});
}

Categories

Resources