Sencha Touch FireEvent from view is not being received in Controller - sencha-touch

I have this defined in my view:
View:
Ext.define("MyApp.view.Welcome", {
extend: 'Ext.Panel',
alias: 'widget.welcomeview',
config: {
///...items... removed lines for brevity..
{
xtype: 'button',
id : 'btnSignInNow',
text: 'Sign In Now',
listeners: {
tap: function() {
this.fireEvent("onSignInNowTap", this);
console.log("onSignInNowTap fired"); /// <-- I see this in console.log
}
}
}
I can see this in the log. But in my controller it is not receiving the event. Can anybody shed any light on this?
Controller:
config: {
refs: {
welcomeView: 'welcomeview'
},
control: {
welcomeView: {
onSignInNowTap: function () {
alert('bla!'); <!-- I Don't see this in console.log
}
}
}
}
I appreciate I might have missed something, but is there any way that I can debug to find out how/where this event is being lost or ignored?

Try
this.parent.fireEvent("onSignInNowTap", this);
instead of
this.fireEvent("onSignInNowTap", this);
that way parent view will be firing event instead of button.
Sometimes if button is nested deep inside you might have to do something like this
this.parent.parent.parent....fireEvent("onSignInNowTap", this);

Write your view's listeners inside initialize,
you will get reference to this in the initialize
Ext.define("MyApp.view.Welcome", {
extend: 'Ext.Panel',
alias: 'widget.welcomeview',
initialize:function(){
this.callParent();
listeners: {
tap: function() {
this.fireEvent("onSignInNowTap", this);
console.log("onSignInNowTap fired");
}
}
}

Thanks ThinkFloyd. Your solution worked. I had to to use this.parent.fireEvent(...) and then the controller was able to catch it...

Related

Sencha Touch2: Passing data from Controller to floating Panel not working

I am new to Sencha Touch2 and facing problem while passing data from my Controller to Floating panel on listitem tap. Here is my controller implementation code:
Ext.define('CustomList.controller.Main', {
extend: 'Ext.app.Controller',
requires:['CustomList.view.DatePanel'],
config: {
refs: {
listView: 'listitems'
},
control: {
'main test2 list': {
activate: 'onActivate',
itemtap: 'onItemTap'
}
}
},
onActivate: function() {
console.log('Main container is active');
},
onItemTap: function(view, index, target, record, event) {
console.log('Item was tapped on the Data View');
Ext.Viewport.add({
xtype: 'DatePanel'
});
}
});
Am able to get data in the controller and DatePanel.js is my floating Panel.
DatePanel.js:
Ext.define('CustomList.view.DatePanel', {
extend: 'Ext.Panel',
alias: 'widget.DatePanel',
xtype:'datepanel',
config: {
itemid:'DatePanel',
modal:true,
centered: true,
hideOnMaskTap:true,
width:'500px',
height:'650px',
items:[
{
styleHtmlCls:'homepage',
tpl:'<h4>{name3}</h4>'
},
{
xtype:'toolbar',
docked:'bottom',
items:[{
text:'OK',
ui:'confirm',
action:'ShowTurnOverReport',
listeners : {
tap : function() {
console.log('Ok');
}
}
},
{
text:'Cancel',
ui:'confirm',
action:'Cancel',
listeners : {
tap : function() {
console.log('Cancel');
var panelToDestroy = Ext.getCmp('datepanel');
panelToDestroy.destroy();
Ext.Viewport.add(Ext.create('CustomList.view.Test2'));//Test.js is my list Panel
}
}
}]
}
]
}
});
Help me out in destroying the panel on 'Cancel' Button.
Can anyone please help me. Thanks.
Create instance of panel you want to add first.
var floatingDatePanel = Ext.create('Yourapp.view.YourDatePanel');
Next get data of selected list item on itemTap
var data = record.getData();
Assign this data to floatingDatePanel with setData() method
UPDATE,
after looking at your panel code, I guess you want to set data to first item in panel ie
{
styleHtmlCls:'homepage',
tpl:'<h4>{name3}</h4>'
}
Right ? If so then you need to change following code
floatingDatePanel.setData(data);
to
floatingDatePanel.getAt(0).setData(data);
Because, it is first item inside panel that is having a template assigned and hopefully the same where you want to set data.
then finally, you can add this panel into viewport with
Ext.Viewport.add(floatingDatePanel);

List item disclosure isn't firing inside a controller

I'm trying to get the item disclosure to work in a list item in Sencha Touch using a controller ref. But the event never seems to fire/receive inside controller. All of the examples I've seen have the list item using a listener but I thought that wasn't very MVC so I'm trying to do it this way (is there any reason why they use listeners instead of a controller?)
In my view, the list is an item inside the EnquiryIndex view.
When I do this in a console window it returns the list correctly so I know the ref is working ok:
Ext.ComponentQuery.query("enquiryindexview list")[0]
See below example:
Ext.define('MyApp.controller.EnquiryIndex', {
extend: 'Ext.app.Controller',
requires: [
],
config: {
refs: {
enquiryIndexViewRef: 'enquiryindexview list'
},
control: {
'enquiryIndexViewRef': {
disclose: 'onDiscloseEnquiryIndex'
}
}
},
onDiscloseEnquiryIndex: function (rec) {
// never gets here!
}
});
Try this
config: {
control: {
'enquiryindexview list': {
disclose: 'onDiscloseEnquiryIndex'
}
}
or this
config: {
refs: {
enquiryIndexViewRef: 'enquiryindexview list'
},
control: {
enquiryIndexViewRef: {
disclose: 'onDiscloseEnquiryIndex'
}
}
Hope this helps
What you might have missed doing is adding this line in the app.js
controllers: ['EnquiryIndex'],
Try this out, it should work now.

Events not caught by Controller

I am trying to respond to a view-fired event inside a controller. The event does fire, but the controller action is never called.
View:
Ext.define("MyApp.view.Dashboard", {
extend: 'Ext.Container',
xtype: 'my_dashboard',
config: {
items: [
{
xtype: 'dataview',
listeners: {
itemtap: function(sender, index, elem, record) {
// fires with param, e.g. 'inbox'
this.fireEvent(record.get('name'));
}
}
}
...
Controller:
Ext.define('MyApp.controller.Dashboard', {
extend: 'Ext.app.Controller',
config: {
control: {
'my_dashboard': {
'inbox': 'showInbox',
...
}
}
},
showInbox: function () {
/* never gets called */
},
...
What am I doing wrong?
UPDATE:
I found a solution, but it feels very hacky. I added a bubbleEvents config to the dataview and the my_dashboard view, and the events started making their way up to the controller.
Since the dashboard can have a variable number of items, I don't know which events I need to bubble up. Of course, I could bubble up all possible dashboard events, but that just seems like a massive kludge.
Should the view fire an application event instead, e.g. MyApp.app.fireEvent()?
I would put an itemId on the dataview.
itemId: 'my_dashboard_dataview'
Then in your controller...
control: {
'#my_dashboard_dataview': {
'itemtap': 'showInbox',
...
}
}
UPDATE
Here is some code that should get you started:
Controller:
Ext.define('MyApp.controller.Dashboard', {
extend: 'Ext.app.Controller',
config: {
control: {
'my_dashboard': {
painted: 'onDashboardPainted',
inbox: 'showInbox'
}
}
},
onDashboardPainted: function(dashboard, eOpts) {
dashboard.down('dataview').on('itemtap', function(sender, index, elem, record){
dashboard.fireEvent(record.get('name'));
//check the console to make sure you the value is: inbox
console.log(record.get('name'));
});
},
showInbox: function () {
console.log('showInbox init');
},
This is definately a scope issue... in your controller add a painted function for my_dashboard... the first function variable will be the my_dashboard component itself:
painted: function(dashboard,...
Now in the painted function add the listener dynamically:
dashboard.down('dataview').on( ... rest of listener code ...
Now inside of the listener do dashboard.fireEvent(....);
Sorry for the formatting im on my mobile, if u cant get it to work i will post code tomorrow

Sencha Touch 2: Call controller function from within Ext.Msg.confirm

I'm just getting started with Sencha Touch 2 and I have never worked with Sencha Touch 1.x before. I've just finished this tutorial (which is the best starter tutorial I have found so far) http://miamicoder.com/2012/how-to-create-a-sencha-touch-2-app-part-1/ and now I want to go ahead and extend this Notes App.
I have a controller and 2 views, a list view and an edit view. In the edit view I want to be able to delete the current record. The delete function is in the controller. After tapping the delete button, I want to show a confirmation dialog ("Are you sure you want to delete...?"). After the user presses yes, the delete function should be called.
Now my problem is: How do I call the controllers delete function from within Ext.Msg.confirm?
Here are the relevant snippets of my code. Please let me know if something important is missing.
Please see the "onDeleteNoteCommand" function. "this.someFunction" obviously doesn't work since "this" is a DOMWindow.
Ext.define('TestApp2.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
noteEditorView: 'noteeditorview'
},
control: {
noteEditorView: {
deleteNoteCommand: 'onDeleteNoteCommand',
}
}
},
onDeleteNoteCommand: function() {
console.log('onDeleteNoteCommand');
var noteEditor = this.getNoteEditorView();
var currentNote = noteEditor.getRecord();
Ext.Msg.confirm(
"Delete note?",
"Do you reall want to delete the note <i>"+currentNote.data.title+"</i>?",
function(buttonId) {
if(buttonId === 'yes') {
//controller functions!! how to call them?
this.deleteNote(currentNote);
this.activateNotesList();
}
}
);
},
deleteNote: function(record) {
var notesStore = Ext.getStore('Notes');
notesStore.remove(record);
notesStore.sync();
},
activateNotesList: function() {
Ext.Viewport.animateActiveItem(this.getNotesListView(), this.slideRightTransition);
},
slideLeftTransition: { type: 'slide', direction: 'left' },
slideRightTransition: { type: 'slide', direction: 'right' },
launch: function() {
this.callParent();
Ext.getStore('Notes').load();
console.log('launch main controller');
},
init: function() {
this.callParent();
console.log('init main controller');
}
});
When you enter callback function of Ext.Msg the scope changes from controller scope to global scope (window), so you must set up it as parameter of confirm method:
Ext.Msg.confirm(
"Delete note?",
"Do you reall want to delete the note <i>"+currentNote.data.title+"</i>?",
function(buttonId) {
if(buttonId === 'yes') {
this.deleteNote(currentNote);
this.activateNotesList();
}
},
this // scope of the controller
);
For more info please check sencha docs: http://docs.sencha.com/touch/2-0/#!/api/Ext.MessageBox-method-confirm

Sencha Touch 2.0 Controller can't handle clicks to my list

Hey guys i just started with sencha touch 2.0 and now i have a problem while using mvc in my project. I have a simple list and i want to open a detail view, with a tab on a list item. So i tried to tell my controller to handle clicks on this list but it doesn't work at all.
What am i doing wrong?
Here's my controller
Ext.define('MyFirstApp.controller.Main', {
extend: 'Ext.app.Controller',
views: ['Home', 'People'],
models: ['People'],
stores: ['Peoples'],
config: {
refs: {
people: 'peoplelist'
},
control: {
people: {
itemtap: 'testFunc'
}
}
},
testFunc: function() {
console.log("something was clicked");
}
});
'peoplelist' is the xtype of my list.
Thank you for your help :-)
Nothing wrong with the code you posted. It works fine with this List:
Ext.define('MyFirstApp.view.People', {
extend: 'Ext.List',
xtype: 'peoplelist',
config: {
fullscreen: true,
itemTpl: '{first} {last}',
store: 'Presidents'
}
});
It doesn't work if xtype is declared inside the config.
Yes, the way you are doing it is correct but you're not getting a reference to the list correctly.
Try this:
config: {
control: {
'peoplelist': {
itemtap: 'testFunc'
}
}
}
This video and code helped me a lot: http://learn.sencha.com/learn/meet-the-list-component/
Updated link: http://docs.sencha.com/touch/2.2.1/#!/video/list
You should have your people/itemtap event inside listeners (not control).
http://docs.sencha.com/touch/2-0/#!/guide/events