Fire event from hyperlink in Sencha Touch 2 - extjs

How would I fire an event (I am wanting to switch card views) from a plain old html link?
If I reference the link by ID in my controls section no event I tried (click, tap) seems to be triggered.
Thanks!

Once you render the link you can add event listener in this way:
Ext.get('[link id here]').on('click', function(){...}, this);
UPDATE
If you want to fire an event once user clicked on hyperlink, you can simply add this.fireEvent('[name of event here]'); but be aware of this keyword meaning in this function, so you'll have an ability to add listener to it properly... Does it make sense?

Add a click listener to the panel containing the link. In the example the tag has the 'link' class. You can substitute it by your own class/id, as it's done in jQuery.
listeners: {
scope: this,
itemtap: this.onItemtapAction,
click: {
element: 'el',
fn: function (e) {
if (e.getTarget('a.link')) {
// Switch cards here
}
}
}

I used simple Java Script to add a listener to the link.
First, I created an "activate" listener for the container component:
...
listeners: {
activate: function (newActiveItem, container, oldActiveItem, eOpts) {
this.onActivate(newActiveItem, container, oldActiveItem, eOpts);
}
}
...
And here is my function:
onActivate: function (newActiveItem, mainNavView, oldActiveItem, eOpts) {
var me = this;
document.getElementById('logOutLink').addEventListener("click",
function(){
me.onLogOut();
}, false);
},
onLogOut:function(){
alert('log out');
}

Related

Where to use listeners and where to use controller - Sencha Touch 2

I am confused between the proper usage of Listeners vs Controllers
E.g. for the same button, I can make the handler for the button-tap event in the button description itself as :
Ext.Viewport.add({
xtype: 'button',
centered: true,
text: 'My Button',
listeners: {
tap: function() {
alert("You tapped me");
}
}
});
and also as in a separate controller as below.
Ext.define("NotesApp.controller.Notes", {
extend: "Ext.app.Controller",
config: {
refs: {
newNoteBtn: Get reference to button here
},
control: {
newNoteBtn: {
tap: "onNewNote"
}
}
},
onNewNote: function () {
console.log("onNewNote");
}
});
What is the best practice, and are there trade-offs?
Thanks
To controller or not to controller, that is the question.
Well, technically, nothing would prevent you from doing one or the other. I have established a way how to decide for myself:
I install listeners on view if the job they are doing does not cross boundaries of the view. If we take form as an example, disabling and enabling, showing and hiding of fields, if it depends only on the state of the form stay within the form - no controller.
I delegate the logic to a controller if the action in one view (a button click, for example) influences another view or the whole application.
Again, these are my preferences, you can have another.

how to add click event for panel and listen to it in controller with panel as argument

I am dynamically adding panels to my container, once all the panels are added i want to have click event for the panels and listen to the event in one of the controller with the panel clicked being the argument.
I have the following code for adding the click event.
'#productListPanel': {
afterrender: this.onProductPanelAfterRender,
},
onProductPanelAfterRender: function(panel) {
panel.mon(panel.el, 'click', this.onProductPanelClick);
},
onProductPanelClick: function(a,b) {
console.log("a");
console.log(a);
console.log("b");
console.log(b);
},
It works fine and adds the click event, but i am not able to determine which panel is being clicked.
can somebody please help me out.
Thanks
When you add dynamically a panel to your container, you can add a listener into your panel definition :
listeners: {
'render': function(panel) {
panel.body.on('click', function() {
nameOfYourApp.app.fireEvent('ClickPanel',panel);
});
}
}
Fire an event when the panel is clicked and listen this event into your controller.
You can add this code into the init function of your controller :
this.application.addListener({
'ClickPanel':this.clickPanel
});
and add the function "clickPanel" into your controller :
clickPanel:function(panel){
// Your code
}
hope this can be helpful for your problem!
If you wanted to do it after the panel is rendered you can use the following. This assume myPanel is a reference to your panel.
myPanel.getEl().on('click',
function(){
alert('Panel Clicked');
}
);

How do I add elements to an ExtJS component tpl so that I can refer to them in a listeners config

I can add a listener to the 'el' element of a component like this:
Ext.widget('component',{
listeners: {
click: {
element: 'el', //bind to the underlying el property on the component
fn: function(){ console.log('you clicked the el'); }
}
}
}
But I want to add more elements to this component's tpl and listen for clicks on them. In place of 'el' in the example above, I want to use a custom element 'awesomelink'. How do I reference elements in the tpl from the listeners config?
Here's an unfinished example:
Ext.widget('component',{
tpl : '<div>{content}<a class="awesomelink">click this awesome link</a></div>',
data:{content:'something'},
listeners: {
click: {
element: 'awesomelink', // this doesn't mean anything
fn: function(){ console.log('you clicked the awesomelink'); }
}
}
}
I assume I need an awesomelink property on the component - but how would that relate to the tpl?
Use event delegation:
listeners: {
afterrender: function(c) {
c.getEl().on('click', function(e, t) {
console.log(t);
}, null, {delegate: '.awesomelink'});
}
}
The element config expects the name of a property on the component which contains a reference to a DOM element, where you want to add your listener (refer to the docs).
That's why you can use "el", since all components have this property, but not "awesomelink" (unless you add that property yourself).
However, the click event on the component's underlying element will also fire if you click on child nodes of that element, so you could just check if the target element is your link in the listener:
listeners: {
click: {
element: 'el',
fn: function(e, t) {
if (Ext.get(t).hasCls('awesomelink')) {
console.log('you clicked the awesomelink');
}
}
}
}

How to listen for dom events in ExtJS

I've to use html sometimes in ExtJS code, but how to listen for dom events in extjs? I know i can listen them but in this way i have to use global functions.
Here is what i've done already:
<a title="click on me" href="javascript:abc();">' + value+ '</a>
Instead of firing event from tag, attach event this way:
var domElement = document.getElementsByTagName("a");
domElement.on('click', function(event, element, options) {
});
Not every ExtJS component raises every event. However, by targeting the container’s element, you can attach many native events to which the component can then listen. You must target the underlying element you want to listen and attach a click listener. The config should look something like this:
listeners: {
click: {
element: 'el', //bind to the underlying el property on the panel
fn: function() {
console.log('Element was clicked!');
}
}
}
http://docs.sencha.com/extjs/4.2.5/#!/api/Ext.util.Observable-cfg-listeners

Is there really no click event for all ExtJS components

I'm learning extjs 4.1 and I can't find click event on most of the components - I'm I blind or I'm unable to react on click on other components than button?
What is the reason? HTML supports click on all elements.
Every component can have the click event exposed at the element level. Some components like Ext.button.Button have a click event at the component level.
Here is a nice way to add a click event on a panel:
new Ext.panel.Panel({
listeners: {
click: this.handlePanelClick,
element: 'el'
}
});
edit to respond to comment
The element string is a any element that is a property of the component.
new Ext.panel.Panel({
listeners: {
click: function() {
alert('you clicked the body');
},
element: 'body'
}
});
The Ext docs have a more thorough explanation http://docs.sencha.com/ext-js/4-1/#!/api/Ext.util.Observable-method-addListener
You can add any DOM event pretty easily by accessing the Ext.dom.Element object that almost all visible components contain once it has been rendered.
Simply add a listener to the afterrender event that adds the event you want to the dom object.
Ext.create('Ext.panel.Panel', {
// other panel configs ...
listeners: {
'afterrender': function(panel) {
panel.el.on('click', function() {
alert('clicked');
});
}
}
});
I think there is also a way to do it for all components of a class that extends Ext.util.Observable (all visible components). I haven't done it before so you would have to play around with that.
Using a self-referencing managed listener (cleanest imo):
Ext.create('Ext.panel.Panel', {
listeners: {
'afterrender': function(panel) {
this.mon(this.getEl(), 'click', this.onClick, this)
}
},
onClick: function() {
alert("mmm mon mon mon");
}
});
If you are only listening to click event you can also do this
xtype: 'container',
listeners: {
el: {
click: function() {
alert('I clicked');
},
scope: this
}
}
If you need to listen to an event that the Ext.dom.Element does not fire, you will need to attach it in the 'render' listener, like others have suggested.

Resources