Jquery optionally add callbacks - javascript

I am trying to write a reusable Jquery form function. I need it to optionally assign callback functions depending on if the function is defined on the page or not.
Is this example I use the Success but would be done for all.
On Main JS File:
function gJs_AjaxCustomSubmit(ObjectContext) {
var AS='';
if (typeof AjaxSuccess == 'function') { AS = 'AjaxSuccess' }
$('#frm').ajaxSubmit({
success: AS, //callback functions
});
}
On the page, if AjaxSuccess function exists, then it would execute on the success callback. If it does not exist, there would be no error.
On normal pages:
function AjaxSuccess(response) {
alert(response);
}
I want to be able to define all the functions on my global JS like this, and then if needed I can just add the actual function to my pages and they will run.
function gJs_AjaxCustomSubmit(ObjectContext) {
var AStart='';
if (typeof AjaxStart == 'function') { AS = 'AjaxStart' }
var ASuccess='';
if (typeof AjaxSuccess == 'function') { AS = 'AjaxSuccess' }
var ABSend='';
if (typeof AjaxBeforeSend== 'function') { AS = 'AjaxBeforeSend' }
var AComplete='';
if (typeof AjaxComplete== 'function') { AS = 'AjaxSuccess' }
var ASt='';
if (typeof AjaxStop== 'function') { AS = 'AjaxStop' }
var AError='';
if (typeof AjaxError== 'function') { AS = 'AjaxError' }
$('#frm').attr("action", $(ObjectContext).data('path'));
$('#frm').ajaxSubmit({
dataType: 'html',
start: AStart, //callback functions
send: ABSend, //callback functions
complete: AComplete, //callback functions
stop: AjaxStop,
success: ASuccess, //callback functions
error: AError, //callback functions
});
}

Here is a clean reusable function that returns either desired function(if it exists) or an empty function if it doesn't.
$('#frm').ajaxSubmit({
start: getFunction('AStart'),
send: getFunction('ABSend'),
complete: getFunction('AComplete'),
//... //callback functions
});
function getFunction(name){
if (typeof window[name] == 'function'){
return window[name];
}
return function(){}; // or null/false
}
If the function passed as parameter by name does not exist, an empty callback will be returned, which will do nothing and not throw any errors.

I ended up using this.
function gJs_AjaxCustomSubmit(ObjectContext) {
//Add function to your page if needed
//AjaxStart
//AjaxBeforeSend
//AjaxComplete
//AjaxSuccess
//AjaxStop
//AjaxError
var DataType = 'html', AStart = '', ASuccess = '', ABSend = '', AComplete = '', AStop = '', AError = '';
if ($(ObjectContext).data('type')) {
DataType = $(ObjectContext).data('type');
}
if (typeof AjaxStart == 'function') { AStart = AjaxStart }
if (typeof AjaxBeforeSend == 'function') { ABSend = AjaxBeforeSend }
if (typeof AjaxComplete == 'function') { AComplete = AjaxComplete }
if (typeof AjaxSuccess == 'function') { ASuccess = AjaxSuccess }
if (typeof AjaxStop == 'function') { AStop = AjaxStop }
if (typeof AjaxError == 'function') { AError = AjaxError }
$('#frm').attr("action", $(ObjectContext).data('path'));
$('#frm').ajaxSubmit({
dataType: 'html',
start: AStart, //callback functions
send: ABSend, //callback functions
complete: AComplete, //callback functions
stop: AStop,
success: ASuccess, //callback functions
error: AError, //callback functions
});
}

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) } )

How can I create a wrapper function for addEventListener that works with removeEventListener?

I want to create a wrapper function for addEventListener that I can call as such:
aEvt('click', document, function (evt, target) {
//Code here
});
I want to do this because it allows me to always have the event target available first from the start as a parameter.
I attempted such a function, but the problem is, in order to have it work with removeEventListener (or my analogous rEvt function), I have to return a callback from the aEvt function and pass that to removeEventListener as the callback.
The aEvt function I currently have is as follows:
function aEvt(evt, elem, fn) {
'use strict';
var callback = function (evt) {
fn(evt, evt && evt.target ? evt.target : window.event.srcElement);
};
if (elem.addEventListener) {
elem.addEventListener(evt, callback);
} else if (elem.attachEvent) {
elem.attachEvent('on' + evt, callback);
} else {
elem['on' + evt] = callback;
}
return callback;
}
Is there any way I can change the aEvt function so that I can send the target to the callback passed to the aEvt function (i.e., fn), but also have the callback I send to the aEvt function be the same callback that I send to the analogous rEvt function I want to write?
In other words, how should I change aEvt to make the following work?
var callbackFn = function (evt, target) { console.log(target); };
aEvt('click', document, callbackFn);
rEvt('click', document, callbackFn);
Felix Kling, thanks a lot for your answer in the SO post you linked to in the comments.
I took what you did and modified it slightly to 1) follow the JS code standards set at my organization, and 2) make it so that I could get the event target as a parameter in the handler callback.
Having the target available as a parameter makes handling events a lot easier in a majority of the use cases I have as well as greatly minimizes the amount of refactoring required.
Anyway, here's the final code (please note that the each function in remove executes a simple for loop, and return false in the function essentially breaks the loop):
var evts = (function () {
'use strict';
var listeners = [],
add,
remove;
add = function (evt, elem, fn) {
var callback = function (evt) {
fn(evt, evt && evt.target ? evt.target : window.event.srcElement);
};
listeners.push({
evt: evt,
elem: elem,
fn: fn,
callback: callback,
removed: false
});
if (elem.addEventListener) {
elem.addEventListener(evt, callback);
} else if (elem.attachEvent) {
elem.attachEvent('on' + evt, callback);
} else {
elem['on' + evt] = callback;
}
};
remove = function (evt, elem, fn) {
var callback;
each(listeners, function (evtObj) {
if (evtObj.evt === evt && evtObj.elem === elem &&
evtObj.fn === fn && !evtObj.removed) {
evtObj.removed = true;
callback = evtObj.callback;
return false;
}
});
if (elem.removeEventListener) {
elem.removeEventListener(evt, callback);
} else if (elem.detachEvent) {
elem.detachEvent('on' + evt, callback);
} else {
elem['on' + evt] = null;
}
};
return {
add: add,
remove: remove
};
}());
And here's an example of using the methods:
var callback = function (evt, target) {
console.log(target);
};
evts.add('click', document, callback);
evts.remove('click', document, callback);

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

Javascript Call Function with String

I'm sending callback strings from php to javascript.
var PostType = function () {
return {
create: function(form, response) {
Custom.resetForm(form);
$('#create-form').modal('hide');
Grid.reset();
}
};
}();
I have to call PostType.create method but it's not working.
I'm calling it like:
//Call function
callFunction: function(func, form, response) {
var fn = window[func];
if(typeof fn === 'function') {
fn(form, response);
} else {
console.log(typeof fn);
return false;
}
}
// Call
Custom.callFunction(response.callback, $form, response);
What should i do?
Okay, got it.
When calling object > method with window;
window["object"]["method"];
So i'v modified my callFunction to this:
callFunction: function(func, form, response) {
//Check for func string if contains any "." (dot)
if(func.indexOf('.') !== -1) {
// If so; split "." character to get Object name and the method name
func = func.split(".");
var fn = window[func[0]][func[1]];
} else {
var fn = window[func];
}
if(typeof fn === 'function') {
fn(form, response);
} else {
return false;
}
},

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']);

Categories

Resources