I am trying to add captcha support to an ajaxsubmitted form (send.module) but there are issues with how captcha works.

It is difficult to implement captcha on my ajax submitted form as the CAPTCHA validation function unsets my captcha token (session var) if i don't validate and since no page refresh - no token exists the 2nd time i try to submit form. Actually, even if i fix the code to only unset if i do validate, i still have the issue of validating captcha but failing to validate other fields on the form - which again causes resubmit to fail captcha since the token has now been cleared.

So i think possible solutions are to never clear the token? Or somehow figure out how to tie captcha module in to ajaxsubmit so that i can pass back a new captcha token?

So my thought was (and i am not exactly a JS expert so i might be off here) was that the ajaxsubmit_dispatch $result['data'] array could possibly include 2 more values - a callback function to another js function (defined in module which has form which will use ajaxsubmit) and an array of variables to be used by that callback function. I think if this was preceded by a module_invoke call it would allow other modules to use the ajaxsubmit pre-canned ajax code.

For example, in my specific case of the send.module - i think i would need to pass a new captcha value back as the callback argument and a then define a js function that would repopulate the form with the new captcha token.

Does this make sense?

Peter Lindstrom
LiquidCMS - Content Management Solution Experts

Comments

liquidcms’s picture

I think this idea would also allow for form returns to do things like close the form or other similar JS actions.

nedjo’s picture

Good idea. For D6, ajaxsubmit needs to be rewritten to use the jQuery forms plugin (now part of Drupal core). Adding this feature could be done after the rewrite.

Ajaxsubmit is intended as a helper module for other modules implementing ajax submission. I added a UI for selecting which forms to submit via AJAX, but it doesn't make a lot of sense, since simply submitting is seldom if ever enough. We need follow up actions.

liquidcms’s picture

Not sure if this is the best way to add this - but as proof of concept i tried this:

added module invoke code near end of ajaxsubmit_dispatch function

  $result = module_invoke_all('ajaxsubmit', $form, $result);      // added this line
  
  print drupal_to_js($result);
  exit(); 

and in ajaxsubmit.js at the very end of Drupal.ajaxsubmit.prototype.onsubmit i added:

  // Run Additional Callback if there was one
  if (data['additional_callback']) eval(data['additional_callback']+"("+data['additional_callback_args']+")"); 

this now lets other modules modify the $result array and pass both a callback function and arguments for it in a hook such as with this hook:

// use new ajaxsubmit_hook to only close STF form if were no errors
function umga_ajaxsubmit ($form, $result) {
  if (!$result['data']['errors']) {
    $result['data']['additional_callback'] = 'hideSendIfNoErrors';
    $result['data']['additional_callback_args'] = array('this');
  }
  
  return $result;
}

and with this callback function:

function hideSendIfNoErrors(mynode) {
  var nid = mynode.form.nid.value;
  $("div#send-"+nid+" form").hide();
}

This particular example lets me close the Send To Friend form on submit only if there were no errors - and it leaves it open if there were errors. I will eventually add another hook (hopefully) to re-add a new CAPTCHA to the form if the form submission fails.

Seems to work pretty well.. :)

liquidcms’s picture

Status: Active » Needs review
liquidcms’s picture

Using the new ajaxsubmit_hook i also added a "close message" icon to hide the submit was good message (i.e. "email has been sent to popoi@poi.ca").

in same hook call as above i added:

// add message close button
  $message_close = '<div class="close-button"><a href="javascript:;" title="Click to close" onclick="hideMessage(this);"><img src="/themes/umg/images/x.gif"/></a></div>';  
  $result['data']['message'] = $message_close . $result['data']['message'];

btw - no callback used in this example - simply using hook to modify existing $message value.

liquidcms’s picture

started working on a new project for some people and sure enough needed my hooks again - for some reason i though this had been committed to cvs; but sadly no. Too bad; hard to imagine using this module where these hooks wouldn't be used.

nedjo’s picture

Project: Javascript Tools » Ajax submit
Version: master » 6.x-1.x-dev
Component: Ajaxsubmit » Code
Status: Needs review » Needs work

The idea is good.

What I'd like to do is modify ajaxsubmit in HEAD (which is the 6.x compatible version) to use the same drupal_alter() approach that I introduced into Views, which is to depend on AJax load, http://drupal.org/project/ajax_load. See instructions on that project's page for steps needed to add support.

liquidcms: can you do up a patch adding this functionality to Ajaxsubmit?

liquidcms’s picture

hey nedjo,

replied to your email before reading this post.. so Dr6? - as i said, i am a bit behind.. and as i didn't say crazy busy.. just launching $20M huge Drupal site today.. hopefully in next week or so i can set up a Dr6 test site and get HEAD rev of your module - i doubt a patch should be too hard.. in Dr5 version this only adds about 3-4 lines of code.

peter..

nedjo’s picture

Sounds good, I look forward to the patch.

nedjo’s picture

Assigned: Unassigned » nedjo

I've implemented the change. For some details on how to use this, see the ajax_load project page, http://drupal.org/project/ajax_load.

nedjo’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.