Passing Extra Data To JQuery Ajax Callback Functions

While working with a form that needed ajax handling I ran into an issue. The system I was developing was extremely likely to cause multiple of the same form on the page, one per element. Trying to find and adjust the form post ajax was starting to involve the addition of ids, moving down the dom to move back up, etc. Just nasty, and totally inefficient. So I did a bit of digging to find a way to pass the initial jQuery $form element from the ajax kickoff into the resulting callbacks.

Credit goes to Brad House on stackoverflow for showing me the method. I'm just wrapping it up in a little cleaner syntax and keeping notes for myself. jQuery's callback parameters expect a function pointer. What I'm doing here is simply changing way jQuery goes out to get those functions at run time. By instructing the callbacks to call closure functions with the form, we get all the extra parameters we want access to in the returned function.

This is the relevant part, but I'll add the full working script below for context too.

  1. // ...
  2. save: function($form){
  3.     jQuery.ajax({
  4.       url: viewControls.controller,
  5.       // Run time call to saveSuccess rather than a static function pointer
  6.       success: viewControls.events.saveSucccess($form),
  7.     });
  8. }
  9. // ...
  10. // Run time closure that returns the required fuction, but includes the $form definition in the function's scope
  11. viewControls.events.saveSucccess = function($form){
  12.   return function(data) {
  13.     console.debug('saveSuccess', $form, data);
  14.   }
  15. }
  16. // ...

Full code:

  1. viewControls = {
  2.   controller: 'ajax/feedback'
  3.   /**
  4.    * Loops over all exposed feedback forms to prepare them
  5.    */
  6.   ,ready: function () {
  7.     // Update our path with the proper settings basePath
  8.     viewControls.controller = settings.basePath + viewControls.controller;
  9.     // Loop over the forms
  10.     jQuery('.node-feedback .feedback-controls', context)
  11.       .once('controls', viewControls.setup);
  12.   }
  13.   /**
  14.    * Binds to the form to submit actions via ajax
  15.    * @param index A numerical value
  16.    * @param element DOM element
  17.    * @return null
  18.    */
  19.   ,setup: function(index, element){
  20.     var $form = jQuery(element);
  21.     // Ensure it can't be submitted with a button interaction
  22.     $form.submit(function( event ) {
  23.       event.preventDefault();
  24.     });
  25.     // Wire our controls
  26.     $form.find('input[type=submit].save').click(viewControls.events.save);
  27.     $form.find('input[type=submit].send').click(viewControls.events.send);
  28.   }
  29.   /**
  30.    * Saves the form
  31.    * @param $form jQuery form element
  32.    */
  33.   ,save: function($form){
  34.     jQuery.ajax({
  35.       url: viewControls.controller,
  36.       data: $form.serialize() + '&op=save',
  37.       type: 'POST',
  38.       dataType: 'json',
  39.       success: viewControls.events.saveSucccess($form),
  40.       error: viewControls.events.saveError($form),
  41.       complete: viewControls.events.saveComplete($form)
  42.     });
  43.     $form.find('input[type=submit], button').attr('disabled', 'disabled');
  44.   }
  45.   /**
  46.    * Saves the form changes and sends the feedback along to the end user
  47.    * @param $form jQuery form element
  48.    */
  49.   ,send: function($form){
  50.     jQuery.ajax({
  51.       url: viewControls.controller,
  52.       type: 'POST',
  53.       data: $form.serialize() + '&op=send',
  54.       dataType: 'json',
  55.       success: viewControls.events.sendSucccess($form),
  56.       error: viewControls.events.sendError($form),
  57.       complete: viewControls.events.sendComplete($form)
  58.     });
  59.     $form.find('input[type=submit], button').attr('disabled', 'disabled');
  60.   }
  61.   ,events: {
  62.     /**
  63.      * Finds the form and passes it off to be saved
  64.      * @param event
  65.      */
  66.     save: function(event){
  67.       event.preventDefault();
  68.       var $form = jQuery(this).parents('.feedback-controls');
  69.       viewControls.save($form);
  70.     }
  71.     ,saveSucccess: function($form){
  72.       return function(data) {
  73.         console.debug('saveSuccess', $form, data);
  74.       }
  75.     }
  76.     ,saveError: function($form){
  77.       return function(jqXHR, textStatus) {
  78.         console.debug('saveError', $form);
  79.       }
  80.     }
  81.     ,saveComplete: function($form){
  82.       return function(jqXHR, textStatus) {
  83.         $form.find('input[type=submit], button').removeAttr('disabled');
  84.       }
  85.     }
  86.     /**
  87.      * Finds the form and passes it off to be saved
  88.      * @param event
  89.      */
  90.     ,send: function(event){
  91.       event.preventDefault();
  92.       var $form = jQuery(this).parents('.feedback-controls');
  93.       viewControls.send($form);
  94.     }
  95.     ,sendSucccess: function($form){
  96.       return function(data) {
  97.         console.debug('sendSuccess', $form, data);
  98.       }
  99.     }
  100.     ,sendError: function($form){
  101.       return function(jqXHR, textStatus) {
  102.         console.debug('sendError', $form);
  103.       }
  104.     }
  105.     ,sendComplete: function($form){
  106.       return function(jqXHR, textStatus) {
  107.         $form.find('input[type=submit], button').removeAttr('disabled');
  108.       }
  109.     }
  110.   }
  111. };
  112.  
  113. jQuery(document).ready(viewControls.ready);
Tags: 

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.