Listener events not being triggered - extjs

I have been playing around with the documentation whilst learning ExtJS. But when testing listener events nothing will happen.
I have generated a modern app using sencha CMD. I deleted all the code that wasn't needed and then added my own based on the documentation. However the listener events just don't seem to work at all. I have tried with several examples and no luck.
What could be the problem?
One example is -
Main
Ext.define('ListenerTesting.view.main.Main', {
extend: 'Ext.panel.Panel',
xtype: 'app-main',
requires: [
'Ext.MessageBox',
'Ext.layout.Fit'
],
controller: 'main',
viewModel: 'main',
tabBarPosition: 'left',
items: [{
xtype: 'button',
text: 'click me',
listeners: {
afterrender: function() {
Ext.Msg.alert("Success", "Message");
}
}
}]
});

Related

Duplicate references when reusing the same component in Sencha app

Suppose we have defined a component (e.g. FieldSet) that we'd like to reuse in the single app (e.g. display/use it in 2 different modal windows.) This FieldSet has a reference, which we use to access it. The goal is to have these 2 windows contain independent fieldsets, so we can control and collect the inputs from each one separately.
Here's the sample fiddle that demonstrates the problem. As soon as any function triggers any lookupReference(...) call, Sencha issues the warning for "Duplicate reference" for the fieldset. It correctly creates two distinct fieldset components (by assigning different ids) on each window, but fails to properly assign/locate the references. As a result, any actions on one of these windows' fieldsets would be performed on the "unknown" one (probably on the first created one), messing up the UI behavior.
I see how it is a problem for Sencha to understand which component to use when operating on the reference, but there should be a way to reuse the same component multiple times without confusing the instances. Any help is greatly appreciated.
According to the docs on ViewController:
A view controller is a controller that can be attached to a specific view instance so it can manage the view and its child components. Each instance of the view will have a new view controller, so the instances are isolated.
This means that your use of singleton on your ViewController isn't correct, as it must be tied to a single view instance.
To fix this, I'd recommend making some modifications to your Fiddle, mainly removing the singleton: true from your VC class, accessing the views through lookup, and getting their VC's through getController to access your func method.
Ext.application({
name: 'Fiddle',
launch: function () {
/**
* #thread https://stackoverflow.com/questions/67462770
*/
Ext.define('fsContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.fsContainerHandler',
// TOOK OUT singleton: true
func: function () {
var x = this.lookupReference('fsRef');
alert(x);
}
});
Ext.define('fsContainer', {
extend: 'Ext.container.Container',
xtype: 'xFSContainer',
controller: 'fsContainerHandler',
items: [{
xtype: 'fieldset',
title: 'myFieldset',
reference: 'fsRef'
}]
});
Ext.define('mainContainerHandler', {
extend: 'Ext.app.ViewController',
alias: 'controller.mainContainerHandler',
singleton: true,
onButton1Click: function () {
var win = this.getView().window1;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
},
onButton2Click: function () {
var win = this.getView().window2;
win.show();
// CHANGED LOGIC
win.lookup('theContainer').getController().func();
}
});
Ext.define('mainContainer', {
extend: 'Ext.container.Container',
width: 400,
controller: 'mainContainerHandler',
window1: null,
window2: null,
initComponent: function () {
this.window1 = Ext.create('window1');
this.window2 = Ext.create('window2');
this.callParent(arguments);
},
items: [{
xtype: 'button',
text: 'Window 1',
reference: 'btn1',
handler: mainContainerHandler.onButton1Click,
scope: mainContainerHandler
}, {
xtype: 'button',
text: 'Window 2',
reference: 'btn2',
handler: mainContainerHandler.onButton2Click,
scope: mainContainerHandler
}]
});
Ext.define('window1', {
extend: 'Ext.window.Window',
title: 'Window1',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.define('window2', {
extend: 'Ext.window.Window',
title: 'Window2',
modal: true,
width: 100,
height: 100,
closeAction: 'hide',
// ADDED referenceHolder
referenceHolder: true,
items: [{
xtype: 'xFSContainer',
// ADDED reference
reference: 'theContainer'
}]
});
Ext.create('mainContainer', {
renderTo: document.body
});
}
});

Sencha Extjs6 - Modern toolkit - NestedList inside an Ext.Menu

I'm quite new to Sencha Extjs6. I'm making a universal app (focusing on the mobile right now) and I'm trying to add a NestedList into a Menu. I have the Menu sliding in from the left and I can display the NestedList, but when I drill down the items in the list get mixed up? I.e. It'll show the parent item as well as its children. If I click back to the root then it'll still display all the leaf nodes etc when it should just show the root item. There's no slide animation between the items either so it makes me think it's not currently possible to use it this way?
When I create the NestedList in isolation (not added to an Ext.Menu) then it works as expected (similar to the KitchenSink example).
This is what I have thus far:
MenuList.js
Ext.define('mobile.view.menu.MenuList', {
extend: 'Ext.NestedList',
xtype: 'menulist',
store: 'mobile.store.menu.MenuListStore',
controller: 'listcontroller',
displayField: 'text',
title: 'Menu',
width: '100%',
itemId: 'menulist',
layout: 'fit',
styleHtmlContent: true,
useTitleAsBackText: false,
backText: ' ',
scrollable: true
});
NavigationMenu.js The nested list is added to this.
Ext.define('mobile.view.menu.NavigationMenu', {
extend: 'Ext.Menu',
xtype: 'navigation',
controller: 'navigation-controller',
renderTo: document.body
...
...
...
getMenuCfg: function(side) {
var me = this;
return {
items:[{
xtype: 'menulist'
}, {
text: 'Log out',
textAlign: 'left'
...
}]
}
}
MenuListStore.js
I have my own data, but I tried it with the carregions example and still didn't change the behaviour.
Ext.define('mobile.store.menu.MenuListStore', {
extend: 'Ext.data.TreeStore',
config: {
model: 'mobile.model.menu.MenuItem',
root: {},
proxy: {
type: 'ajax',
url: 'resources/carregions.json'
}
}
});
MenuItem.js
Ext.define('mobile.model.menu.MenuItem', {
extend: 'Ext.data.Model',
config: {
fields: ['text']
}
});
In a nutshell it works as a standalone component when added to the viewport, but not when I add it as a component into a menu. Any help or guidance would be fantastic. Thanks a lot guys. :)
I managed to solve it. It seems that removing layout: 'fit' got it working.

I cannot get component from controller in ExtJS

I have defined a window like this:
Ext.define(), { 'MyApp.view.MyCustomWindow'
extends: 'Ext.window.Window',
alias: 'widget.mywindow',
...
items: [{
xtype: 'form',
items: [{
xtype: 'fieldset',
...
items: [{
xtype: 'combobox',
...
itemId: 'comboFilter'
}]
}]
}],
dockedItems: [{
xtype: 'toolbar',
items:[{
xtype: 'button',
itemId: 'okBtn'
}]
}]
}
Then I would like to get the component from my controller:
init: function(application) {
var me = this;
this.control({
"mywindow combobox#comboFilter": {
keypress: me.onClickCombo // removed <'>, still not working
},
"mywindow button#okBtn": {
click: me.onButtonOk // works!!!
}
});
}
But onClickCombo is never beeing called. What is wrong with mywindow combobox#comboFilter?
EDIT: Added an "OK button" that works!!! Look at my edit of the code above.
Your selector is not the problem.
Add enableKeyEvents: true to your combobox if you'd like the keypress event to be fired.
See the keypress event documentation:
This event only fires if enableKeyEvents is set to true.
Try this.
"mywindow combobox#comboFilter": {
keypress: me.onClickCombo // without <'>
}
If it isn't the solution, change:
"mywindow combobox[itemId=comboFilter]":{
keypress: me.onClickCombo // without <'>
}
UPDATE:
Add this config to the component.
Sencha api - Combobox Events
Keypress input field event. This event only fires if enableKeyEvents is set to true.

Changing order of tabs in Ext.tab.panel without cut-paste of code manually

I am writing a code as below in Sencha Touch 2.3. Is there a way to bring the nestedlist to show up before the formpanel (it is currently after) without cutting and pasting the code manually? something like each of TabPanel's component having a Rank or an Order property that I can set? Thanks
Ext.create("Ext.tab.Panel", {
fullscreen: true,
tabBarPosition: 'bottom',
items: [
{
title: 'Home',
iconCls: 'home',
cls: 'home',
...
},
{
xtype: 'formpanel',
..
},
{
xtype: 'nestedlist',
..
}
]});
You cannot do it at definition time but you could do it at runtime by calling tabpanel.insert(newIndex, nestedList), where newIndex would be most likely 1 and nestedList is the reference to the already existing nested list.

Sencha Touch 2: How do you use a button on the homepage to navigate to other views?

If you were going to take the "Getting Started with Sencha Touch 2" video one step further and add button navigation on the home page to allow you to go to the Blog and Contact pages how would you do it? I have set it all up like the thread Sencha Touch 2 MVC - how to switch views with button
The problem that I am running into is that if I create a button to go to the Blog page in the Home.js page the button will work but then the nested list on the Blog.js page does not work anymore and the TitleBar from Main.js does not appear on Blog.js anymore either. My controller code looks like this
control: {
'blog list': {
itemtap: 'showPost'
},
'button[go]':{
tap: function(){
Ext.Viewport.setActiveItem({
xtype: 'blog'
})
}
}
}
Where showPost is the same function as the GS video. My button on the Home.js file looks like this
items:[
{
xtype: 'button',
text: 'text',
go: 'buttonPage'
}]
}
Everything else is exactly like the GS video. I want the button on the Home.js page to act exactly like the buttons on the TitleBar work in Main.js from the Getting Started video. What am I missing? Thanks in advance.
4/13/12 Update: all the js files. They are all essentially the original GS video code.
view/Main.js
Ext.define("GS.view.Main", {
extend: 'Ext.tab.Panel',
requires: ['Ext.TitleBar'],
config: {
xtype: 'bottombar',
tabBarPosition: 'bottom',
items:[{xtype: 'homepanel'},
{xtype: 'blog'}]}
});
view/Home.js
Ext.define('GS.view.Home', {
extend: 'Ext.Panel',
xtype: 'homepanel',
config: {
title: 'Home',
iconCls: 'home',
items:[{
xtype: 'button',
text: 'text',
go: 'buttonPage'}]
}
})
view/Blog.js
Ext.define('GS.view.Blog',{
extend: 'Ext.navigation.View',
xtype: 'blog',
requires: ['Ext.dataview.List', 'Ext.data.proxy.JsonP', 'Ext.data.Store'],
config: {
title: 'Blog',
iconCls: 'star',
items: [{
xtype: 'list',
itemTpl: '{title}',
title: 'Recent Posts',
store:{
autoLoad: true,
fields: ['title', 'author', 'content'],
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://data.9msn.com.au/Services/Service.axd/feeds/rss/news/headlines',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
}
}
}]
}
})
controller/Main.js
Ext.define('GS.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
blog: 'blog'
},
control: {
'blog list': {
itemtap: 'showPost'
},
'button[go]':{
tap: function(){
Ext.Viewport.setActiveItem({
xtype: 'blog'
})
}
}
}
},
showPost: function(list, index, element, record){
this.getBlog().push({
xtype: 'panel',
title: record.get('title'),
html: record.get('content'),
scrollable: true,
styleHtmlContent: true,
})
}
});
app.js
Ext.application({
name: 'GS',
requires: ['Ext.MessageBox'],
controllers: ['Main'],
views: ['Main', 'Home', 'Blog'],
launch: function() {
Ext.Viewport.add(Ext.create('GS.view.Main'));
},
});
Since using Ext.Viewport.setActiveItem({xtype: 'blog'}) doesn't reuse the xtypes that you have created it gets confused when trying to use the blog list. I use some of what Roberto said and a little bit of my own code to end up with the controller 'button[go]' function looking like this:
'button[go]':{
tap: function(btn){
if(Ext.ComponentQuery.query(btn.go) == '')
{
Ext.Viewport.setActiveItem({
xtype: btn.go
})
}
else
target = Ext.ComponentQuery.query(btn.go);
Ext.Viewport.setActiveItem(target[0])
}
}
And that created the xtype the first time and then reused it every subsequent time so the navigation in the nexted list worked as well as the navigation on the homepage
you can easily switch views by button tap if you are using navigationView.
take your main view as navigationView .
put the button into the navigationView .
write the following code into tap-listener of your button
this.up('your navigationView xtype').push({
xtype: 'xtype of the view at which you wanna go by button tap'
});
2 Steps You have to follow
in View
{
xtype: "button",
//text: "Book Bus Ticket",
ui: 'action',
action:"book" , // button Action
},
{
xtype: "button",
text: "Get Ticket Details",
ui: 'action',
action:"getticket" , // button Action
},
Note the Button Action
2.in Controller
first specify the particular view xtype as a ref in that controller
Ext.define('jetbus.controller.BookticketController', {
extend: 'Ext.app.Controller',
refs: {
'busdetails':"busDetailsList", // object:xtype
},
control: {
'busdetails button[action=book]': { // button action
tap: 'book'
},
' button[action=getticket]': { // button action
tap: 'getticket'
},
}
book: function(){
var mn=Ext.create('abc.view.Main'); // Functionname the page you want to redirect
Ext.Viewport.add(mn);
Ext.Viewport.setActiveItem(mn);
},

Resources