Is there a way to bind more than one event/class to a function in meteor template events map?
Something like this:
Template.template_name.events(
{
'click .class1 .class2 h1': function (event, template)
{
alert("click");
}
}
doesn't work
According to my experience with meteor, the correct syntax is :
Template.templateName.events({
"event1 cssSelector1, ..., eventN cssSelectorN":function(event,template){
}
});
Warning : the space between the comma and the next event DOES matter.
So in your example, you might come up with something like :
Template.template_name.events({
"click .class1, click .class2, click h1":function(event,template){
}
});
Related
I want to be able to set/get data of a template object when using template event handler functions. I have tried to set a variable at the point when the template is rendered and hoped it would be accessible later on, in this case when an element in the template is clicked by the users, but it isn't working:
<template name="fooBar">
<div class="some_element">CLICK ME</div>
</template>
Template.fooBar.rendered = function(){
this.templateVar = "Hello";
}
Template.fooBar.events({
'click .some_element': function(e,t){
alert(this.templateVar); // Should say 'Hello', but is 'undefined'.
}
});
Using reactive-dict package, you can do like this.
First add it.
meteor add reactive-dict
Second create the templates. (note im using meteor 1.1 version)
if (Meteor.isClient) {
Template.hello.onRendered(function(){
this.templateVar = new ReactiveDict(); //create the var templateVar
})
Template.hello.onRendered(function(){
this.templateVar.set("hi", "hello"); //give them a value
})
Template.hello.events({
'click .some_element': function(e,t){
console.log(t.templateVar.get('hi')) //and print the value using the template instance.
}
});
}
As per the suggestion given by Sindis, this is the quickest way to solve the issue:
Instead of...
alert(this.templateVar);
... just do...
alert(this.templateVar); or alert(Template.instance().templateVar);
I need to add a webkitTransitionEnd event listener to one of the DOM elements in my EmberView.
This javascript (DOM) equivalent would be:
function transitionEnded() {
console.log("transition ended");
}
document.getElementById('foo').addEventListener(
"webkitTransitionEnd",
this.transitionEnded,
true);
I've tried the following:
var MessageView = Ember.View.extend({
...
transitionEnded: function() {
console.log("Transition Alert!");
},
actions: {
closeMessageWithTransition: function(){
var elem = document.getElementById('transitionThis');
elem.addEventListener(
"webkitTransitionEnd", this.transitionEnded, true);
// Trigger the transition here
}
...
I've also tried using:
this.$("#transitionThis").get(0).addEventListener(...);
instead of using:
var elem = document.getElementById('transitionThis');
elem.addEventListener(...);
but to no avail. The transition happens, but I do not get any events nor do I see errors in the console.
I can confirm that the document.getElementById method selects the right element. So, where are my event handlers going?
EDIT 1: Didn't realize there was an emberjs.jsbin.com. So, here you go:
Emberjs.jsbin
PS: I do realize that the element I'm attaching a listener to ends up getting destroyed later when in transitionTo('messages') but I've commented out that bit and still no effect.
EDIT 2: I've added an alternate method of trying to catch the event using an EventManager as outlined in the Ember.View docs.
Alternate Method
It looks like it's using animation, not transition, webkitAnimationEnd is the appropriate hook.
http://emberjs.jsbin.com/awEWUfOd/4/edit
I'm trying to display a simple template, but it seems like the template doesn't get added, as there is nothing added to the DOM. The code is called for sure and a container has the method setTpl(tpl). What am I doing wrong? The sample above is the most simple example I could imagine, but it doesn't work!
Ext.define('MyApp.view.sample', {
extend: 'Ext.Container'
config: {},
initialize: function() {
this.callParent();
var sampleText = '<div> why?? </div>';
var t = new Ext.Template(
sampleText,
{
compiled: true
}
);
t.compile();
this.setTpl(t);
},
});
HTML = template + data. So your next step is to call setData. Check the docs for tpl. If what you want is to plug in some raw HTML that doesn't depend on data, you've got the html config (and the corollary method setHTML). Last advice, if that's just for rendering some HTML, you don't need to use a container, a Component would be enough.
You have created a class, but you also need to instantiate it. Try something like this:
Ext.create('MyApp.view.sample', {
renderTo: 'some-div-id',
// any other necessary config options
// (see http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.Container)
});
I am designing a SaaS application and have been directed to Backbone.js. The service in part tracks DOM events such as how many of each have occurred and then applies scores based on this information.
Decoupling data into Models and Collections is very appealing, but before I go any deeper I want to enquire as to whether it is the right tool for the job.
I want to work with existing DOM elements written in the HTML of a site owners page rather than create JavaScript templates. I will therefore be tracking DOM events on existing elements which then update the data model. The site owner making use of the service will then be able to use the data in the Model to create their own Views and render their own templates specific to their needs.
I understand that I will need to use Backbone.View to track the events, and from what I have read so far it seems Backbone has the flexibility to allow this. However, I haven’t seen any examples in my research of Backbone used to track a bunch of events on a number of form elements.
Take this code for example:
App.Models.Event = Backbone.Model.extend({
defaults: {
clicks: 0,
dblClicks: 0,
tabs: 0,
kbdFunctions: 0
},
urlRoot: 'events'
});
App.Views.Event = Backbone.View.extend({
model: new App.Models.Event(),
events: {
'click input' : 'clickCount',
'dblclick input' : 'dblClickCount',
'tabEvent input' : 'tabCount',
'kbdEvent input' : 'kbdEventCount'
},
initialize: function () {
this.el = $('[data-transaction=start]');
},
clickCount: function (e) {
console.log('click counted');
},
dblClickCount: function (e) {
console.log('double click counted');
},
tabCount: function (e) {
console.log('tab counted');
},
kbdEventCount: function (e) {
console.log('keyboard event counted');
}
});
I want to be able to track clicks, double clicks, tabs and other custom keyboard events that occur on input, textarea, select options and button that are contained within the [data-transaction=start] element. Firstly, is this an applicable use case for Backbone, and secondly, if so what is the best way of adding multiple elements within the Backbone.View events object literals? I haven't seen any examples of this in the documentation or anywhere else, but it would be good if I could add a variable into this like:
...
var someVariable = input, textarea, select, button;
events: {
'click someVariable' : 'clickCount',
...
Events are assigned by Backbone using the delegateEvents method in view. This method is called AFTER your view initialize method (code reference)
so you could pass your variables in view constructor
myView = new App.Views.Events ( someVariable )
in your initialize method, you can assign events:
initialize: function(someVariable) {
//assign this.events from someVariable as you would like
}
EDIT:
just read in Backbone documentation:
The events property may also be defined as a function that returns an
events hash, to make it easier to programmatically define your events,
as well as inherit them from parent views.
I am trying to inject another component into an element that is rendered by the template of another Coomponent..but in the afterrender event, the template is yet to be rendered so the call to Ext.get(el-id) returns null: TypeError el is null.
tpl:
new Ext.XTemplate(
'<tpl for=".">',
'<ul>',
'<li class="lang" id="cultureSelector-li"></li>',
'</ul>',
'</tpl>'
),
listeners: {
afterrender: {
fn: function (cmp) {
console.log(Ext.get('cultureSelector-li')); // < null :[
Ext.create('CultureSelector', {
renderTo: 'cultureSelector-li'
});
}
}
},
So when can I add this component so that the element is targeting has been created in the DOM?
I think it depends on the component that you are working with. For example, the Data Grid View has a "viewready" event that would suite your needs, and depending what you are attempting, the "boxready" function could work for combo box (only the first render though). Other than that, you can either go up through the element's parent classes searching for the XTemplate render function being called (might be in the layout manager) and extend it to fire an event there, or risk a race condition and just do it in a setTimeout() call with a reasonable delay.
I ended up having to do the work myself. So, I now have the template as a property called theTpl, and then rendered it in beforerender, and then i was able to get a handle on the element in afterrender. This seems wholly counter-intuitive, does anyone have any insight?
beforeRender: {
fn: function (me) {
me.update(me.theTpl.apply({}));
}
},
edit in fact I just extended Component thus:
Ext.define('Ext.ux.TemplatedComponent', {
extend: 'Ext.Component',
alias: 'widget.templatedComponent',
template: undefined,
beforeRender: function () {
var me = this;
var template = new Ext.XTemplate(me.template || '');
me.update(template.apply(me.data || {}));
me.callParent();
}
})
...template accepts an array of html fragments
Turns out I was using the wrong things - apparently we should be using the render* configs for this type of thing (so what are thetpl & data configs for?)
Here's a working fiddle provided for me from the sencha forums:
http://jsfiddle.net/qUudA/10/