Here is my situation:

Per my other post, I have a form embedded in a block inside of a quicktab! I set the #action item so it all submits just fine. A new form is, of course, placed where the submitted one was. So that part is perfect!

What I want to do, is, after the new form is built, execute a javascript or jquery function. My JS skills are weak, so I'd appreciate advice. I'll be working on these skills this year a lot, but I'm still not comfortable with things yet.

Do I need to somehow bring in new javascript? I have tried adding the function via drupal_add_js("MY CODE HERE", "inline"), but that doesn't seem to work.

The code I want to execute pops up a modal dialog via the popups module. I was also figuring on placing some data from a global variable somewhere that javascript can access it for the new form. Ideas for how to do that would be helpful too, but the primary issue is executing the function I mentioned.

I realize that this is not necessarily stuff exclusive to this module and is more of a general javascript question, but on the chance you may have done this before, I thought I'd ask here first. Thanks in advance.

Comments

leenwebb’s picture

I came here to ask this same question! I have some forms that I have AJAX-ified (so easy, thanks!) and after the form submits it displays a drupal-message at the top of the page. I'd like the message to fade out after a few seconds; I know how to do that with jQuery but since the form is submitted with AJAX I don't know how to get it to "activate" (for lack of a better term) my jQuery script anew to apply to the new message.

pivica’s picture

Hi all,

@leenwebb you can try to implement 'afterMessage' hook and probably get that behavior you want - check ajax_scroller module for an example.

I have also similar problem, but I want to have special jQuery effect that happens before and after messages are shown and want far more control when ajax module is showing messages. I think with current hooks and a way things work this is not something that can be easily done.

After quick scanning of ajax.js code it seems to me that it would be a logical step to extract Drupal.Ajax.writeMessage function and create new plugin from it. Then in Drupal.Ajax.message instead of

if (Drupal.Ajax.invoke('message', data)) {
  Drupal.Ajax.writeMessage(data.local.form, data.local.submitter, options);
  Drupal.Ajax.invoke('afterMessage', data);
}

We would have something like

data.options = options;
Drupal.Ajax.invoke('message', data);
Drupal.Ajax.invoke('afterMessage', data);

If something like this can be implemented than it will cover different use case:
- sometimes user will not want any kind of messages - he will not enable default message plugin,
- most of the time default message is ok,
- more advanced user will be able to implement their own message plugins and implement custom messages - fadein/fadeout, popups....

If module author thinks this is an ok idea I can invest more time and create a patch and we can then test proposed feature.

FrontBurner’s picture

Status: Active » Closed (fixed)
Drupal.Ajax.plugins.MyAjaxPlugin = function(hook,args)
{
        if(hook === 'complete')
        {
               //do whatever you want after form has been submitted
        }
        if(hook === 'afterMessage')
        {
               //do whatever you want after message is displayed
        }
};

Available Hooks: init, submit, redirect, message, afterMessage, scrollFind, complete

pivica’s picture

Status: Closed (fixed) » Active

@FrontBurner thanks for the tip, this almost work for my use case. What I want is to reimplement Drupal.Ajax.writeMessage and use my own version - I just want to add simple fadeIn animation when showing message.

Drupal.Ajax.plugins.MyAjaxPlugin = function(hook, args) {
  if (hook === 'message') {
    myWriteMessage(args.local.form, args.local.submitter, args.options);
    Drupal.Ajax.invoke('afterMessage', args);
    return false;
  }
};

myWriteMessage would be copy&paste of Drupal.Ajax.writeMessage and I would add code for message fadeIn. The only problem is that I don't have args.options in my custom hook. Can we add

data.options = options;

in Drupal.Ajax.message function so we have something like this

Drupal.Ajax.message = function(formObj, submitter, data, options) {
  var args;
  data.local = {
    submitter : submitter,
    form : formObj
  };

  data.options = options;

  if (Drupal.Ajax.invoke('message', data)) {
    Drupal.Ajax.writeMessage(data.local.form, data.local.submitter, options);
    Drupal.Ajax.invoke('afterMessage', data);
  }
  return true;
};
Bilmar’s picture

+1 subscribing

I would really like to learn a way to make the drupal system messages (from drupal_set_message) to fade in and fade out after 5 seconds.

Thanks!

xine’s picture

I have modified the ajax response function to post 'afterComplete' message/hook so you can subscribe for that:

The modified response function below

Drupal.Ajax.response = function(submitter, formObj, data){
  var newSubmitter;
  data.local = {
    submitter : submitter,
    form : formObj
  };
  /**
   * Failure
   */
  if (data.status === false) {
    Drupal.Ajax.updater(data.updaters);
    Drupal.Ajax.message(formObj, submitter, data, {
      action : 'notify',
      messages : data.messages_error,
      type : 'error'
    });
  }
  /**
   * Success
   */
  else {
    // Display preview
    if (data.preview !== null) {
      Drupal.Ajax.updater(data.updaters);
      Drupal.Ajax.message(formObj, submitter, data, {
        action : 'notify',
        messages : decodeURIComponent(data.preview),
        type : 'preview'
      });
    }
    // If no redirect, then simply show messages
    else if (data.redirect === null) {
      if (data.messages_status.length > 0) {
        Drupal.Ajax.message(formObj, submitter, data, {
          action : 'notify',
          messages : data.messages_status,
          type : 'status'
        });
      }
      if (data.messages_warning.length > 0) {
        Drupal.Ajax.message(formObj, submitter, data, {
          action : 'notify',
          messages : data.messages_warning,
          type : 'warning'
        });
      }
      if (data.messages_status.length === 0 &&
          data.messages_warning.length === 0) {
        Drupal.Ajax.message(formObj, submitter, data, {action:'clear'});
      }
    }
    // Redirect
    else {
      if (Drupal.Ajax.invoke('complete', data)) {
        Drupal.Ajax.redirect( data.redirect );
      }
      else {
        Drupal.Ajax.updater(data.updaters);
        if (data.messages_status.length === 0 &&
            data.messages_warning.length === 0) {
          Drupal.Ajax.message(formObj, submitter, data, {action:'clear'});
        }
        else {
          Drupal.Ajax.message(formObj, submitter, data, {
            action : 'notify',
            messages : data.messages_status,
            type : 'status'
          });
			Drupal.Ajax.invoke('afterComplete', data); // and here is the new message 
        }
      }
    }
  }
  return true;
};

so after that you can write something like that to listen for 'afterComplete' message:

Drupal.Ajax.plugins.FormPlugin = function(hook,args) {
	if(hook == 'afterComplete') {
		args.local['form'].find('div.status').delay(3000).fadeOut('slow');
	}
};

You can always debug the args to see what you have there and find your DOM elements there