Menu active state lost when using modules?

Hi there,

I have some kind of similar problem like described here. I’m using truly fabulous menu system (mbmenu), which descents from base CMenu. As you can see in the demo of this menu, it highlights active menu item with some kind of glow.

Really nice effect, but it gets lost when I go in my application into any module or submodule. I have “Admin” menu, which currently has three items. First leads to ‘admin’ module of main aplication, last two are connectors to two submodules of ‘admin’ module. No matter which option I select from “Admin” menu, the top item (i.e. “Admin” in main menu structure) does not gets highlighted.

It works perfectly for any other submenus like "Contact" for example - i.e. as long as clicked submenu item is connected to a controller inside main application. But if it leads to any controller of any module, highlighting does not work.

Does anyone has any idea how to fix this problem? Is there a way to tell application that particular module belongs to this or that menu item or any other way to force highlighting of menu items from inside module or submodule?

Thanks in advance.

You would need to check how the highlighting works… ie. how it chooses what and when to highlight…

I don’t know if it uses CMenu or it’s some implementation of mbmenu (not used yet)…

MbMenu extends CMenu. It is using active option of CMenu.items property and CMenu.normalizeItems() method. That is why started this thread as I’m pretty sure that the same problem involves CMenu. If I would think that it is related to MBMenu itself I would contact extension’s author rather.

You can try with CMenu to see if you have the same problem…

have you properly set the active property for modules ?

You can call me dumb, but as I found not active property in CModule and since I thought menu highlighting is done automatically by analysing URL or route I assumed that I don’t have to do anything special about it. As I don’t do anything for regular application elements and menu is correctly highlighted.

I meant active property of the CMenu items… for the modules that you don’t get highlighted :)

Edit:

an example in this post - http://www.yiiframework.com/forum/index.php?/topic/9006-cmenu-and-active-menu-items/page__p__44826__hl__cmenu+active#entry44826

Thanks for sharing this. I’ll paste my results here, in case someone would look after it here.

I used solution proposed by GSTAR:


'active'=>Yii::app()->controller->id == 'go'

When I used the one proposed by 独飞:


array('label'=>'管理首页',  'url'=>array('/admin/default/index'),'active'=>$this->id=='default'?true:false),

 array('label'=>'文章管理',  'url'=>array('/admin/articles/admin'),'active'=>$this->id=='articles'?true:false),

(no matter, if with or without “?true:false” part) I got error saying: “Using $this when not in object context”. Probably, because my menu generation is involved into few functions and isn’t just a plain array.

But this works only, because my only module and all its submodules (whole app’s configuration region) are all using the same controller’s name - Go. If they wouldn’t, this solution would also not work.

I believe (writing from memory, not checked, because I would have to rename at least one of my controllers) that this should solve the problem for main administration module:


('active'=>Yii::app()->getModule('admin') !== null && Yii::app()->controller->getModule() == Yii::app()->getModule('admin'))

But what about submodules of ‘admin’ module? Is there any easy way to determine, if current controller belongs to a module and that module is a submodule of ‘admin’ module?

A quick solution is:


array('label'=>'Admin', 'url'=>array('/Admin'), 'active'=>$this->module->id=='Admin')

Well… seems to be a good idea at first site. I can’t implement it as in my current project I have a rather complex menu structure, separated into a few files and partially generated by some functions. Therefore, if I use your solution I got error saying “Using $this when not in object context”. But, maybe for some simpler application this could work?

$this refers to the current controller.

Another and maybe better way would be:


array('label'=>'Admin', 'url'=>array('/Admin'), 'active'=>Yii::app()->controller->module->id=='Admin')

Well… I thought that message saying that I’m trying to use $this in non-object context means that $this refers neither to a controller nor to any other object…

An attempt of use your second code ends with "Trying to get property of non-object" error message.

Don’t get me wrong. I’m not looking for a working solution to this problem as my current one (crafted upon GSTAR’s example) is satisfying me. Could be better, but at least works. But, if you are keep feeding me with new examples I keep testing them and giving you results! :]

Great! But have you read what I wrote? Have you tested your code?

If Yii::app()->controller->module->id throws "Trying to get property of non-object" then your function will always return false in my situation - i.e. Yii::app()->controller->module is not set (isset() = FALSE)[i].

[/i]

And furthermore. How you would like to use this code for checking in menu item is active? Put whole your code for evaluation with eval() as string contents of ‘active’ parameter of menu configuration array? Declare a function and call it in active? Or use unnamed function feature of PHP 5.3+. If I’m not mistaken, there was some comply in a related topic that active must strictly return TRUE or FALSE and not all parsing works there.

