How can I make a function act like a callback - javascript

How can I make shwOpts.show("fast"); to act when removeHighlight() is done?
I thought if I put an anonymous function as an argument in the other it will act as a callback. This didn't work.
removeHighlight : function(f) {
// remove previous highlight.
var highlight = $('#openid_highlight');
if (highlight) {
highlight.replaceWith($('#openid_highlight a')[0]);
}
},
moreOptsLink = $("#more-options-link").click(function () {
moreOptsLink.detach();
openid.removeHighlight(function(){$("#show-more-options").show("fast");});
//shwOpts.show("fast");
openid.setPref("showMoreOpenIdOptions", !0)
});

You're not executing the callback function
removeHighlight : function(f) {
// remove previous highlight.
var highlight = $('#openid_highlight');
if (highlight) {
highlight.replaceWith($('#openid_highlight a')[0]);
}
if (typeof(f) === "function") {
f();
}
},

You should call the callback in the removeHighlight function like this:
removeHighlight : function(f) {
// remove previous highlight.
var highlight = $('#openid_highlight');
if (highlight) {
highlight.replaceWith($('#openid_highlight a')[0]);
if( typeof f === 'function' ) {
f();
}
}
},
moreOptsLink = $("#more-options-link").click(function () {
moreOptsLink.detach();
openid.removeHighlight(function(){
$("#show-more-options").show("fast");
});
openid.setPref("showMoreOpenIdOptions", true);
});
By using typeof control, you don't take any error when you don't pass a function as parameter to the function.

removeHighlight : function(f) {
// remove previous highlight.
var highlight = $('#openid_highlight');
if (highlight) {
highlight.replaceWith($('#openid_highlight a')[0]);
}
//you need to call f
f()
},

Related

Passing value from one callback to another callback

I created the following plugin that mostly works. It takes xeditable, but allows for jQueryUI's autocomplete to select the value. It mostly works, however, I am struggling on how to pass the returned id from jQueryUI Autocomplete to the success callback.
How do I pass a value from the jQueryUI autocomplete select callback to the xeditable success callback?
EDIT. I got it working, but think it is a bit of a kludge. What is the proper way to do so?
EDIT #2. See https://jsfiddle.net/fndnu5m0/5/ for a demo.
$('#targetID').xeditableAutoSource({
source: 'getSource.php',
success: function(response, newValue) {
console.log($(this).data('uid')); //This is the value I want!
}
});
(function($){
var defaults = {
source: [], //Replace with URL
placement: 'right',
title: 'XEditable Title',
success: function(response, newValue) {} //id will be $(this).data('uid')
};
var methods = {
init : function (options) {
var settings = $.extend({},defaults, options || {});
this.each(function () {
var $this=$(this).editable({
//send:'never',
placement:settings.placement,
title:settings.title,
success: settings.success
})
.on('shown', function(e, editable) {
var $input=editable.input.$input.val('');
var $button=$input.parent().next().find('button.editable-submit').css('opacity', 0.3)
.bind('click.prevent', function() {return false;});
$input.focus(function() {
$button.css('opacity', 0.3).bind('click.prevent', function() {return false;});
})
.autocomplete({
source: settings.source,
select: function(e, ui) {
$input.blur();
$button.css('opacity', 1).unbind('click.prevent');
$this.data('uid',ui.item.id); //This is the value I need in the success callback!
}
})
.autocomplete('widget').click(function() {return false;});
});
})
},
destroy : function () {
return this.each(function () {
return this.each(function () {});
});
}
};
$.fn.xeditableAutoSource = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || ! method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.xeditableAutoSource');
}
};
}(jQuery));
Too much code... As far as I understood you want to pass to a function not just a callback but also its parameter. You can try the following technique:
var f1 = function(callback) { //we will pass a callback to this function
callback()
}
var f2= function(param1) { //that will be our callback
console.log(param1)
}
var p = 'Callback will always be called with this parameter'
f1( function() { f2(p) } ) //here we pass f2 with p as a callback to f1
Callback and it's parameter are wrapped into anonymous function. 'f1' and 'f2' are the functions from you libraries, you don't have to modify them, they are needed to illustrate the technique.
With some minor changes you can make it work if a function that accepts a callback passes some other parameters to it:
var f1 = function(callback) {
var p1 = 'Parameter set by f1'
callback(p1)
}
var f2= function(param1, param2) {
console.log(param1 +' '+ param2)
}
var p = 'Constant parameter'
f1( function(p1) { f2(p1, p) } )

jQuery: add callback function to another function

So I have this function
$.fn.myFunction = function( options, callback ) {
var settings = $.extend({
opacity : '',
margin : ''
}, options );
}
and I do some funny stuff like this
$('.selector').myFunction( options, function() { /* do some stuff */ } );
Where should I specify inside my function about the callback function and how?
Like this :
JS
$.fn.myFunction = function( options , callback ) {
var settings = $.extend({
opacity : '',
margin : ''
}, options );
// where you want your callback
if(callback && typeof callback === "function") callback();
}
A callback is simply a parameter in a function. So, your case could be expressed very simply:
var myFunction = function(options, callback) {
console.log('I am running in the main function');
if (callback) { callback(); }
};
myFunction('', function() {
console.log('I am running in the callback!');
});
Demo is here: http://repl.it/0b0

String to jQuery function

