custom component reuse with extjs4 - extjs

I have created a custom grid in a javascript file. I want to use it as a xtype on to different panels in seperate js files. If I use it on a single panel, it works fine; but when I use try it use it on different panels at the same time, I get a error in the chrome developer tool console saying:
Uncaught TypeError: Cannot read property 'isComponent' of undefined
My grid definition is as follows:
Ext.define('DataBox.view.FootNotes', {
extend : 'Ext.grid.Panel',
alias : 'widget.footNotes',
initComponent : function() {
this.columns = [ {
header : 'SL',
field : {
xtype : 'checkbox',
checked : 'true'
}
}, {
header : 'Symbol',
}, {
header : 'Notes',
}, ];
this.callParent(arguments);
}
});
and to include the grid on the panels i use following code
initComponent : function() {
/* this.footNotesInfoGrid = Ext.create('DataBox.view.FootNotes', {
colspan: 2,
border: false,
frame: 'false'
}); even tried this */
Ext.apply(this,{
items : [{
xtype : 'footNotes',
columnWidth : .50,
id : 'infoFootNotesGrid',
}]
}
}
I tried many other ways suggested on different forum discussions.. but my problem stil persists.
Can somebody point out where I am going wrong?

Don't assign created objects within a configuration! Use initComponent for that!
this line
plugins : [ Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit : 1
}) ],
should be placed as
this.plugins = [ Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit : 1
}) ];
anywhere in the initComponent body, but before callParent is called
Edit:
to still allow override do
if(!this.plugins) {
this.plugins = [ Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit : 1
}) ];
}
Edit
Avoid using static id properties! The framework handle that part for you. Wrap your head around Ext.ComponentQuery instead. It will help you to find any Component you are looking for.

Related

Way to render any component in extjs on fly

I am provided with built in extjs components classes.
I cannot change them as i am working on plugin.
I cannot override them as there are certain things which cannot be
predefined.
And also I want to change component for particular case, not all
cases.
Now If it will be possible that I pick that component from DOM,
change it any of property and render it there onwards. If it could
be done, then my work become lot easy.
Its completely a scenario. But still for ease in understanding, I am adding a sample code.
var tabPanel = Ext.create('Ext.tab.Panel', {
width : 300,
height : 200,
activeTab : 0,
items : [
{
title : 'Tab1',
bodyPadding : 10,
items : [
{
xtype : 'button',
text : 'B1'
}
]
},
{
title : 'Tab2',
items : [
{
xtype : 'button',
text : 'B2'
}
]
}
],
renderTo : Ext.getBody(),
autoRender : true
});
// Change title of tab panel
tabPanel.items.each(function(item) {
item.title = "text"+Math.random();
});
Now I want to remove this already rendered tab panel. And want to render it upon my choice wherever i want.
After lot of search, I find solution to problem. We can use doLayout() or update() function of component to fulfill purpose.

The right event to apply "scrollTo" to show a dynamically added nested panel

