Yii 1.1: ajaxmenu

extend CMenu allowing you to easily use ajax link inside it
16 followers

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)

Total 18 comments

#10751 report it
Pluk at 2012/11/21 08:09am
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?

#10750 report it
Pluk at 2012/11/21 07:30am
AjaxBeforeUpdate

Is there any parameter called "AjaxBeforeUpdate"? How can i do a preload image before update? Thanks! good extension by the way!

#9580 report it
Ocean Wind at 2012/08/24 01:15pm
re: Problems since update to 1.1.11

Yep. That fixed it for me, too.

Thanks!

#9574 report it
Kabinenkoffer at 2012/08/24 02:49am
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)

#9571 report it
Ocean Wind at 2012/08/23 07:08pm
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.

#9496 report it
Kabinenkoffer at 2012/08/17 11:59am
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!

#9342 report it
Lemar at 2012/08/05 09:02am
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."); });
                                });
                });
     });
#8086 report it
nickcv at 2012/05/09 09:01am
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!

#7981 report it
fpolli at 2012/04/30 10:29pm
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!

#4048 report it
nickcv at 2011/06/01 04:23am
corrections made!

thanks a lot anupam_sam, i made your corrections to the extension.

#3781 report it
Anupam at 2011/05/07 09:00pm
[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']);
}
#3575 report it
mjkulet at 2011/04/19 11:06pm
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

#3536 report it
nickcv at 2011/04/18 07:49am
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!

#3535 report it
mjkulet at 2011/04/18 07:36am
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. :)

#3534 report it
nickcv at 2011/04/18 07:35am
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.

#3533 report it
mjkulet at 2011/04/18 07:29am
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.

#3532 report it
nickcv at 2011/04/18 07:22am
@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?

#3531 report it
mjkulet at 2011/04/18 07:03am
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

Leave a comment

Please to leave your comment.

Create extension