ExtJS 5 create dynamic panel from object - extjs

lets say I have object
var obj = {
xtype: 'panel',
title: 'other panel'
}
And I want to get dynamic panel from it.
I want something like this:
var obj = {
xtype: 'panel',
title: 'other panel'
}
var panel = Ext.create(obj); //not work of course
and then bind event
panel.on('added', function(){console.log('hello world'});
how It possible?

Try using Ext.widget instead, like:
var panel = Ext.widget(obj.xtype, obj);

Related

ExtJS6: Binding store to panel items

Does ExtJS6 allows a store binding to simple panel items, such that it plucks specified columns and display them as item
{
xtype: 'panel',
id: 'master_list',
title: 'MasterList',
defaultType: 'button',
bind: {
store: '{zones}'
}
}
Atm in extJS 6, the item config on a panel is not a bindable item, mostly due to the fact that there is no getItem() and setItems() method found on the panel. You could always override panel and add that functionality and it would look something like this:
Ext.define("Ext.panel.StoreButtonPanel", {
/* extend a panel so you get same base functionality of a panel */
extend: 'Ext.panel.Panel',
/* other configs and overrides you might want */
setStore:function(){
// function to bind the store to panel
},
getStore:function(){
// function to get store from panel
}
setItems: fuunction(){
var me = this,
myStore = me.getStore();
// loop through store and add items.
myStore.each(function(storeItem){
// create the items that you want from teh store via loop and using
// storeItem
Ext.create('Ext.button.Button', {
text: storeItem.get('text'),
/* other things here if needed */
})
});
},
init: function(){
var me = this;
// call method to create items if a store is found.
if(me.getStore()){
me.setItems();
}
me.callParent();
}
});
You can add store parameter to your panel. Extjs will load the store directly.
store: Ext.Create('Yourapp.store.storename'),

How do I access root node from event handler in Tree?

How do I access my treepanel from an event handler inside of an Ext.tree.Panel ?
The following itemClick code does not work. I have tried going both 'up' and 'down'.
Ext.create('Ext.tree.Panel', {
title: 'Example Tree',
width: 200,
height: 450,
store: store,
listeners: {
itemclick: function(dv, record, item, index, e) {
var me = this;
var panel = me.up('treepanel');
var rn = panel.getRootNode(); //panel undefined :(
}
}
}
However if I have a button in a toolbar it works fine :
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
text: 'Search',
handler: function () {
var me = this;
var panel = me.up('treepanel');
var rn = panel.getRootNode(); // :)
}
}]
}]
Both these examples are illustrated in this fiddle.
This is how scope works in ExtJS(To be more specific, in Javascript). In the first example, 'this'(me) it self is treepanel. Try following
`listeners: {
itemclick: function(dv, record, item, index, e) {
//var me = this;
//var panel = me.up('treepanel');
var panel = this; //'this' is treepanel
var rn = panel.getRootNode();
}
}`
Coming to the second example, if you observe the config pattern, it is a shortcut pattern to create a button inside the toolbar, hence 'this' becomes the button and you can get tree by component query.
As you are inside the panel Bala's approach should work. If it doesn't try like below. The first parameter of the itemclick function is the view. You can get the panel from it.
listeners: {
itemclick: function(dv, record, item, index, e) {
var panel = dv.up('treepanel');
var rn = panel.getRootNode();
}
}

Accessing toolbar from extjs Grid

I have a requirement where I have a number instances of a custom Grid (called PackageGrid).
This Grid has a default Toolbar with a couple of buttons. However for each instance of the Grid that I create, some additional widgets can be added to the toolbar using the insert method on the toolbar like so :
tBar.insert(0, {xtype:'button'})
My first approach was to define a custom toolbar and assign it to a variable, and then add that variable to my Grid, like so :
var tb = Ext.create('js.grid.Toolbar') //my custom toolbar
Ext.define('js.grid.PackageGrid', {
referenceToToolbar: tb,
extend: 'Ext.grid.Panel',
tbar: tb //this.toolbar
});
I hold a reference to the toolbar called referenceToToolbar. I then later grab this toolbar reference and add my widgets.
this.packageGrid = Ext.create('js.grid.PackageGrid')
var tBar = this.packageGrid.referenceToToolbar;
tBar.insert(0, {....})
The problem with this approach is that when I add widgets using tBar.insert(..) to my grid instances, ALL of my grids isntances get the same widgets... because, while the Grids are seperate instances, there is only one toolbar instance shared across all grids (tb).
I have tried playing around with the initComponent method to create an instance of the toolbar.
Basically I need ONE instance of a toolbar for ONE instance of my grid. And then be able to get a reference to that toolbar (before render time), and add some more widgets.
Can that be done?
You can pass additional toolbar item as configuration into grid. Then in grid's initComponent method you can create grid's tbar with merged items (shared and additional).
So your grid definition could be like this:
Ext.define('js.grid.PackageGrid', {
extend: 'Ext.grid.Panel',
initComponent: function() {
var me = this;
me.initTbar();
me.callParent();
},
initTbar: function() {
var me = this;
var tbarItems = [{
xtype: 'button',
text: 'Shared Button'
}];
if (me.aditionalTbarItems && me.aditionalTbarItems.length) {
tbarItems = me.aditionalTbarItems.concat(tbarItems);
}
me.tbar = tbarItems;
}
});
Then you can pass additional toolbar items in configuration when you are creating instance of your grid:
var grid1 = Ext.create('js.grid.PackageGrid', {
title: 'Grid 1',
aditionalTbarItems: [{
xtype: 'button',
text: 'Grid 1 Button'
}],
renderTo: Ext.getBody()
});
Fiddle with example: https://fiddle.sencha.com/#fiddle/70q

