I've been playing with the new ajax framework and have successfully used it for the admin form on the D7 version of Quicktabs - awesome stuff, the ajax callback is so simple! :-)
Anyway, I was also testing the use of the 'use-ajax' class to do just a regular ajax request when clicking on a link. My menu callback calls ajax_deliver() as long as ajax is passed in and not nojs. I can get this to work only by hacking ajax.js to tell it what element.wrapper and element.click should be, otherwise it causes a js error as these properties are missing and I can't figure out how to set them from the php side. I, perhaps naively, thought that something like this should work:

  $build['ajaxy_link'] = array(
    '#type' => 'link',
    '#title' => t('Click here'),
    '#href' => 'ajaxy/nojs/',
    '#attributes' => array('class' => array('use-ajax')),
    '#ajax' => array(
      'event' => 'click',
      'wrapper' => 'content',
    ),
  );

Anyway, this does not load ajax.js on the page and does not communicate the wrapper and event properties as required. It would be great if someone who understands how this should work could either add the explanation to the existing docs or give a brief instruction in this thread and I'll write it up in the docs.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Scott Reynolds’s picture

subscribing

rfay’s picture

Excellent - I plan to do full Ajax docs for the new system and will try to cover this. As of now, I haven't explored it.

rfay’s picture

I'm not to no-js yet, but

1. Updated the 6-to-7 documentation at http://drupal.org/update/modules/6/7#ahah-now-ajax
2. Committed the D7 version of the Ajax Example to the Examples Module

I would appreciate review of those two, plus contributions of more sophisticated AJAX examples. There's a lot more stuff in here!

The coolest thing in the world is how simple the callbacks have become. One line for each of my examples. I guess we could have figured out how to do away with the callback entirely if you wanted to replace the entire form.

rfay’s picture

Title: ajax.inc PHPDoc Improvements » Ajax Framework Documentation To-Do list

May I hijack this issue for a general To-Do list for Ajax Documentation? There are several different issues that need to be addressed. I will maintain this comment as time goes on.

Other items that should be covered? Chime in!

effulgentsia’s picture

Title: Ajax framework documentation only covers ajax forms » Ajax Framework Documentation To-Do list

For now, subscribing. When I'm able to, I'd also like to help.

katbailey’s picture

FileSize
26.84 KB
821 bytes

Just want to add a bit of clarification regarding my initial question above. Rfay and I were discussing this on irc yesterday and the more I look at the code the more I realise that what I was trying to do above is definitely not possible, currently. The only time ajax.js gets automatically added is when ajax_process_form is called. So it seems it really is only intended for forms.
Nobody seems to know how the use-ajax class is supposed to be used currently (or if it can be) so I've been hacking away seeing what it would take to get it to work the way I initially assumed it did. The attached patch allows you to set up ajax functionality on a link (independent of any form) when the link is rendered as follows:

  $build['ajaxy_link'] = array(
    '#type' => 'link',
    '#title' => t('Click here'),
    '#href' => 'ajaxy/nojs/',
    '#options' => array('attributes' => array('class' => array('use-ajax'), 'id' => 'myId')),
    '#ajax' => array(
      'event' => 'click',
      'wrapper' => 'block-system-main',
    ),
    '#id' => 'myId',
  );
  $output = drupal_render($build);

I should have pointed out above that rendering a link this way is only possible with this patch: #602522: Links in renderable arrays and forms (e.g. "Operations") are not alterable
So, I'm attaching a patch which builds on this and, just as a proof of concept, adds an ajax_process_link() function - the first hunk in the patch - which replicates the main functionality in ajax_process_form. I assumed I could add this to the type definiton of the link element in system.module like this:

  $types['link'] = array(
    '#process' => array('ajax_process_link'),
    '#pre_render' => array('drupal_pre_render_link', 'drupal_pre_render_markup'),
  );

... but that didn't work so instead I'm calling it from within drupal_pre_render_link.

Anyway, I'd love if someone could look at this and comment, even if it's just to say that these are the ravings of a crazy person ;-)
The attached module should help test it - just enable the one block in a sidebar. This assumes your page has an element with id of 'block-system-main'.

thanks!

K

Edit: I know this is no time for proofs of concept. It's just that there does seem to be a gap in the ajax framework and I'm wondering if this is the way to fill it...

katbailey’s picture

FileSize
26.83 KB

Attaching an updated patch as there was a problem with the href in the last one...

katbailey’s picture

OK, finally got this one figured out, after chatting with merlinofchaos in irc - I had misunderstood how this was supposed to work and now it all makes sense. A tiny patch was required though and you'll find it here: #615504: Ajax framework's use-ajax class doesn't work.
And here's an example of how you'd use the use-ajax class:

// function that outputs the content with the ajax link
function my_content_with_link() {
  drupal_add_js('misc/ajax.js');
  $output = l('Click here', 'ajaxy/nojs/', array('attributes' => array('class' => array('use-ajax'))));
  $output .= '<div id="myDiv"></div>';
  return $output;
}

