If I want to use the tester API, and use say assertSelectorExists, how can I waitFor a selector? I understand that you could use waitForSelector's onTimeout callback and manually create a message in there but it would seem to defeat the purpose of having the ability to assert...
Something like this?
casper.waitForSelector('#my-selector', function() {
this.test.pass('selector found');
}, function() {
this.test.fail('selector was not found');
});
Related
Template.temp.events({
"focusOut window" : function(){
console.log('exit window')
}
});
Like this focusOut window trigger code?
Not sure this will work as the template will only list to dom events inside its own scope.
Better to handle this using jquery and setup an event listener when the template is rendered.
Template.temp.onRendered(function() {
Meteor.setTimeout(function(){
$(window).blur(function() {
// Do something here....
$("title").text("Don't forget to read this..." + pageTitle);
});
}, 1000);
}
Something along these lines should work, its fragile... and may need some tweaking, but this should get you started.
I have a BackboneJS App where I fetch a bunch of collections. Now I want to apply some sort of loader to indicate that the collection is loading and the user gets to know that something is happening. So I want to use the .ajaxStart() and .ajaxStop()-method. So I was thinking about something like this:
this.artistsCollection.fetch(
$(document).ajaxStart(function () {
console.log('ajax start');
$('.someDiv').addClass('TEST');
}),
$(document).ajaxStop(function () {
console.log('ajax stop');
// stop doing stuff
})
);
Issue is that first time I trigger the .fetch() my console says ajax stop and the class is not applied!?!? Second time I trigger the .fetch() it works like it should and the class gets applied. Does anyone know whats the issue?
Please help anyone?
You're passing the returned result of adding the two event handlers with jQuery as parameters to the Collection fetch method. The Backbone Collection fetch method receives an options object which can include a success callback (see documentation).
I think if you move the listeners out of the method call it should work as you expect:
// Global AJAX listeners
$(document).ajaxStart(function () {
console.log('ajax start');
// do stuff
});
$(document).ajaxStop(function () {
console.log('ajax stop');
// stop doing stuff
});
this.artistsCollection.fetch();
I'm triyng to build a simple animation jQuery-plugin. The main idea is to take an element and manipulate it in some way repeatedly in a fixed intervall which would be the fps of the animation.
I wanted to accomplish this through events. Instead of using loops like for() or while() I want to repeat certain actions through triggering events. The idea behind this: I eventualy want to be able to call multiple actions on certain events, like starting a second animation when the first is done, or even starting it when one animation-sequence is on a certain frame.
Now I tried the following (very simplified version of the plugin):
(function($) {
$.fn.animation = function() {
obj = this;
pause = 1000 / 12; //-> 12fps
function setup(o) {
o.doSomething().trigger('allSetUp');
}
function doStep(o, dt) {
o.doSomething().delay(dt).trigger('stepDone');
}
function sequenceFinished(o) {
o.trigger('startOver');
}
function checkProgress(o) {
o.on({
'allSetup': function(event) {
console.log(event); //check event
doStep(o, pause);
},
'stepDone': function(event) {
console.log(event); //check event
doStep(o, pause);
},
'startOver': function(event) {
console.log(event); //check event
resetAll(o);
}
});
}
function resetAll(o) {
/*<-
reset stuff here
->*/
//then start over again
setup(o);
}
return this.each(function() {
setup(obj);
checkProgress(obj);
});
};
})(jQuery);
Then i call the animation like this:
$(document).ready(function() {
$('#object').animation();
});
And then – nothing happens. No events get fired. My question: why? Is it not possible to use events like this inside of a jQuery plugin? Do I have to trigger them 'manualy' in $(document).ready() (what I would not prefer, because it would be a completely different thing – controling the animation from outside the plugin. Instead I would like to use the events inside the plugin to have a certain level of 'self-control' inside the plugin).
I feel like I'm missing some fundamental thing about custom events (note: I'm still quite new to this) and how to use them...
Thx for any help.
SOLUTION:
The event handling and triggering actually works, I just had to call the checkProgress function first:
Instead of
return this.each(function() {
setup(obj);
checkProgress(obj);
});
I had to do this:
return this.each(function() {
checkProgress(obj);
setup(obj);
});
So the event listening function has to be called before any event gets triggered, what of course makes perfect sense...
You need set event on your DOM model for instance:
$('#foo').bind('custom', function(event, param1, param2) {
alert('My trigger')
});
$('#foo').on('click', function(){ $(this).trigger('custom');});
You DOM element should know when he should fire your trigger.
Please note that in your plugin you don't call any internal function - ONLY DECLARATION
Note: I'm a total ignoramus regarding javascript.
I've broken my ExtJS 4.1 MVC app out into several controllers like:
/app/controller/Auth
| |Quiz
| |Result
| |Blah...
|model/...
I want to respond to an "event", not a DOM Event, rather a Ext.form.action.Submit.success event by calling functions in both my Auth and Quiz controllers. The summarized code for the first part is here:
// File: app/controller/Auth.js
attemptLogin : function() {
var form = Ext.ComponentQuery.query('#loginpanel')[0].form;
if (form.isValid()) {
form.submit({
success : function(form, action) {
// THIS IS THE FUNCTION FROM THE CURRENT CONTROLLER
Assessor.controller.Auth.prototype.finishLogin();
// THIS IS THE FUNCTION FROM THE OTHER CONTROLLER
Assessor.controller.Quiz.prototype.setupAssessment();
},
This works but feels wrong. Is there a proper way to do this? It seems like I should fire a unique event that is listened to by both controllers, but I can't understand how to do that with Ext.Event. Any guidance?
Thanks! I'm really grateful for all the great ideas and advice.
It makes sense to me to fire a custom event from the form and simply listen to it in both your controllers, like what you said here:
It seems like I should fire a unique event that is listened to by both
controllers
// File: app/controller/Auth.js
attemptLogin : function() {
var form = Ext.ComponentQuery.down('#loginpanel').form;
if (form.isValid()) {
form.submit({
success : function(form, action) {
// fire the event from the form panel
form.owner.fireEvent('loginsuccess', form.owner);
},
Then in each of your controllers you can listen to it with Controller#control, like this:
Ext.define('YourApp.controller.Auth', {
extend: 'Ext.app.Controller',
init: function() {
var me = this;
me.control({
'#loginpanel': {
loginsuccess: me.someHandler
}
});
},
someHandler: function(form) {
//whatever needs to be done
console.log(form);
}
}
And then add the same thing to your Quiz controller:
Ext.define('YourApp.controller.Quiz', {
extend: 'Ext.app.Controller',
init: function() {
var me = this;
me.control({
'#loginpanel': {
loginsuccess: me.someOtherHandler
}
});
},
someOtherHandler: function(form) {
//whatever needs to be done
console.log(form);
}
}
I've used this approach successfully in 4.1.0 and 4.1.1
It really should be
Assessor.controller.Auth.prototype.finishLogin.apply(this, arguments)
or something along these lines (in order to have a correct this reference that points to the 'owner' of the method, the controller object)
However, why do you use this unorthodox way to call the current controller's method. Just set the scope for the success callback, then call this.finishLogin().
form.submit({
success : function(form, action) {
// THIS IS THE FUNCTION FROM THE CURRENT CONTROLLER
this.finishLogin();
...
},
scope: this
});
Also, you can retrieve another controller instance using Controller#getController.
this.getController('Assessor.controller.quiz').setupAssignment();
Then, if your controller methods are not depending on each other, you could make them both listen to the same event.
Another solution is to fire a custom event once the login is finished. You could do that on the application object
this.application.fireEvent('logincomplete');
and in your controller's init method:
this.application.mon('logincomplete', this.setupAssignment, this);
Please note that you cannot listen to those events via Controller#control - see Alexander Tokarev's blog post for a patch to Ext to achieve this.
There is no standard way to fire events between controllers, but it's possible with some custom hacks. See my recent blog post.
I have also been looking for this and all you need is Asanda.app.getController('quiz').setupAssignment();, where Asanda is the name of your app
You should use a MessageBus if you have to send events between controllers:
Ext.define('MyApp.utils.MessageBus', {
extend : 'Ext.util.Observable'
});
store the message bus in a global var
MsgBus = Ext.create('MyApp.utils.MessageBus');
Where you have to send events:
MsgBus.fireEvent('eventName',eventArg_1,eventArg_2);
Where you have to receive events:
MsgBus.on('eventName', functionHandler,scope); //scope is not mandatory
...
functionHandler:function(eventArg_1,eventArg_2){
...
//do whatever you want
...
}
In Metor 0.3.5, when all events were jQuery events, I was able to use use jQuery UI Draggable and then handle the drag & dragstop events using a Metor event map:
Template.game.events['dragstop .card'] = function (e) {
//stuff
};
But I just read this in the Meteor mailing list:
In 0.3.6, event maps no longer depend on jQuery
And sure enough, the above technique no longer seems to work – my dragstop handler isn't called at all now.
I'd greatly appreciate any advice as to how to achieve the same effect in 0.3.6.
Nowadays, you can simply use body events to accomplish this the "Meteor" way:
Template.body.events({
'dragstop #somedivid': function(e) {
// Do stuff
}
});
Custom jQuery events can be bound with plain old jQuery, bypassing event maps altogether:
$(function () {
$('body').on('dragstop', '.card', function (e) {
//stuff
});
});
Remember to use jQuery's on function to bind the handlers, since template elements are not necessarily included in the DOM at all times.