So I've got a jquery project where I'm using an external class that has callback style events.
Meaning, it has an "onSave" property that takes one function. However, I need to more than one other components to hook into it.
What I've settled on for now, goes like this:
var saveCallbacks = $.Callbacks();
saveCallbacks.fire.callbacks = saveCallbacks;
globalDoodad.onSave = saveCallbacks.fire;
which allows me to do this in my other components:
globalDoodad.onSave.callbacks.add( myMethod );
Is there a better way to handle this? It seems to be working ok, just has a bit of a smell to it.
Related
There is a widget in the POS(point of sale) called PaymentScreenWidget and inside that there's a customer_changed method which is called when the customer is changed.
Suppose that I want to call a method after this method is called then how can I do this without interfering with this code?
Interfering with this code leaves a lot of trouble in many case so are there any ways to achieve this?
I want to append some text to it but since there are many module who try to change those code or override it I want to avoid doing it and try to call my method after that method has been called.
You'll have to do some code instrumentation.
For example,
let old_customer_changed = customer_changed;
customer_changed = function(){
// my awesome code
old_customer_changed();
}
You'll have to implement similar thing in whatever modules you are using.
I am trying to find the event DOM target when there are nested jQuery calls. If there was only one level of call, then event.target would get the DOM target and I could go from there. But how to get through nested calls?
I am testing with a Javascript function
jQuery(document).bind('gform_post_render', function(event, formID){
jQuery("#id").val(event.target.nodeName);
});
I can look at event.target.nodeName and see that it is "#document". I assume that is because the trigger which called this function was something like
jQuery(document).trigger('gform_post_render', ...);
And I think there is another level or two of calls above that.
What I'd like to be able to do is something like
event.trigger.event.trigger.closest(.classname).attr("attname");
although I realize that 'event.target.event.target' is not allowed.
Is there any way to do this?
BTW, what I am trying to do is extract a piece of data from the HTML that is going though a couple of WordPress plugins (popup and gravity forms) that do the jQuery calls. So I have no ability to change things, just trying to deal with what they did.
You can pass a data argument to trigger, and then access it within the handler. So you pass it like this:
$(document).trigger('gform_post_render', {target: event.target});
and then in the handler:
$(document).on('gform_post_render', function(event, data) {
var target = data.target;
...
});
I'm working with a 3rd party product where I am extending the UI with my own custom functionality. Within part of that I need to call an event after the UI has been updated with an AJAX call. Luckily the app fires a call to a Custom Event using the Prototype JS library after the call is complete, like this:
$(document.body).fire("ns:customevent");
If I add my own custom event with the same name then this works as expected
$(document).observe("ns:customevent", function(event) {
//do custom stuff here
});
[I could not get $(document.body).observe() to work here but I don't think that really matters.]
My concern here is that there may be other parts of the app that have registered functions against that event, and I am (blindly) overwriting them with my own, which will lead to issues further down the line.
Does Prototype append custom functions even though they have the same name or does it in fact overwrite them? If it does overwrite them then how can I append my function to anything that is already existing? Is there anyway of viewing what
I would imagine something like this, but I hardly know Protoype and my JS is very rusty these days.
var ExistingCustomEvent = $(document.body).Events["ns:customevent"];
$(document).observe("ns:customevent", function(event) {
ExistingCustomEvent();
//do custom stuff here
});
I can't add my event handler or add in code to call my own function, I want to try avoiding the 3rd party library (if that would even be possible).
Thanks.
As an FYI for anyone else that stumbles upon this question, following the comment from Pointy it turns out that Prototype does append the functions to the custom event.
I verified this by trying the following and both alerts fired.
$(document).observe("ns:customevent", function(event) {
alert("ALERT 1");
});
$(document).observe("ns:customevent", function(event) {
alert("ALERT 2");
});
Great :)
I want to know when a DOM element generated by Ractive is ready. In my case, I want to use jquery to attach an autocomplete function onto the element. Ideally it would go something like this:
Template:
{{#list}}
<input type="text" proxy-load="attach-typeahead">
{{/list}}
Javascript:
ractive.on("attach-typeahead", function(event){
$(event.node).typeahead(...);
})
But the event never fires even though I remeber seeing proxy-load mentioned somewhere in the documentation. What's the proper way to do what I'm trying to do? Thanks.
Codler's answer is spot on - transitions can be used to attach behaviour to nodes (and detach it, with outro).
As of the latest (0.3.8) version, there's another method, which behaves similarly but is slightly more streamlined for this purpose: decorators.
The documentation hasn't been written yet (my bad), but you can see a typeahead decorator here. A decorator is simply a function that gets called as soon as a node is added to the DOM, and which returns an object with a teardown() method that gets called as soon as the node is removed from the DOM.
You can make a decorator globally available like so:
Ractive.decorators.foo = function ( node ) {
// do some setup work with the node here...
return {
teardown: function () {
// do any necessary cleanup here
}
};
};
Or you can specify per-instance decorators, as in the fiddle.
Another decorator example here, this time a sortable list.
The proxy-events are mentioned here in the documentation of ractive. Your example doesn't work because the input element does not have a native load event.
All the ractive functions have a complete function callback that fires when the rendering has completed. Maybe you can use that.
You can use the intro attribute. It is a transition in ractive. When the DOM are created, intro will be called.
You can find more info here https://github.com/RactiveJS/Ractive/wiki/Transitions
I'm working on a project in JavaScript where we're building a Greasemonkey plugin to an organizational site we're using in our office. We're having trouble getting our changes to stay rendered, since we can't simply inject our changes into the existing render function.
As a result, we need to find every event where rendering happens and inject our own render function there. However, there are some events that we can see happening, but we can't hook into them. What I'd like to know is how to bind a function to an object's data member, so that the function is called whenever that member changes. One of our team members seemed to think it was possible, but the method he told us to use didn't seem to work.
What we tried was something along the lines of
window.Controller.bind("change:idBoardCurrent", OMGITWORKED);
where idBoardCurrent is a member of window.Controller and OMGITWORKED is the function we'd like to be called when window.Controller.idBoardCurrent is changed.
I'm not very familiar with JavaScript or data binding, so I have no idea if this is right or wrong, or what is correct or incorrect about it. If someone could point out what to change in this snippet, or if they could suggest another way to go about this, I would be very appreciative.
You can use Object.defineProperty to define a setter and getter for the Objects property
Object.defineProperty(window.Controller,"idBoardCurrent",{
get : function() { return this.val; },
set : function(value) {this.val = value;OMGITWORKED(value); }
});
function OMGITWORKED(param) {
console.log("idBoardCurrent has been Changed to " + param);
}
window.Controller.idBoardCurrent = "Test";
window.Controller.idBoardCurrent = "Test2";
console.log(window.Controller.idBoardCurrent)
Edit: changed the code according to the contexts object
JSBin
As this is specifically Firefox, you can use the mutation events it provides. But note the caveats on them from that page:
The W3C specification for them was never widely implemented and is now deprecated
Using DOM mutation events "significantly degrades" the performance of DOM modifications
If you're able to restrict yourselves to Firefox 14 and higher, you can use the new mutation observers stuff instead.
This is, when I am not totally wrong, more a question of javascript.
I found some information about that topic
Listening for variable changes in JavaScript or jQuery
jQuery trigger on variable change
Javascript Track Variable Change
Sorry when I didn't understand the topic.
All the best