![]() |
|
Snippets |
|
I have:
<?php echo link_to_remote("update news", array( 'update' => 'news_zone', 'url' => 'news/index', ) ) ?>
The div with the id 'news_zone' will be updated if i click on the link 'update news'. But how can i update another div ?
You have to add the code in the file symfony/helper/JavascriptHelper.php:
function remote_function($options) { sfContext::getInstance()->getResponse()->addJavascript('/sf/js/prototype/prototype'); // Multi ajax call if (isset($options[0]) && is_array($options[0])) { $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; } $javascript_options = _options_for_ajax($options); ...
Now you can use a new syntax (This patch won't affect the "old" syntax. You can use it):
<?php echo link_to_remote('multi ajax', array( array('update' => 'news_zone', 'url' => '/news/index' ), array('update' => 'second_zone', 'url' => '/module/action' ) ) ); ?>
I provide a special feature: "ajax in order". Requests are asynchronous. Now, you can set an order:
<?php echo link_to_remote('multi ajax', array( array('update' => 'news_zone', 'url' => '/news/index' ), array('update' => 'second_zone', 'url' => '/module/action', 'wait' => 0 /* index table. So update after 'news_zone' */ ) ) ); ?>
Comments on this snippet
Also to be recommended: the JSON approach
Yes but there are problems with JSON approach. Indeed, IE (old versions) has a Header limit and prototype uses the Header. JSON is the convient thing to do. But when i click many times, sometimes JSON doesn't work. (problem)
I don't really like this approach, unless i misunderstood which is very possible, it breaks down backward compatibility. I had to use multible ajax calls for one link some days ago and here is the solution i found (to add in JavascriptHelper.php)
3: is your solution better now or what? =) I need something that remotely updates more than one element from different urls :x
I think that it's a bad idea to do several remote colls because you want to update several zones. Performancewise, it's a nightmare, and the responsiveness of your application will be very poor.
The right solution is to have one remote function that returns a javascript that updates several zones.
But then I have to 'script' => true, right? And the returned Javascript from the action can be normal Javascript Helper thingies?
yes, you need to enable script execution in the remote response. And as long as you declare the use of the Javascript helper in your templates, you can use them even in the AJAX template.
So, but then I have to use some kind of a wrapper action/template where I declare which layers I want to update. This action/template will do nothing else than print some Javascript remote functions, am I right?
I try to explain what situation I'm in and what I want to do with AJAX:
I have five layers - #menu - #submenu - #primary - #filters - #sidebar.
The #menu layer updates the #submenu layer on click - the #primary, #filters and #sidebar layer will stay empty. When I click on a link in the #submenu (they always link toindex/list action of a module) I want to update the #primary, #filters and #sidebar layer (some kind of "initial module load").
So, some actions require to disable the #filters and #sidebar, for example the "create" button. On click the #filters and #sidebar layers should be cleared, and the #primary layer will be filled with the form. When I click "save" in the form, the index/list action will be called and then #primary, #filters and #sidebar will be filled again with the initial thingies.
So - my question is: do I have to add remote functions in the index/list template to fill #filters and #sidebar and do I have to add remote functions to clear #filters and #sidebar in the create/edit template? But then, every time I do a paging in the list, the #filters and the #sidebar layers will be re-filled again - that sound's a bit stupid to me (overhead - but I maybe can detect if I did a pagination and then leave both layers as they're).
Also, how do I have to write those remote functions? How can I enable them to be executed when the action is finished (with printing the actions template)?
Pierre: no, the remote action should return a set of update_element_function(), not a set of remote calls. Try to design your AJAX so that every interaction by the user generates a single request.
I suggest we continue this discussion in the forum, if you don't mind.
Francios, thank you very much for your help and hints. Everything works now perfectly and in some kind much better as I expected to. Thanks!
To make things clearer, I added a new snippet to explain my approach.