Snippets

Create an account or login to be able to add, comment and rate snippets.

Navigation

More on multiple ajax div updates

Quentin Garnier, in this snippet: http://www.symfony-project.com/snippets/snippet/57, suggested a way to have a link call multiple remote functions (with "in order" calls being enforced by a new 'wait' parameter). With a slightly modified version of his code, here are a few more functions to be added to you Javascript.php function in the symfony core:

function periodically_call_remotes($options = array())
{
  $frequency = isset($options[0]['frequency']) ? $options[0]['frequency'] : 10; // every ten seconds by default
  $code = 'new PeriodicalExecuter(function() {'.remote_functions($options).'}, '.$frequency.')';
 
  return javascript_tag($code);
}
 
function link_to_remotes($name, $options = array(), $html_options = array())
{
  return link_to_function($name, remote_functions($options), $html_options);
}
 
function remote_functions($options)
{
  // Multi ajax call
  $multi_function = "";
  // First pass (wait)
  for ($i = 0; isset($options[$i]); $i++) {
    if (isset($options[$i]['wait']) && $options[$i]['wait'] != $i && isset($options[$options[$i]['wait']])) {
      if (isset($options[$options[$i]['wait']]['complete'])) {
          $options[$options[$i]['wait']]['complete'] .= '; ' . remote_function($options[$i]);
      } else {
          $options[$options[$i]['wait']]['complete'] = remote_function($options[$i]);
      }
    }
  }
 
  // Second pass
  for ($i = 0; isset($options[$i]); $i++) {
    if (!(isset($options[$i]['wait']) && $options[$i]['wait'] != $i && isset($options[$options[$i]['wait']]))) {
      $multi_function .=  remote_function($options[$i]) . ';';
    }
  }
  return $multi_function;
}

To use it, you could do something like this:

<?php echo link_to_remotes('multi ajax',
    array(
        array(
            'update' => 'first_zone',
            'url' => '/module/action1',
            'loading' => "Element.show('indicator')"
        ),
        array(
            'update' => 'second_zone',
            'url' => '/module/action2',
            'wait' => 0 /* update in a second server call, after 'news_zone' returns */
        ),
        array(
            'update' => 'third_zone',
            'url' => '/module/action3',
            'wait' => 0
        ),
        array(
            'update' => 'fourth_zone',
            'url' => '/module/action4',
            'complete' => "Element.hide('indicator')",
            'wait' => 2 /* update in a third server call, after 'third_zone' returns */
        )
    )
) ?>

or this:

<?php echo periodically_call_remotes('multi ajax',
    array(
        array(
            'frequency' => 60 /* every 60 seconds, frequency only needs to be specified in first call, not subsequent calls */
            'update' => 'first_zone',
            'url' => '/module/action1',
            'loading' => "Element.show('indicator')"
        ),
        array(
            'update' => 'second_zone',
            'url' => '/module/action2',
            'wait' => 0 /* update in a second server call, after 'news_zone' returns */
        ),
        array(
            'update' => 'third_zone',
            'url' => '/module/action3',
            'wait' => 0
        ),
        array(
            'update' => 'fourth_zone',
            'url' => '/module/action4',
            'complete' => "Element.hide('indicator')",
            'wait' => 2 /* update in a third server call, after 'third_zone' returns */
        )
    )
) ?>

Notes

It should be noted that using the 'wait' parameter will cause all top level ajax remote function calls to be executed in one call to the server, and each second level to be executed in a second call, etc. Basically, multiple calls to the server are generated by the user action.

This will cause huge performance issues if you attempt to use these functions in a high-traffic scalable-sensitive system. It is mainly intended for a link which executes two or three functions at most. To do more, you should consider using another approach, like the JSON approach documented in the wiki.

by Stephen Riesenberg on 2006-11-20, tagged ajax  helper  multiple 

Comments on this snippet

gravatar icon
#1 Francois Zaninotto on 2006-11-21 at 09:07

I made the same comment in the other snippet and I repeat it here: I strongly discourage this technique, because it is not good for the user experience, not good for the server, and way too complicated.

If you want to have one remote call update multiple divs, then the result of the remote call must be a list of update_element_function() calls. This means that there will only be one single remote call, and that the update will be fast and effective, in a word: user-friendly.

gravatar icon
#2 Stephen Riesenberg on 2006-11-21 at 08:12

See "Notes" section, which states I am aware of such fallbacks. The use of every approach has reasoning behind it. As educated computer scientists, we can chose when extremes are necessary, and when they aren't.

You need to create an account or log in to post a comment or rate this snippet.