I have a panel in ExtJS6 modern (mobile) application that can scroll vertically only. Sub panels are added dynamically to it. I need to scroll the panel to its end after adding a new sub-panel in order to make it visible. This is done using this line:
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
I execute this line in a button click, and it works (but need to click the button manually). I tried to find the right event where I can add this line to do the scroll automatically, without success. I nearly tried all the possible relevant events of the sub-panel: show, add, added, activate, ... I also tried the events of the parent panel without success.
Apparently, these events happen before the scroller of the parent panel takes into account the added sub-panel, so it scrolls to the before-last one. I smell asynchronous behavior here. The proof is that I call the scrollTo method in a delayed task of 0.5 second and it works. But this solution is not reliable.
The question is: where (in which event of which component) this line of code should go in order to scroll the parent to its end correctly?
[EDIT]
Here is the part of the code concerning the question. First, the Message class:
Ext.define('MyApp.view.message.Message', {
extend : 'Ext.Panel',
xtype : 'message',
layout : 'hbox',
config : {
mBody : ''
},
listeners: {
added: function (element) {
MyApp.view.main.Global.scroller.delay(500); //start a delayed task to scroll parent panel
}
},
items: [
{
flex : 1
},
{
maxWidth: '80%',
width: 'auto',
html : '<div class="myClass">' + this.getMBody() + '</div>'
}
]
});
Here is the delayed task that scrolls the parent panel tabmainMessagesPanel to its end in order to show the newly-added message:
Ext.define('MyApp.view.main.Global', {
statics: {
scroller: Ext.create('Ext.util.DelayedTask', function() {
Ext.getCmp('tabmainMessagesPanel').getScrollable().scrollTo(Infinity, Infinity, true);
})
}
}
Now, the tab panel that contains the panel tabmainMessagesPanel that will contain the messages:
Ext.define('MyApp.view.main.TabMain', {
extend : 'Ext.tab.Panel',
mixins : [ 'Ext.mixin.Responsive' ],
xtype : 'tabmain',
responsiveConfig : {
portrait : {
items :
[
{
title : 'Messages',
layout : 'vbox',
items : [ {
xtype: 'panel',
layout : 'vbox',
height: '100%',
id: 'tabmainMessagesPanel',
scrollable : 'vertical',
style : 'background-color:#F0F0F0'
},
{
xtype : 'inputfield',
docked : 'bottom'
}]
},
{
title : 'Connect',
layout: 'vbox',
items : [
//some UI elements
]
}
]
},
//--------------------------------------------------
landscape : {
// same as portrait
}
},
//--------------------------------------------------
controller : 'tabmain',
viewModel : 'tabmain',
defaults : {
tab : {
iconAlign : 'top'
},
styleHtmlContent : true
}
});
Finally, this is an event in a controller that creates and adds a message to tabmainMessagesPanel whenever a new message arrives:
handle_message: function (mess) {
var p = Ext.create('MyApp.view.message.Message', {
mBody : mess.body
});
Ext.getCmp('tabmainMessagesPanel').add(p);
}
Here is the answer for this. I found it 6 months later. I post it here for the benefit of those who may have the same issue.
The solution is to define the event refresh of the scroller of the panel tabmainMessagesPanel, and scroll to the end in it. So, the definition of the panel tabmainMessagesPanel becomes:
{
xtype: 'panel',
layout : 'vbox',
height: '100%',
id: 'tabmainMessagesPanel',
scrollable : 'vertical',
listeners: {
initialize: function (me) {
me.getScrollable().on('refresh', function () {
me.getScrollable().scrollTo(Infinity, Infinity, true);
});
}
},
style : 'background-color:#F0F0F0'
}

ExtJS 5 bind toggle button to multiple components state

I'm working with ExtJS 5 and I need to bind the pressed config of a toggle button to the same config of an arbitrary array of another toggle buttons. In other words it should be something like this:
Ext.define('MyApp.view.MyPanel', { extend : 'Ext.panel.Panel',
alias : 'widget.myPanel',
requires : ['path to viewmodel'],
viewModel : {
type : 'myPanel'
},
items : [
{
xtype : 'button',
reference : 'btn1',
enableToggle : true
},
{
xtype : 'button',
reference : 'btn2',
enableToggle : true
},
// ... bunch of other buttons
{
xtype : 'button',
enableToggle : true,
bind : {
pressed : '{btn1.pressed && btn2.pressed}'
}
}
],
});
Furthermore I should be able to dinamically add or remove components to the dependend toggle button. How can I achieve this?

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
});
}

displaying labels in marathi language

i am tring to display lable of form in marathi language for that
am creating marathi.js
this my mararhi.js
if(Ext.app.formPanel)
{
Ext.apply(Ext.app.formPanel.prototype,
{
selectUser:'नाव'
}
);
}
and my other js file contain this
var Ext.app.formPanel = Ext.extend(Ext.form.FormPanel,{
selectUser:'Select User',
initComponent : function(config) {
Ext.apply(this, {
title : 'User Rights',
bodyStyle : 'padding: 10px; background-color: #DFE8F6',
labelWidth : 100,
width : 755,
id : 'formUserRights',
renderTo:'adminpanel',
items : [ id: 'User',
fieldLabel:this.selectUser,
width:200
] //items
});//Ext.apply
Ext.app.formPanel.superclass.initComponent.apply(this, arguments);
}//init component
}); //yuyu
......
....
but it can not work
it gives error ; missing before
var Ext.app.formPanel = Ext.extend.....
but when i checked all carefully every thing is correctly nested.
First thing, the syntax error that vava noted in his comment above.
Second, you should not var the 'Ext.app.formPanel' namespace.
Third, initComponent does not pass any arguments.
Fourth, you need to call the superclass, not apply it - also no need to pass arguments, as there are none.
Ext.ns('Ext.app');
Ext.app.formPanel = Ext.extend(Ext.form.FormPanel, {
selectUser : 'Select User',
initComponent : function() {
Ext.apply(this, {
title : 'User Rights',
bodyStyle : 'padding: 10px; background-color: #DFE8F6',
labelWidth : 100,
width : 755,
id : 'formUserRights',
renderTo : 'adminpanel',
items : [ {
id : 'User',
fieldLabel : this.selectUser,
width : 200
} ]
});
Ext.app.formPanel.superclass.initComponent.call(this);
}
});
On a side note, I prefer not to use the Ext namespace for my app code, there is a chance for collision that way. I would suggest creating your own namespace.
Enjoy this one on the house, with the hope that someday you will actually award answers.

Resources