Sencha touch 2 conflicting listeners - sencha-touch-2

I have listeners for html code in the following style:
listeners : {
tap: {
fn: function(e, del, sender) {
console.log("you pressed A!");
},
element : 'element',
delegate : '.a'
},
tap: {
fn: function(e, del, sender) {
console.log("You pressed B!");
},
element:'element',
delegate : '.b'
}
}
Within listeners they both conflict and only the second one will be attached. Both of them use the name 'tap' in the same object for listeners so I assume this is the reason,
How would I fix this? (Btw this is abridged I have a couple of keyups there too), I can't attach directly to the elements because they're listeners for html code.

listeners:{
tap: function(list, index, target, record, e, eOpts){
var elm = Ext.get(e.target);
if(elm.dom.className == "a"){} // or any other thing you want to check
}
}
you can console it to see more info on it you can also do elm.dom.id

Related

Correct way of attaching 'disclose' (or any other) event handler in Sencha Touch

In my simple application I'm listening for the disclose event like this :
In the NotesList.js (view) file...
Ext.define("NotesApp.view.NotesList", {
extend : "Ext.dataview.List",
xtype : "noteslist",
...
config : {
onItemDisclosure : true, //adds the disclose arrow
}
});
NotesList is used in NotesListContainer which is an Ext.Container.
Then in NotesListContainer.js (view) ...
var notesList = {
xtype : "noteslist",
...
listeneres : {
disclose : { fn : this.onNotesListDisclose, scope : this }
}
};
this.add([topToolbar, notesList]);
The function does this :
onNotesListDisclose : function(list, record, target, index, evt, options) {
console.log(' onNotesListDisclose() called'); //nevers gets logged
this.fireEvent('editNoteCommand', this, record);
}
Then in Notes.js (controller) :
refs : {
//get elemets using xtype attr
notesListContainer : "noteslistcontainer",
noteEditor : "noteeditor"
},
//handlers for events
control : {
//define which events should this controller respond to
notesListContainer : {
//events fired by NotesListContainer
newNoteCommand : "onNewNoteCommand",
editNoteCommand : "onEditNoteCommand"
}
}
},
//Event/Command handler
onEditNoteCommand : function(list, record) {
console.log(' onEditNoteCommand called ');
this.activateNoteEditor(record);
}
I think the problem is in NotesListContainer.js where I am instantiating the list.
If I listen for the event in controller like this :
refs : {
//get elemets using xtype attr
notesListContainer : "noteslistcontainer",
notesList : "noteslistcontainer list",
},
//handlers for events
control : {
//define which events should this controller respond to
notesListContainer : {
//events fired by NotesListContainer
newNoteCommand : "onNewNoteCommand",
//editNoteCommand : "onEditNoteCommand"
},
notesList : {
disclose : "onEditNoteCommand" //adding it this way works...
}
}
It works just fine. However, I would prefer to work with a more application specific event instead of very generic disclose event.
I am new to sencha touch, any help is appreciated.
If you want to have your own custom business logic driven events, do the following:
Subscribe to necessary UI events in your main controller
Generate application wide business events
Subscribe to these events in your view controller
what you mean with 'a more application specific event'?
The disclose event is a list-component specific one:
http://docs.sencha.com/touch/2.2.1/#!/api/Ext.dataview.List-event-disclose

Sencha Touch FireEvent from view is not being received in Controller

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...

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

How do I get a Sencha controller to respond to a swipe event in a view?

I have a dataview that I would like to detect a swipe on. It'd be great if I could listen for that in the controller, but as far as I understand I can't do that. My testing bears this out. So instead I need to listen in the view for the event. Currently I'm doing that in the initialize method of my data view like so:
initialize: function() {
var el = Ext.get("list");
el.on('swipe', function(event) {
alert(event.direction);
});
}
So a couple of things:
Is my understanding correct, that I have to listen for DOM events like this in the view?
Is this the best way to set the swipe listener on the dataview? I couldn't seem to make it work through the config object.
How do I then let my controller know about the swipe? It will need to manipulate the view when the swipe happens (like change the view size). What are the best practices in this area?
Thanks in advance.
It is always better to put the events for a component inside the controller. So, first create a ref for that dataview in your controller.
refs : {
listView : 'list' //Or a selector to get the reference
},
control : {
listView : {
// Dataview has an "itemswipe" event - not "swipe" event
itemswipe : function(dataview, index, target, record){
//Do here what you want
}
}
}
This should work (not tested).
I think this is what you are after, its the same idea just changing the scope to the controller:
Ext.define('app.controller.myListControler', {
extend: 'Ext.app.Controller',
config: {
refs: {
list: { selector: 'myList', autoCreate: true, xtype: 'myList' }
}
},
init: function () {
},
launch: function () {
this.getList().on('swipe', this.onSwipe);
},
onSwipe: function (event) {
console.log(event.direction);
}
}