// menu callback for the 'ajaxy' path
function ajaxy_ajax_response($type = 'ajax') {
  $output = '<div>Hello</div>';
  if ($type == 'ajax') {
    $commands = array();
    $commands[] = ajax_command_append('#myDiv', $output);
    $page = array('#type' => 'ajax_commands', '#ajax_commands' => $commands);
    ajax_deliver($page);
  }
  else {
    return $output;
  }
}
rfay’s picture

I confirm that this approach works. Thanks so much for the detective work!

Roi Danton’s picture

Thanks for mentioning this issue in IRC (was afk therefore I couldn't reply there). The examples (also the ones in examples module) are helpful when working with ctools wizard ajax render callback (D6), too. There in the ajax-responder.js the click event is attached to links.

te-brian’s picture

I was playing around with the AJAX framework this morning, and came across a relatively new use case: adding new custom commands.

I wanted to add some commands for working with a jQuery UI Dialog. An example of my approach, which is working but not fully tested, follows:

mymodule.module

/**
 * Return an ajax command array to set the dialog options.
 *
 * @param $options
 * An array of jQuery UI dialog options, keyed by option name.
 */
function mymodule_ajax_command_dialog_options($selector, $options, $settings = NULL) {
  return array(
    'command' => 'mymodule_dialog_options',
    'options' => $options,
    'settings' => $settings,
  );
}

mymodule.js

Drupal.behaviors.mymodule = {
  attach: function(context, settings) {    
    // Add custom commands to Drupal.ajax objects.
    for (var i in Drupal.ajax) {
      Drupal.mymodule.addCommands(Drupal.ajax[i]);
    }
  }
};

// Add custom commands to a Drupal.ajax object.
Drupal.mymodule.addCommands = function (ajax) {
  //Add options dialog command to ajax object.
  ajax.commands.mymodule_dialog_options = function (ajax, response, status) {
    options = response.options;
    if (options) {
      for (var option in options) {
        $(response.selector).dialog('option', option, options[option]);
      }
    }
  }
}

The result is that I can add the 'mymodule_dialog_options' command in my ajax callbacks and my custom command function runs on the client side.

So here is an actual question :)

Is there a better way to add these commands to the Drupal.ajax object(s)? The way I got it working, is adding the command to each Drupal.ajax object that exists one-by-one. The better approach, which I could not get working, would be to add it to all Drupal.ajax objects in one swoop. This is where my javascript mastery falls a bit short. I initialy tried to do this:

Drupal.ajax.commands.prototype.mymodule_dialog_options = function() { ...

But I guess the Drupal.ajax object is not extendable in this way?

rfay’s picture

Committed update to forms_api_reference.html updating to current AJAX situation.

http://drupal.org/cvs?commit=294182

rfay’s picture

Status: Active » Needs review
FileSize
7.35 KB

This documentation-only patch adds significant information to the AJAX overview in ajax.inc.

New topics covered or with improved coverage include:

  • A simple example
  • How status messages are handled.

Plus lots of little cleanup.

rfay’s picture

FileSize
4.93 KB

It's nearly impossible to review a doc change as a patch, so attached is the HTML rendered by the API module. It doesn't show what's changed, but really, everything is open for improvement.

rfay’s picture

katbailey’s picture

This is a great enhancement to the ajax docs - it's very helpful to have example code in there.
There's still one part of the docs that I have a problem with:

 * Each command is an object. $object->command is the type of command and will
 * be used to find the method (it will correlate directly to a method in
 * the Drupal.ajax[command] space). The object may contain any other data that
 * the command needs to process.

Maybe I'm missing something, but on the php side, each command is just an associative array and only becomes an object on the js side. So, would something like the following make more sense:

 * Each command item is an associative array which will be converted to a command
 * object on the JavaScript side. $command_item['command'] is the type of
 * command, e.g. 'alert' or 'replace', and will correspond to a method in the
 * Drupal.ajax[command] space). The command array may contain any other
 * data that the command needs to process, e.g. 'method', 'selector', 'settings', etc.
katbailey’s picture

Attached patch makes the change in #16.

rfay’s picture

Title: Ajax Framework Documentation To-Do list » ajax.inc PHPDoc Improvements
Status: Needs review » Reviewed & tested by the community

Good by me. Marking RTBC - thanks for the review and improvement.

The bot approved #17 despite the lack of marking on it: See http://qa.drupal.org/pifr/test/26734

For other reviewers, #17 is still exactly the same as #13 (which you can read as HTML in the attachment to #14) - except for the following change.

--- includes/ajax.inc
+++ includes/ajax.inc
@@ -152,10 +152,11 @@
  * be converted to a JSON object and returned to the client, which will then
  * iterate over the array and process it like a macro language.
  *
