Thanks to this extensions you'll be able to easily have ajax links inside your menus.
Requirements ¶
Tested on Yii version 1.1.7 It should work on every release of Yii starting from 1.1.5
Usage ¶
It's extremely easy:
put the extension inside the extension folder and then just create your menus.
<?php $this->widget('ext.AjaxMenu',array(
'items'=>array(
array('label'=>'Home', 'url'=>array('/site'), 'linkOptions' => array('id' => 'idname'), 'ajax' => false),
array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about'), 'ajax' => array('update' => '#content')),
array('label'=>'Contact', 'url'=>array('/site/contact')),
array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
),
'optionalIndex'=>true,
'ajax'=>array(
'update' => '#page',
),
'randomID'=>true,
)); ?>
with this extensions you have two new options:
optionalIndex is a boolean. If you set it on true and you'll write your controller name as the url value without specifying the index action, the menu item will be highlighted as if you did.
ajax this is just like the ajaxOptions attribute of the ajaxLink element.
Therefore it supports update, replace and success.
If you use that parameter every single link inside your menu will be created with that value, if you won't say otherwise.
randomID this parameter is a boolean and defaults to false. If you set it on true random strings will be generated at the end of the id to avoid multiple ajax request
For that reason your menu items have a new property too, and it's named ajax as well.
If you set it on false that menu item will be a regular link, even if you setted the ajax property of the menu.
If you want to override the behavior setted by the ajax property you can use the item ajax parameter to set the behavior you want.
If you just need a single link to be an ajax link you can forget about the menu ajax property and just set that single item ajax property.
Active Status automatic update ¶
you can use both "update" and "replace" ajax options without having to worry about what's going to happen to the item active status. This widget will automatically generate the needed code to update the active status of your menu items.
If you choose to use a different CSS class for you active items you won't have to worry about anything, because the widget will use the classname you chose.
Clarifications ¶
if you don't know how to use ajaxLink look at the official documentation
Changelog ¶
6-01-2011
version 1.2
added the corrections made by anupam_sam
4-18-2011
added randomID property
now when you click on an ajax link the active status on the menu will be updated.
from now on the random ids will start with letters to avoid weird problems on certain browsers (thanks mjkulet)
Just what I need, but..
I have downloaded and installed it in extensions/ajaxMenu/ folder. Then I used it like this:
<?php $this->widget('ext.ajaxMenu.AjaxMenu',array( 'items'=>array( array('label'=>'Home', 'url'=>array('/site/index')), array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about'),'ajax' => array('update' => '#content')), array('label'=>'Contact', 'url'=>array('/site/contact')), array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest), array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest) ), )); ?>
But it's not working. No errors. Firebug's console doesn't register anything. I don't have sufficient knowledge in jquery so I can't tell yet where the problem is. Could somebody help me? I'm using Yii 1.1.7
@mjkulet
i just tried your code (copy and paste actually) and the ajax call is working just fine...
when i click on the About menu item the page is loaded with ajax.
what kind of problem are you experiencing exactly?
I think I got it..
If I did not declare an id for the ajaxlink, the ajax thingy does not work..
Actually, if the ID is all numbers, ajax refuses to work...
I experimented the same thing with the basic ajax, and it failed to work when I replaced the ID with the randomly generated id with all numbers..
To sum it up, I solved my problem by providing an id for the link.
thanks!
thanks for the bug report... i'll make a new release that will force the randomly generated id to start with letters to avoid that kind of bug.
keep in mind that to create ajax links this extension is actually using Yii CHtml::ajaxLink method, so every possible bug that is there will be replicated into this extension.
Hi there
Hi nickcv,
I didn't notice your reply until I refreshed the page. That's wierd, maybe there are other factors that's affecting my code?
I'm currently using Mozilla Firefox 3.6.16 in Ubuntu 10.04.
And before I even finish sending my reply....
Confirmed, it is working in Google Chrome. The only problem is with the browser. Probably when the Ubuntu's firefox update comes, the problem will go away. But I think it's better to declare the ID even for links, because I wouldn't know when this problem be experienced by the user.
Thanks for the immediate reply btw. :)
yes it's probably browser related
i tested it on firefox 4 for os x... maybe it has some problems if the element id starts with a number... i'll make the new release as soon as possible ^^
thanks again for the feedback!
Thanks!
I was reviewing my comments, and found that I forgot to say thanks for this wonderful extension..silly me :p
Again, thanks a bunch! Too bad I can only give 1 thumbs up. :D
[SOLVED] There are 2 issues with this extension
There are 2 issues with this extension:
[1] Troubles with JQuery ajax Live problem.
So i set to 'live'=>false by default. Still if u want it true you can set it true in the linkOptions.
[2] The code seems to remove any other ajax option if 'replace' & 'update' are set.
For example, consider this the ajax option for this extension:
'ajax' => array( 'update' => '#content', 'beforeSend'=> "js: function(){ scrollTop(); $('#'+mainLoadingIcon).show();}", 'complete'=> "js: function(){ $('#'+mainLoadingIcon).hide();}", ),
Now it will process only the 'update' option & remove the beforeSend & complete.
Here is the updated code that will support all ajax options:
protected function renderMenuItem($item) { // raise the item counter $this->_itemCounter++; if (isset($item['url'])) { // sets the link label $label = $this->linkLabelWrapper === null ? $item['label'] : '<' . $this->linkLabelWrapper . '>' . $item['label'] . '</' . $this->linkLabelWrapper . '>'; // creates the ajax link if (($this->ajax && (!isset($item['ajax']) || (isset($item['ajax']) && $item['ajax'] !== false))) || (isset($item['ajax']) && $item['ajax'])) { // set the new id if randomID is true if ($this->randomID) $item['linkOptions']['id'] = isset($item['linkOptions']['id']) ? $item['linkOptions']['id'] . rand() : 'am' . uniqid(); else $item['linkOptions']['id'] = isset($item['linkOptions']['id']) ? $item['linkOptions']['id'] : 'am-' . $this->_itemCounter; // set the ajax options // START original code changed $ajax = isset($item['ajax']) ? $item['ajax'] : $this->ajax; $ajax_options = $ajax; if (isset($ajax['success']) == FALSE){ if (isset($ajax['update'])) $jquery_method = '$("' . $ajax['update'] . '").html(data);'; elseif (isset($ajax['replace'])) $jquery_method = '$("' . $ajax['replace'] . '").replaceWith(data);'; else $jquery_method = NULL; $ajax_options['success'] = 'js: function(data) { $("#' . $this->id . ' li").removeClass("' . $this->activeCssClass . '"); $("#' . $item['linkOptions']['id'] . '").parent().addClass("' . $this->activeCssClass . '");' . $jquery_method . ' }'; } // creates the ajax link. $item['linkOptions'] should come 2nd in the array_merge. $linkHtmlOptions = (isset($item['linkOptions']) ? array_merge(array('live'=>false), $item['linkOptions']) : array('live'=>false)); return CHtml::ajaxLink($label, $item['url'], $ajax_options, $linkHtmlOptions); // END original code changed } else return CHtml::link($label, $item['url'], isset($item['linkOptions']) ? $item['linkOptions'] : array()); } else return CHtml::tag('span', isset($item['linkOptions']) ? $item['linkOptions'] : array(), $item['label']); }
corrections made!
thanks a lot anupam_sam, i made your corrections to the extension.
AjaxMenu --> YiiSmartMenu?
Hey Nick, I saw that you wrote this, and I think UserGroups looks fabulous, so I thought I would check this out too. I can see myself using it, but I have a (compound) question: Are you aware of YiiSmartMenu and how could one use both menu extensions together?
Thanks for the great extensions!
RE: AjaxMenu --> YiiSmartMenu?
thanks fpolli, unfortunately since i moved to a new company i've been in development hell and i couldn't really keep up with things, so i cannot unfortunately help you...
the bright side is that i managed to finally convince my project manager to use Yii for our next project!
Evl more elegant
Maybe a more elegant solution could be to take the original CMenu as is and catch the links with JQuery and replace them with the AJAX call. In this way the menu is also full functioning when javascript is turned off:
$(document).ready(function(){ $('#mainmenu a').each(function(){ $(this).click(function(ev){ ev.preventDefault(); $.get(this.href,{ajax:true,},function(html){ $('#divToUpdate').html(html); }) .error(function() { alert("An error occurred. Please reload the site."); }); }); }); });
Problems since Update to 1.1.11
After i updated to Yii 1.1.11 ajaxmenu is not working anymore in my project. i get this javascript error:
SyntaxError: missing } after property list
...k', function(){jQuery.ajax({'success':js: function(data) { $("#yw0 li").removeCl...
Is anybody having the same problems?
Thanks!
re: Problems since update to 1.1.11
Yes, @Kabinenkoffer, I'm having this problem, too. Wherever there is JQuery / Ajax stuff -- including the standard Delete buttons in CRUD, this error is being generated.
re: Problems since update to 1.1.11
Update to 1.1.12, for me this worked again. There is a Bug in 1.1.11
Bug #1109: Fixed "js:" encoding BC-break in CHtml::ajax() and related methods introduced in 1.1.11 (samdark)
re: Problems since update to 1.1.11
Yep. That fixed it for me, too.
Thanks!
AjaxBeforeUpdate
Is there any parameter called "AjaxBeforeUpdate"? How can i do a preload image before update?
Thanks! good extension by the way!
beforeSend
Ok, i've tried this:
'beforeSend'=> 'js:function(){ $("#right").empty(); $("#right").html("<img src="/images/precarga.gif"/>");};',
But it doesn't work. what am i doing wrong?
Error unziping tar: "This does not look like a tar archive tar"
Error:
Solution:
Through this link, vía Abhishek Prakash.
"Now loaded with gunzip:" turn "tgz" extension to "tar".
And voilà!
...we get AjaxMenu.php.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.