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
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,
});
I need to use both of configs tpl and html within panel class but it's not let to render both configs.
How can be able to use both?
Ext.define('InfoCard.Main', {
extend: 'Ext.panel.Panel',
viewModel: {
type: 'infocardvm'
},
layout: {
type: 'table'
},
items: [{
xtype: 'infocard',
userCls: 'totalReCls',
bind: {
html: '{totalReBar}'
}, //Can't use 'tpl' here because it doesn't have setTpl()
glyph: 'xf015#FontAwesome',
// tpl: 'TotalReBar' //When I'm uncomment the config, then ignores 'bind: html'
}]
});
Here is full sample FIDDLE.
Question is related with this post at Software Engineering site.
You can use displayfield inside of items of panel. In display field have methods for setValue() and setFieldLabel(). So you can change on basis of requirement.
In this FIDDLE, I have created a demo using your code and put modification. Hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.define('InfoCard.Main', {
extend: 'Ext.panel.Panel',
tbar: [{
text: 'Refresh data',
handler: function () {
var vm = this.up('panel').getViewModel(),
store = vm.getStore('firstStore');
store.getProxy().setUrl('stat1.json');
store.load();
}
}],
viewModel: {
type: 'infocardvm'
},
layout: {
type: 'table'
},
defaults: {
xtype: 'infocard',
},
items: [{
items: {
xtype: 'displayfield',
fieldLabel: 'Total ReBar',
bind: '{totalReBar}'
},
glyph: 'xf015#FontAwesome'
}, {
items: {
xtype: 'displayfield',
fieldLabel: 'Total RoBar',
bind: '{totalRoBar}'
},
bodyStyle: {
"background-color": "#DFE684"
},
glyph: 'xf015#FontAwesome'
}, {
items: {
xtype: 'displayfield',
fieldLabel: 'Total PaBar',
bind: '{totalPaBar}'
},
bodyStyle: {
"background-color": "#fbe3ab"
},
glyph: 'xf015#FontAwesome'
}]
});
When I understand you correctly you want to render a static string with a variable value.
{
xtype: 'infocard',
bind: { data: '{totalReBar}' }, // bind the data for the tpl
tpl: 'TotalReBar {totalCount}' // use the data provided via binding in the tpl
}
The formula now has to return an object for the tpl data binding.
You can access the values in the tpl via the key's.
formulas: {
totalReBar: {
bind: {bindTo: '{firstStore}', deep: true},
get: function (store) {
var record = store.findRecord("code", "TOTALRE");
return {
totalCount: record ? record.get("totalcount") : "-1" // totalCount is now available in the tpl as a variable
};
}
},
See the modified fiddle.
I believe that what you want is this:
{
xtype: 'infocard',
userCls: 'totalReCls',
bind: {data: {'myVal': '{totalReBar}'}},
glyph: 'xf015#FontAwesome',
tpl: '{myVal}'
}
hope that helps
I am attempting to load a detail view for an item disclosure from a list but without using NavigationView and the "push()" command.
CONTROLLER:
Ext.define('App.controller.MyPlans', {
extend: 'Ext.app.Controller',
requires: ['App.view.EventDetail',
'App.view.PlansContainer'],
config: {
refs: {
},
control: {
'MyPlansList': {
disclose: 'onDisclose'
}
}
},
onDisclose: function (view, record) {
console.log("My Plans list disclosure " + record.get('id'));
var eventDetailView = Ext.create('App.view.EventDetail');
eventDetailView.setRecord(record);
Ext.Viewport.setActiveItem(eventDetailView);
}
});
VIEW:
Ext.define('App.view.EventDetail', {
extend: 'Ext.Panel',
xtype: 'EventDetail',
config: {
items: [{
xtype: 'toolbar',
docked: 'top',
title: 'Event Name',
items: [{
xtype: 'button',
id: 'addRunBackBtn',
ui: 'back',
text: 'Back'
}]
}, {
xtype: 'panel',
styleHtmlContent: true,
itemTpl: [
'<h1>{name}</h1>',
'<h2>{location}</h2>',
'<h2>{date}</h2>']
}],
}
});
I am basically trying to pass the data to the view using the "setRecord()" command but nothing seems to be loading in the view. Any thoughts??
Thanks
Instead of ItemTpl just write Tpl. I doubt that itemTpl exists without list xtype.
Other thing is put Tpl inside config:
{tpl:['<div class="ListItemContent">{descriptionddata}</div>']}
The answer before/above me is good but if you intend of keeping your formatting inside view and not in controller then , it works by using setData instead of setRecord
detailview.setData({title:record.get('title'), description:record.get('descriptiondata')});
Instead of panel try list as below
Ext.define('App.view.EventDetail', {
extend: 'Ext.TabPanel',
xtype: 'EventDetail',
config: {
items: [{
xtype: 'toolbar',
docked: 'top',
title: 'Event Name',
items: [{
xtype: 'button',
id: 'addRunBackBtn',
ui: 'back',
text: 'Back'
}]
}, {
xtype: 'list',
styleHtmlContent: true,
itemTpl: [
'<h1>{name}</h1>',
'<h2>{location}</h2>',
'<h2>{date}</h2>']
}],
}
});
I found the issue here:
A panel doesn't have a itemTpl
{
xtype: 'panel',
styleHtmlContent: true,
itemTpl : [
'<h1>{name}</h1>',
'<h2>{location}</h2>',
'<h2>{date}</h2>'
]
}
The one of the possible way to do it could be:
Change the VIEW:
{
xtype: 'panel',
id: 'thePanel',
styleHtmlContent: true
}
Change the Controller:
onDisclose: function(me, record, target, index, e, eOpts) {
...
Ext.getCmp('thePanel').setHtml('<h1>'+record.get('name')+'</h1><h2>'+record.get('location')+'</h2><h2>'+record.get('date')'</h2>'); //For setting the Data
...
}
Hope this could help!
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"]'
i have a tab-panel which works fine so far,
but as soon as i apply a grid-panel as one of the tabs i'm getting a js-error somewhere in Observerable.js (a class from ext) that say that 'item.on(...)' is not a function after 'item is undefinded'
Here are the appropriate code lines:
This is what i do in my tab panel:
initComponent: function() {
this.items = [{
xtype: 'profileList',
title: 'Profiles'
}];
this.callParent(arguments);
}
and here is how the code of my grid panel:
Ext.define('BC.view.profile.ProfileList', {
extend: 'Ext.grid.Panel',
alias: 'widget.profileList',
cls: 'profileList',
border: false,
initComponent: function(){
Ext.apply(this, {
store: 'Profiles',
columns: [{
text: 'Name',
dataIndex: 'name',
flex: 1,
}, {
text: 'Others',
dataIndex: 'otherUsers',
width: 200
}, {
text: 'Limit',
dataIndex: 'limit',
width: 200
}]
});
console.log('before');
this.callParent(arguments);
console.log('after');
}
});
Thanks for any help!
Edit: the first console.log works, the error seems to happen in 'callParent()'
You cannot create the items of the tab panel like that:
this.items = [{
xtype: 'profileList',
title: 'Profiles'
}];
You should use Ext.apply(... instead:
Ext.apply(this,{items:[{
xtype: 'profileList',
title: 'Profiles'
}]);