Dynamically add xtype items to the panel with slidenavigatoin

So I'm trying to put items dynamically to the panel that has slidenavigation feature:
// FlyoutNavigation.js
Ext.define("APN.view.FlyoutNavigation", {
id: "flyoutNavigationPanel",
extend: 'Ext.ux.slidenavigation.View',
Here is the initialisation of the view in another view:
// MainViewContainer.js
this.home = "Some var"
this.flyout = Ext.create('APN.view.FlyoutNavigation', {
id: 'flyoutNavigationPanel',
home: this.home
});
Than I'm trying to use this variable in the this.config.items section, however that doesn't work, it seems that Sencha compiles everything first and than initialiases the components, I might be wrong, I'm really new to Sencha Framework.
So here is the view where the home variable is used:
Ext.define("APN.view.FlyoutNavigation", {
id: "flyoutNavigationPanel",
extend: 'Ext.ux.slidenavigation.View',
xtype: 'flyoutnavigation',
requires: [
... heaps of things omitted ...
],
initialize: function () {
this.callParent();
this.setupDynamicItems();
},
config: {
items: [
{
itemId: 'nav_home',
id: 'homeView',
items: [{
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: this.home, // - that's the place where UNDEFINED occurs
flex: 1
}
],
},
So this.home is undefined...
One possible solution
Comming from this question: How to dynamically create xtype templates in Sencha Touch
I decided to put all the code in this.config.items.add({ ... my items ... }) however Ext.ux.slidenavigation.View looks like gave me the BUG! :( as the initialise method occurs after the binding methods on items of FlyoutNavigation view.
Here is the message from of the bug: Uncaught TypeError: Cannot read property 'raw' of undefined View.js:310 which is basically this line: if (Ext.isFunction(item.raw.handler)) {
So my questions would be
How to get the instance variable in the config.items section? If that's possible, than all is OK
Or do you know the work around of this issue?
Thanks
I don't think you can use this.config when defining the class, instead you can use initialize function as I told you earlier. So you should be able to do this:
initialize : function() {
var me = this;
var home = me.config.home;
me.add({
itemId: 'nav_home',
id: 'homeView',
items: [{
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: home,
flex: 1
}
],
});
}
OR if you have defined homeView in parent class, you can do this:
initialize : function() {
var me = this;
var home = me.config.home;
me.down('#homeView').add({
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: home,
flex: 1
});
}

Populating the value of a Label

I am using the MVC architecture (i have gone through the docs on MVC, but i am still lost here) and i need to know how to populate the records on to my Label. I know that i have to get this done by Stores.
I have loaded the values from the store, but unable to display it on my Panel for some reason. here's my code;
Most of the examples/books demonstrates how to display in a grid, but not a label (I know it has to be the same logic, but i am lost). And it shows how to write to a DB/JSON file and not display the values.
I need to display the COUNTRYNAME in the Label text. This is an example code that i am doing to understand this, can some one help me ?
Ext.define ('ProjectDisplayExample.model.Country',{
extend: 'Ext.data.Model',
//
fields:['countryid','countryname']
//
});
STORE
Ext.define('ProjectDisplayExample.store.Country',{
extend:'Ext.data.Store',
model:'ProjectDisplayExample.model.Country',
remoteGroup:true,
proxy: {
actionMethods : {
read : 'POST',
},
type: 'ajax',
url : '/server/country.php'
}
});
VIEW
Ext.define('ProjectDisplayExample.view.CountryWindow', {
extend: 'Ext.window.Window',
alias: 'widget.countrywindow',
...........
initComponent: function() {
var st = Ext.getStore('Country');
st.load();
this.items = [
{
items: [
{
xtype: 'panel',
region: 'north',
items: [{
xtype: 'label',
// NEED TO DISPLAY COUNTRT NAME FROM THE STORE HERE
}]
}]
}
UPDATE
var store = ... // Your store
store.on('load', function() {
// here store is loaded and you can do anything you want with it
console.log('store is loaded. number of records = ', store.getCount());
}, this, { single: true });
store.load; // I ADDED THIS LINE.................... <---------
UPDATE 2
this.items = [
{
items: [
{
xtype: 'panel',
region: 'north',
items: [{
xtype: 'label',
name : f
}]
}]
I will not post a code sample to exactly solve your question, but I will give you couple points:
Store contains array or records. So you can't just say give me country name from the store. You need first to get a record, for example: var r = store.getAt(0), and only after that you can get countyname field var f = r.get('countryname').
Load() method is asynchronous, so you can just execute it somewhere in the code and assume that for the very next line your store is ready. You need to subscribe to the load event, something like:
var store = ... // Your store
store.on('load', function() {
// here store is loaded and you can do anything you want with it
console.log('store is loaded. number of records = ', store.getCount());
}, this, { single: true });
store.load();
Labels as in xtype: label are actually very rarely used in ExtJs. What exactly are you trying to display in that panel? But anyhow... after you get data out of the store you can use something like update() or setValue() or any other method to update component.
Hope this helps...

Resources