- * Each command is an object. $object->command is the type of command and will
- * be used to find the method (it will correlate directly to a method in
- * the Drupal.ajax[command] space). The object may contain any other data that
- * the command needs to process.
+ * Each command item is an associative array which will be converted to a command
+ * object on the JavaScript side. $command_item['command'] is the type of
+ * command, e.g. 'alert' or 'replace', and will correspond to a method in the
+ * Drupal.ajax[command] space. The command array may contain any other data
+ * that the command needs to process, e.g. 'method', 'selector', 'settings', etc.
  *
  * Commands are usually created with a couple of helper functions, so they
  * look like this:
Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

rfay’s picture

Status: Fixed » Active

Remaining items to do in #4

rfay’s picture

Title: Ajax Framework Documentation To-Do list » AJAX Documentation items to be completed

I think that no-js and use-ajax are the last remaining items to be documented in this issue

rfay’s picture

Title: AJAX Documentation items to be completed » Document AJAX no-js and use-ajax
Assigned: Unassigned » rfay

I'll put this on my list for docs day.

@katbailey, could you write a quick description here of what you think should be said? 'twould be much appreciated.

rfay’s picture

Status: Active » Fixed

I'm going to say that http://api.drupal.org/api/group/ajax/7 + the AJAX link example are good enough.

Status: Fixed » Closed (fixed)

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

rfay’s picture

Status: Closed (fixed) » Needs work

Hmm... I don't find anything about class="no-js" *anywhere* in D7 code or documentation. Did I miss something?

ñull’s picture

// menu callback for the 'ajaxy' path
function ajaxy_ajax_response($type = 'ajax') {
  $output=strftime('%c');
  if ($type == 'ajax') {
    $commands = array();
    $commands[] = ajax_command_append('#myDiv', $output);
    $page = array('#type' => 'ajax_commands', '#ajax_commands' => $commands);
    ajax_deliver($page);
  }
  else {
    return $output;
  }

This code as proposed by katbaily is unsuitable for dynamic content. I always get the same date/time here (see changed ajax response code above). No effect when I clear the browser cache in between. Only reloading the page where this link is helps. How do I "uncache" it? Would be good to include that too in the examples and documentation.

ñull’s picture

Forget my post. For some obscure reason now it works.

nod_’s picture

Version: 7.x-dev » 8.x-dev
LewisNyman’s picture

Issue summary: View changes
Issue tags: +JavaScript, +frontend

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

  • Dries committed 0fa98a7 on 8.3.x
    - Patch #610068 by katbailey, rfay: improved phpDoc.
    
    

  • Dries committed 0fa98a7 on 8.3.x
    - Patch #610068 by katbailey, rfay: improved phpDoc.
    
    

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

  • Dries committed 0fa98a7 on 8.4.x
    - Patch #610068 by katbailey, rfay: improved phpDoc.
    
    

  • Dries committed 0fa98a7 on 8.4.x
    - Patch #610068 by katbailey, rfay: improved phpDoc.
    
    
andypost’s picture

Version: 8.2.x-dev » 8.4.x-dev
Assigned: rfay » Unassigned

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

seanB’s picture

New data attributes are being added to links with the use-ajax class in #3026636: Allow AJAX links to replace a specific selector (CR: https://www.drupal.org/node/3031444).
This probably needs to be taken into account when writing the documentation for the AJAX links.

As far as I can tell, the ajax link support the following data attributes:

  • data-dialog-type: This is either 'modal' or 'dialog'
  • data-dialog-options: Should be a JSON encoded string of options for Drupal.dialog. Basically all options supported by http://api.jqueryui.com/dialog/ can be used and are just passed along to the jQuery UI dialog.
  • data-dialog-renderer: Has been added in #2844261: Allow dialog links to specify a renderer in addition to a dialog type. It appears to be used to specify how a dialog should be rendered. offcanvas is an example, but not sure which other values are supported and how that works in detail.

The content is always being fetched from the href attribute of the link.

#3026636: Allow AJAX links to replace a specific selector adds the following attributes:

  • data-ajax-wrapper: This accepts the ID of the HTML element (without the #) that should be replaced by the content fetched via AJAX. The AJAX system already supported setting the wrapper for Drupal.Ajax, this behavior has not been changed. Now AJAX links can also use this.
  • data-ajax-progress: By default the AJAX links used the throbber progress indicator. AJAX links can now override the default with this data attribute (by setting this to 'fullscreen' for example).
  • data-ajax-focus: This accepts a jQuery selector targeting the element that should receive focus. By default the the focus is returned to the AJAX link after the AJAX request is handled. AJAX links can now override this default with this data attribute. This was added to improve accessibility.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

paper boy’s picture

Issue tags: -JavaScript +JavaScript

I ran into this old issue but couldn't find any documentation page for use-ajax for Drupal 8. Does this docs page already exist somewhere?

I added a documentation for Ajax Dialogs to the AJAX API Guide that explains how to use the use-ajax class to display Dialogs. If there's no other docs page for use-ajax yet, I'd add a documentation page to the AJAX API Guide that focuses on use-ajax and use-ajax-submit.

  • Dries committed 0fa98a7 on 9.1.x
    - Patch #610068 by katbailey, rfay: improved phpDoc.
    
    

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.