I have a Tab panel with multiple Tabs in it. Now I want to add a simple button with an action to the tab bar. When clicked it should not open a Tab like the other ones, just execute a javascript function.
How is this possible in Extjs?
Yes it is possible. You can do it with tabBar configuration. You will need to add setActive method and will need to handle events to change tabs.
You can also specify different styles for each tab header, have different types of headers and can easily highlight specific tab in custom colors as shown in fiddle.
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.Viewport.add({
xtype: 'panel',
layout: 'fit',
title: 'Tab Panel with custom button',
items: [{
xtype: 'tabpanel',
id: 'tabPanel',
tabBar: {
items: [{
xtype: 'button',
text: 'Batman',
ui: 'action',
setActive: function (active) {
this.setPressed(active);
},
handler: function () {
var tabPanel = Ext.getCmp('tabPanel');
tabPanel.setActiveItem(0);
}
}, {
xtype: 'button',
text: 'Goku',
ui: 'action',
setActive: function (active) {
this.setPressed(active);
},
handler: function () {
var tabPanel = Ext.getCmp('tabPanel');
tabPanel.setActiveItem(1);
}
}, {
xtype: 'spacer',
setActive: function () {}
}, {
xtype: 'button',
text: 'Custom button',
ui: 'decline',
setActive: function () {},
handler: function () {
Ext.Msg.alert('Custom Message', 'This way you can do custom js function execution on tab bar');
}
}]
},
items: [{
items: [{
html: 'Batman is cool'
}]
}, {
items: [{
html: 'Goku can defeat superman'
}]
}]
}]
});
}
});
Example Fiddle : https://fiddle.sencha.com/#view/editor&fiddle/29r1
Related
I am new to ExtJS and I want to create a container Panel for my buttons in ExtJS, all i managed to do so far is to try to add a simple button in my class like so :
Ext.define('MyClass.view.buttons', {
extend: 'Ext.container.Container',
alias: 'widget.MyClass',
controller: 'MyClass',
requires: [
'MyClass.view.Main',
],
items : [
{
xtype: 'button',
text : 'My Button'
}
]
});
Which doesn't display nothing too (with no reported errors in the console).
Please help me out with this.
Update:
You can user handler or listeners property to set click handler. My code was just for reference and rendering element to body will of course render it on page and not inside another element. Take a look at this updated example, where I have used xtype property of my defined component to use it inside another custom component.
Ext.define('MyClass.view.buttons', {
extend: 'Ext.container.Container',
alias: 'widget.MyClass',
xtype: 'myclass',
items: [{
xtype: 'button',
text: 'Child Button Button',
handler: function() {
alert('You clicked the button!');
}
}]
});
Ext.define('MyClass.view.anotherButtons', {
extend: 'Ext.container.Container',
alias: 'widget.MyAnotherClass',
items: [{
xtype: 'myclass'
}, {
xtype: 'button',
text: 'Parent Container Button'
}]
});
Ext.create('MyClass.view.anotherButtons', {
renderTo: Ext.getBody(),
width: 400,
height: 300,
});
Ext.define('MyClass.view.buttons', {
extend: 'Ext.container.Container',
alias: 'widget.MyClass',
items: [{
xtype: 'button',
text: 'My Button'
}]
});
Ext.create('MyClass.view.buttons', {
renderTo: Ext.getBody(),
width: 400,
height: 300,
});
Using Extjs 5 I am defining my custom toolbar:
Ext.define('Core.toolbar.view.ToolbarView',
{
extend: 'Ext.toolbar.Toolbar',
dock: 'top',
items: [
{
xtype: 'button',
text: 'add'
},
{
xtype: 'button',
text: 'remove'
}]
});
Now I want to use it:
Ext.define('MyApp.view.ToolbarView',
{
extend: 'Core.toolbar.view.ToolbarView',
items: [
{
xtype: 'button',
text: 'ADDING AN OTHER BUTTON'
}]
});
Ext.create('MyApp.view.ToolbarView');
Using items property I am overriding the old items with the new item, but I do not want to do it. I want to add third button.
Is possible?
I'd make use of initComponent, like this (example):
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('Core.toolbar.view.ToolbarView', {
extend: 'Ext.toolbar.Toolbar',
dock: 'top',
items: [{
xtype: 'button',
text: 'add'
}, {
xtype: 'button',
text: 'remove'
}]
});
Ext.define('MyApp.view.ToolbarView', {
extend: 'Core.toolbar.view.ToolbarView',
initComponent: function() {
this.callParent();
this.add({
xtype: 'button',
text: 'ADDING AN OTHER BUTTON'
});
}
});
Ext.create('MyApp.view.ToolbarView', {
renderTo: Ext.getBody()
});
Ext.create('MyApp.view.ToolbarView', {
renderTo: Ext.getBody()
});
}
});
You can use onClassExtended on your core toolbar and set a onBeforeCreated hook, for example:
onClassExtended: function (cls, data, hooks) {
var onBeforeClassCreated = hooks.onBeforeCreated,
Cls = this,
xArray = Ext.Array;
hooks.onBeforeCreated = function (clss, dataa) {
dataa.items = xArray.from(Cls.prototype.items).concat(xArray.from(dataa.items));
onBeforeClassCreated.call(this, clss, dataa, hooks);
};
}
Working example: https://fiddle.sencha.com/#fiddle/t3i
When you provide items on extending an Ext.container.Container (or creating an instance of it), by default, any previously specified items will be overridden, indeed. There is no out-of-the-box logic in place to merge them — simply because Ext JS does not know how you want them merged: whether you want the latter items to go after the former ones, or before, or somehow in the middle, or you want overriding. You need to tell Ext JS what you want explicitly.
So, here is yet another approach:
Ext.define('Core.toolbar.view.ToolbarView', {
extend: 'Ext.toolbar.Toolbar',
dock: 'top',
buildItems: function() {
return [
{
xtype: 'button',
text: 'add'
},
{
xtype: 'button',
text: 'remove'
}
];
},
initComponent: function() {
this.items = this.buildItems();
this.callParent();
}
});
Ext.define('MyApp.view.ToolbarView', {
extend: 'Core.toolbar.view.ToolbarView',
buildItems: function() {
return this.callParent().concat([
{
xtype: 'button',
text: 'ADDING AN OTHER BUTTON'
}
]);
}
});
Ext.create('MyApp.view.ToolbarView');
Example: https://fiddle.sencha.com/#fiddle/t48
I have this weird issue with ExtJS 4.2.1.
I have a controller whose listeners catch events from a view that it shouldn't.
Here's said controller:
Ext.define('Customer_Portal_UI.controller.NavigationMenu', {
extend: 'Ext.app.Controller',
init: function () {
this.control({
'panel': {
render: function (panel) {
panel.body.on('click', function (panel, e) {
alert('onclick');
});
}
}
});
}
});
It 'controls' this view:
Ext.define('Customer_Portal_UI.view.NavigationMenu', {
extend: 'Ext.form.Panel',
alias: 'widget.navigationmenu',
region: 'west',
layout: 'fit',
ui: 'cssmenu',
loader: {
autoLoad: true,
url: '/resources/notloggedin.html'
}
});
But it also catches panel clicks from this view:
Ext.define("Customer_Portal_UI.view.MainContent", {
extend: 'Ext.form.Panel',
alias: 'widget.maincontent',
region: 'center',
layout: 'card',
border: false,
activeItem: 0,
requires: ['Ext.grid.Panel'],
initComponent: function () {
this.items = [
{
xtype: 'panel',
title: ''
},
{
xtype: 'gridpanel',
id: 'contactlistgrid',
store: Ext.data.StoreManager.lookup('contactStore'),
columns: [
....
],
features: [{
ftype: 'grouping',
groupHeaderTpl: ['{columnName}: {name} - ({rows.length} employees)'],
hideGroupedHeader: true,
startCollapsed: false
}],
viewConfig: { id: 'contactlistgridview' }
},
{
xtype: 'gridpanel',
id: 'caselistgrid',
store: Ext.data.StoreManager.lookup('caseStore'),
columns: [
{ text: 'Title', dataIndex: 'title' },
{ text: 'Description', dataIndex: 'description' },
{ text: 'Ticket number', dataIndex: 'ticketnumber' }
],
viewConfig: { id: 'caselistgridview' }
}
]
this.callParent(arguments);
}
});
Do you see any obvious reasons why it would do this ? panel is indeed the panel I'm clicking and not the document body, which could have explained why.
Note that's in not catching clicks from other panels, just from the MainContent view, which it should not...
Thanks.
The fix was two fold as shown in here:
http://www.fusioncube.net/index.php/sencha-extjs-4-make-any-component-fire-a-click-event/comment-page-1
Then I was able to listen to 'click' for 'panel' (there's only one panel within the view) within my controller without having to refine my selector.
Ext.application({
launch: function () {
Ext.define("User", {
extend: "Ext.data.Model",
config: {
fields: [{name: "title", type: "string"}]
}
});
var myStore = Ext.create("Ext.data.Store", {
model: "User",
proxy: {
type: "ajax",
url : "http://www.imdb.com/xml/find?json=1&nr=1&tt=on&q=twilight",
reader: {
type: "json",
rootProperty: "title_popular"
}
},
autoLoad: true
});
var view = Ext.Viewport.add({
xtype: 'navigationview',
//we only give it one item by default, which will be the only item in the 'stack' when it loads
items: [{
xtype:'formpanel',
title: 'SEARCH IMDB MOVIES ',
padding: 10,
items: [{
xtype: 'fieldset',
title: 'Search Movies from IMDB',
items: [{
xtype: 'textfield',
name : 'Movie Search',
label: 'Search Movie'
}, {
xtype: 'button',
text: 'Submit',
handler: function () {
view.push({
//this one also has a title
title: 'List of Movies',
padding: 10,
//once again, this view has one button
items: [{
xyz.show();
}]
});
}
}]
}]
}]
});
var xyz = new Ext.create("Ext.List", {
fullscreen: true,
store: myStore,
itemTpl: "{title}"
});
}
});
error is with xyz.show();
it will work properly if i remove xyz.show();
but i want to show list after clicking on buttton
This is a navigation view on click of button i want to show list
Change your xyz list as follows:
var xyz = new Ext.create("Ext.List", {
//this one also has a title
title: 'List of Movies',
padding: 10,
xtype:'xyz',
alias:'xyz',
hidden:true,
fullscreen: true,
store: myStore,
itemTpl: "{title}"
});
Then just below it write
view.add(xyz);
Then in your handler
handler: function () {
xyz.show();
}
Not tested but it should work with possible adjustments.
Try this :
handler: function () {
view.push({
//this one also has a title
title: 'List of Movies',
padding: 10,
//once again, this view has one button
items: [
xyz
]
});
}
i am a noob in ext js and stuck with a problem.
i have created an app
this is the init function of my controller.
init: function () {
console.log('initialized filesystem controller');
this.control({
'filesystemtree': {
itemdblclick: this.OpenFile,
select: this.NodeSelected
},
'filesystemtree filesystemmenu button[text="Delete"]': {
click:this.DeleteButtonClicked
}
});
}
and this is the view with xtype : 'filesystemtree'
Ext.define('IDE.view.fileSystem.List', {
extend: 'Ext.tree.Panel',
alias: 'widget.filesystemtree',
title: 'Navigation2',
store: 'FileSystems',
rootVisible: 'false',
dockedItems: [{
xtype:'filesystemmenu',
dock:'top'
}],
initComponent: function () {
console.log('file system tree initializing');
this.callParent(arguments);
}
})
and this is the view with xtype:filesystemmenu docked to filesystemtree
Ext.define('IDE.view.fileSystem.FileSystemMenu', {
extend: 'Ext.toolbar.Toolbar',
alias: 'widget.filesystemmenu',
items: [
{
xtype: 'splitbutton',
text: 'Menu',
menu: new Ext.menu.Menu({
items: [
{
text: 'Delete'
},
{
text: 'Copy'
},
{
text: 'Paste'
},
{
text: 'Cut'
},
{
name: 'Rename',
xtype: 'textfield',
emptyText: 'Enter text to rename'
}
]
})
},
{
text: 'Add Item',
id:'FSAddItemButton'
},
'->',
{
xtype: 'box',
id: 'fileSystemNodeNameLabel'
}
]
})
but in the controller im unable to attach a click event to the delete button present in the filesystemmenu which itself is present as a docked item to the filesystemtree.
basically this line in the controller aint working.
'filesystemtree filesystemmenu button[text="Delete"]': {
click:this.DeleteButtonClicked
}
what am i doing wrong?
Look at your selector. You're asking it to find a button with the text "Delete", however you don't have any component matching the criteria, because children of menus are Ext.menu.Item by default, so your selector should be:
'filesystemtree filesystemmenu menuitem[text="Delete"]'