API page: http://api.drupal.org/api/drupal/includes--ajax.inc/function/ajax_comman...

Describe the problem you have found:

It states that $selector A jQuery selector string. If the command is a response to a request from an #ajax form element then this value can be NULL. I assume this means when you return an array of AJAX commands from a callback called from an #AJAX form element that the selector is automatically set to the wrapper or the element that called the request. However if I do set this parameter to NULL then nothing happens.

When debugging the situation it looks like on line 580 of misc/ajax.js the response.selector is NULL. If I add a parameter then it works as expected.

Is this the desired outcome? Maybe you're not meant to call the AJAX commands through a callback function when using Form API but I can't see anything else in the documentation to call an AJAX command without returning an array of them via a callback.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jhodgdon’s picture

Title: Documentation problem with ajax_command_invoke » ajax_command_invoke - does it work with $selector = NULL?
Component: documentation » ajax system

Good question. We should probably get someone who knows about the AJAX framework to answer it.

So although this is likely a documentation issue, I'm moving it in to the ajax system component to see if we can get an answer.

rfay’s picture

The case of $selector == NULL is where we're using the 'wrapper' portion of #ajax to determine the selector. In other words, if the selector is null, assume we're in the middle of #ajax operation and know that the selector is the one determined by '#ajax'['wrapper'].

If you're returning an array of AJAX commands, you're already overriding that behavior.

I'm not entirely sure I understand what you're trying to accomplish, but essentially: you probably won't use the NULL situation if you're working with AJAX commands.

jhodgdon’s picture

So rfay does the documentation need an update here or is this a support request only?

jdelaune’s picture

Status: Needs review » Active

Thanks guys.

rfay, I am passing a #wrapper paramater on the Form API element where the #ajax callback is made from. How would one call an AJAX Command straight from a Form API element without providing a #ajax callback parameter? I can't see to see it documented anywhere.

For an example:

<?php
  $element['browse'] = array(
    '#type' => 'submit',
    '#value' => t('Browse Entities'),
    '#ajax' => array(
      'callback' => 'relation_browser_field_widget_form_callback',
      'wrapper' => 'relation_browser_' . $unique_identifier,
    ),
    '#attached' => array(
      'library' => array(
        array('system', 'ui.dialog'),
      ),
    )
  );
  
  $element['browser_markup'] = array(
    '#prefix' => '<div class="relation_browser" id="relation_browser_' . $unique_identifier . '">',
    '#suffix' => '</div>',
    '#markup' => t('Browser Goes Here'),
  );
?>
<?php
function relation_browser_field_widget_form_callback($form, $form_state) {
  $commands = array();
  $commands[] = ajax_command_invoke(
    NULL,
    'dialog',
    array(
      array('modal' => true),
      array('minHeight' => 400),
      array('minWidth' => 600),
    )
  );
  return array('#type' => 'ajax', '#commands' => $commands);
}
?>

Thanks in advance

jdelaune’s picture

After some more testing it seems to be based on the ajax command you are using on whether or not it will work.

e.g. ajax_command_append() and ajax_command_insert() seem to work when you set the selector to NULL. But other commands like ajax_command_css() and ajax_command_invoke() don't work, you need to specify a selector.

Is this expected?

jdelaune’s picture

I think I have found the bug, not maybe it's not a bug it's working as you expect.

Here's the 'patched' misc/ajax.js function (line 576)

  /**
   * Command to apply a jQuery method.
   */
  invoke: function (ajax, response, status) {
    if (response.selector == null) {
      response.selector = ajax.wrapper;
    }
    var $element = $(response.selector);
    $element[response.method].apply($element, response.arguments);
  },

Simply if you don't supply a selector then it will fall back and use the wrapper?

Works a treat for what I want.

rfay’s picture

IMO they should all behave the same. I probably can't look at this in the next week, but could you post a patch that makes it behave predictably?

Thanks,
-Randy

jdelaune’s picture

FileSize
2.75 KB

This lets you set the selector parameter to NULL on all AJAX commands, if NULL then it will default to the wrapper as specified, if available.

Results tie in to what the documentation states should happen.

jdelaune’s picture

Hmm lets see if the test bot like this one better...

jhodgdon’s picture

Status: Active » Needs review

You need to set the issue status to "needs review" for the test bot to review it. :)

jdelaune’s picture

Thanks for the tip. So what's the next stage if the test bot likes it?

jhodgdon’s picture

The next step is for people to review the patch.

rfay’s picture

Version: 7.x-dev » 8.x-dev
Status: Active » Needs review

And unfortunately the next step is to get it into 8.x first.

jdelaune’s picture

Well I'll continue to hoop jump...

This one is made against the 8.x branch

klonos’s picture

...bump.

Status: Needs review » Needs work

The last submitted patch, 14: patch_commit_7ab945d0d1f3.patch, failed testing.

Wim Leers’s picture

Version: 8.0.x-dev » 7.x-dev
Issue summary: View changes

No longer relevant for D8.