EDIT: jacmoe was so kind to delete his post, I’m answering here, so reading this is now useless! :confused:

Man,

Your solution requires overloading (extending) CMenu with own class, which is not an option for me, for some reasons being off-topic here. I asked specifically, if there is any solution using active, not by extending CMenu. For this question, you haven’t provided any answer. If I could use idea of extending CMenu I would use your previous code and wouldn’t ask any more. Comprende? :]

And here I’ll surprise you (or maybe not?). I gave -1 to your post not because I haven’t read it or not understood it. I voted it down because I general I think that pasting just a piece of code without even a line of explanation is a laziness, threading asker as moron and overall bad behaviour. I would vote down anyone in your place, if I would found a post with just a bunch of line of code.

[s]You posted some piece of code without any explanation. I thought that you are relating directly to my earlier post. How, in the hell, should I figure out that you were referring to your far earlier post and idea of extending CMenu. Maybe this will be a shock for you, but not everyone here is so clever and wise as you! :confused:

You, on the other hand voted my post down for what? As a revenge? Then we have an beautiful example of voting-war. I won’t comment that. I thought you are pretty much more reasonable and professional person.[/s]

[s]No, it will. If you use, as I wrote earlier:

[/s]


if(Yii::app()->controller->module->id == 'admin') return true;

[s]

as you can’t use id in this context. In your solution you are using $item[‘id’], which is only available, when extending CMenu (not, when using active), which - again - is not an option for me. [/s]

[i]/* never mind */

[/i]

Are you kidding me? Never mind and you voted down my another post? Would you be so kind to explain me, for what?

Are you going to vote down each of my new post until my, even now poor reputation hit ground (zero) or get on minus?

I see that, after all, it was a huge mistake to ask you for any help or answer any of your posts! Pity… :confused:

hahaahaaaa… [color="#FFFFFF"]…[/color] :lol:

the vote down wars, this the first time i see in yii forum

@jacmoe if you want to vote down, do it slightly

the wars will be ending something like this

The End of Wars

i dont know who vote that all, to pity…

maybe i am too, don’t remember :huh:

if i not wrong, 5 votes share each days.

peace : don’t vote me down, i got it with hard work you now ;D

I wrote never mind because I didn’t want to be yelled at or ridiculed, and because I don’t have the time to come up with a solution on a silver platter.

I think you are way out of line here.

I thought you’d be intelligent enough to turn what I wrote - yes: only a code snippet because I didn’t have the time to write it out in full, nor adapt it to your use case - yet you go totally bananas with insults. What is eating you?

Do I get a vote down because I slip in an short answer in between other things on my plate?

Ternary operators in PHP to the rescue:


active => (isset(Yii::app()->module) ? blah : false)

That’s why I decided to never mind the post.

Don’t worry, though.

I am not going to waste my precious time on you. :lol:

Well… I would say that kitty10’s profile is a sad story. Not a bad contribution (over 150 posts) pinned down by some idiotic voting war. And since he or she hasn’t been active since a long time we may assume that we lost a good contributor to this community. Sad! :[

It would be best if one user would not be able to vote down more than once another user in the same thread. But forum software probably hasn’t got that feature and even so, if someone wants to pin down someone then will find his way. That’s why I think that voting-war is a behaviour of less professional users, to name it that way.

I will for sure not end like that with jacmoe. I’m not that kind of person, which is voting down each opponents post, just to show out to him (and rest of the world) that a bad day occurred or someone got up on a wrong foot. And I’m for sure not that kind of person, who is deleting own posts voted down, just to fake regain reputation. As I wrote to Antonio Ramirez once, for me the very good community is most important here! Not some numbers on reputation or stuff like this…

Me versus jacmoe - 0:2 (thanks to his tricky deletion of voted down post). That is by far enough for me…

On the contrary! :] +1 just for good humour! :]

But you do have time to vote down my next post, right?

I think that, what you just wrote (cited) summarize everything and it will be best to end this discussion… At least with you… Cheers!

Totally agree:

That is just a bunch of total bullshit.

It does strike me as a shock, however, that you are doing such a rookie mistake in your code and doesn’t even see it.

Suit yourself.

I am not going to spend more time and energy on trying to get time to answer your questions - especially if it means that I get flak.

I don’t need to prove to you that I am reasonable and professional.

The fact that I am a moderator since 2005 with over 18.000 posts at Ogre3d.org speaks for itself now, doesn’t it?

I find your behavior totally unacceptable.