JQuery trigger and JS Function Call revisited


I just have to post this little code listing. It’s basically a mix between stuff detailed in two prior posts, Keeping it DRY with Function.call and jQuery toggle and Using jQuery’s trigger for automated interfaces. It is however much simpler than either of the prior posts and therefore makes for a better example.

The interface here lists various transactions to be made from a payment queue/table. 2 basic actions are possible, Pay and Delete. Paying a transaction executes the payment and deletes the transaction from the queue. Deleting a transaction simply deletes it from the queue without any payments being made of course. A third meta action is also possible: Auto Pay which will will execute payments for the whole transaction queue, by way of AJAX, and display the result for each transaction.

The auto action is of course being managed by way of jQuery’s trigger and we keep things DRY by way of JavaScript’s Function.call which lets us capitalize on the similarities between deleting a transaction and paying it.

Here is the complete listing:

var trans_ids = [];
var automatic = false;

function buildIds(){
    $("div[id^='pay-']").each(function(){
    	trans_ids.push( $(this).attr("id").split("-").pop() );
    });
}

function setupAction(action, func){
	$("div[id^='"+action+"-']").click(function(){
		var me 			= $(this);
		var myId 		= me.attr("id").split("-").pop();
		var phpAction 	= action == 'pay' ? 'exec_queue' : 'delete_queue';
		me.html('<img src="ajax-loader.gif"/>');
		$.post("ajax.php", {table: '<?php echo $table ?>', action: phpAction, transaction_id: myId}, function(res){
			func.call(me, me, res);
		});
	});
}
		
$(document).ready(function(){

	setupAction('pay', function(me, res){
		if(res == "fail")
			me.html('The transaction failed.');
		else
			me.html('New balance: ' + res);

		if(automatic == true)
			$("#pay-"+trans_ids.pop()).trigger('click');

		me.unbind('click');
	});

	setupAction('delete', function(me, res){
		if(res == "fail")
			me.html('The entry could not be deleted.');
		else
			me.html('The entry was deleted.');

		me.unbind('click');
	});
	
	$("#start_auto").click(function(){
		automatic = true;
		buildIds();
	    $("#pay-"+trans_ids.pop()).trigger('click');
	});

	$("#stop_auto").click(function(){
		automatic = false;
	});
	
});

So we start out with setting up all the delete and pay “buttons”. This happens by way of setupAction which will accept the action to execute and a callback function to execute when the AJAX call returns. The action can be either pay or delete and will proceed with working with DIVs with ids on the form of pay-23 or delete-23 where 23 is the transaction id in question.

Note that if the global variable automatic is set to true we use jQuery’s trigger to execute a click on the next transaction in the list, and so on and so forth until all transactions have been executed.
The callback function accepts two arguments, me and res where me is the jQuery DOM object (DIV) in question and res is the AJAX result.

Finally, note how the Function.call() in setupAction takes 3 arguments but as you’ve seen we only define 2 arguments when passing the callback to setupAction. This is due to the fact that the first argument to call() is the object you want any potential this statement to refer to, this argument does not need to be defined but needs to be passed in our case. In this example we simply pass the me variable two times though and refrain from using this in the callbacks. The reason for this is to limit the amount of confusion the code could give rise to.

Related Posts

Tags: ,