Overview
I am trying to find the jQuery function that matches a selection attribute value and run that function on the selection.
Example.
$('[data-store="' + key + '"]').each(function() {
var $callback = $(this).attr('data-filter');
if($callback != null) {
var fn = window['$.fn.nl2br()'];
if(jQuery.isFunction(fn)) {
$(this).fn();
}
}
$(this).setValue(value);
});
Problem 1
I'm not sure how to create a jQuery function call from string.
I know I can call the function like this, $(this)'onclick'; however I have no way to check if it exists before trying to call it.
Normally I could do this:
var strfun = 'onclick';
var fn = body[strfun];
if(typeof fn === 'function') {
fn();
}
This seems to fail:
var fn = window['$.fn.nl2br()'];
if(jQuery.isFunction(fn)) {
$(this).fn();
}
EDIT:
I seem to be having success doing this:
if($callback != null) {
var fn = $(this)[$callback]();
if( typeof fn === 'function') {
$(this)[$callback]();
}
}
Problem 2
Using jQuery.isFunction() how do you check if a methods exists? can you do this with jQuery.isFunction()?
Example
Declare function:
$.fn.nl2br = function() {
return this.each(function() {
$(this).val().replace(/(<br>)|(<br \/>)|(<p>)|(<\/p>)/g, "\r\n");
});
};
Test if function existe, these options fail:
jQuery.isFunction($.fn.nl2br); // = false
jQuery.isFunction($.fn['nl2br']()); //false
Functions in JavaScript are referenced through their name just like any other variables. If you define var window.foobar = function() { ... } you should be able to reference the function through window.foobar and window['foobar']. By adding (), you are executing the function.
In your second example, you should be able to reference the function through $.fn['nl2br']:
$.fn.nl2br = function() {
return this.each(function() {
$(this).val().replace(/(<br>)|(<br \/>)|(<p>)|(<\/p>)/g, "\r\n");
});
};
console.log(jQuery.isFunction($.fn['nl2br']));
See a working example - http://jsfiddle.net/jaredhoyt/hXkZK/1/
var fn = window['$.fn.nl2br']();
and
jQuery.isFunction($.fn['nl2br']);

Trying to understand this code (pub/sub library)

This is Peter Higgins's pub sub library: https://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js
(function (d) {
var cache = {};
d.publish = function (topic, args) {
cache[topic] && d.each(cache[topic], function () {
this.apply(d, args || []);
});
};
d.subscribe = function (topic, callback) {
if (!cache[topic]) {
cache[topic] = [];
}
cache[topic].push(callback);
return [topic, callback];
};
d.unsubscribe = function (handle) {
var t = handle[0];
cache[t] && d.each(cache[t], function (idx) {
if (this == handle[1]) {
cache[t].splice(idx, 1);
}
});
};
})(jQuery);
I don't understand the logic and the functionality of publish:
cache[topic] && d.each(cache[topic], function () {
**this.apply(d, args || []);** //what is happening here?
});
What is the purpose of this part? except the fact that it publishes the event
In this context, the && is used as a shorthand for:
if (cache[topic]) {
d.each(cache[topic], function() { … });
}
This is because && (and ||) are short-circuiting, so if the left hand side evaluates to a false-ish value (or true-ish value, in the case of ||), the right hand side does not get evaluated.
For example:
> function foo(result) { console.log("foo"); return result; }
> function bar(result) { console.log("bar"); return result; }
> foo(false) && bar(true);
foo
false
Basically, you call each topic callback (if any) with args (if any arguments are passed). So you can:
$.subscribe('do_something', function(str) { alert(str + ' world!')});
$.subscribe('do_something', function(str) { console.log(str)});
$.publish('do_something', ['Hello']); // will alert Hello world! and output 'Hello' to console
cache[topic] && d.each(cache[topic], function () {
this.apply(d, args || []);
});
Applying for each element of d, if cache[topic] is defined, function, which calls the apply method of it with d argument, and args, or an empty array, if args is not defined.

How can I call any function in a chain of functions, without the chaining?

Sorry if my question wasn't clear enough. I'll put my code here...
var chain = {
'fn_1' : {
//fn_1 code here
chain.fn_2();},
'fn_2' : {
//fn_2 code here
chain.fn_3();}
...and so on
}
Let's say if i wana call chain.fn_1(), is there a way I can do that without calling chain.fn_2()?
What I can think of right now is a flag, but that would be alot of excess flags probably for each function. Do you guys have any ideas?
If the series of functions each call the next one you're correct, you'd need to have some sort of flag. In all likelihood, what would be best would be to modify your functions so that they return the reference to the object. Then you could chain like so:
var chain = {
'fn_1': function () {
// do something here.
return this;
},
'fn_2': function () {
// do something here.
return this;
},
'fn_3': function () {
// do something here.
return this;
}
};
// call the full chain:
chain.fn_1().fn_2().fn_3();
// call only the middle.
chain.fn_2();
g.d.d.c's answer is best, but if you can't modify the object for some reason, you could do this:
var _oldFn2 = chain.fn_2
chain.fn_2 = function() { return; };
chain.fn_1();
chain.fn_2 = _oldFn2;
var chain = {
fn : ['fn1', 'fn2', 'fn3'],
call : function(name) {
var i = 0, pos = -1, l = this.fn.length;
for(i = 0; i < l; i += 1) {
if(this.fn[i] == name) {
pos = i;
}
if(pos !== -1) {
this[this.fn[i]]();
}
}
},
fn1 : function() {
alert('fn1');
},
fn2 : function() {
alert('fn2');
},
};
chain.call('fn1'); //chain
chain.fn1(); //single

Categories

Resources