Show/hide Cmenu Items Dynamically With Jquery

Hi,

Here is a guide on how to dynamically show and hide menu items (operations menu in left/right panels). There may be other ways to do this but i didnt manage to find it. Yii is so vast and powerful its likely this can be done numerous ways.

I have a page where I need to be able to switch the mode of the page without reloading. I have a YiiBooster button group widget that allows me to do this. When I click a button it fires an ajax request to make the necessary changes to the data on the page. The problem is, I have a menu item on the right side (Bulk Edit) that is only applicable to one of these modes, so it needs to be hidden/shown depending on what mode is currently selected.

So here is my menu.

PHP code like this…




$this->menu=array(

        array('label'=>'Current/Next Matches', 'url'=>array('comp/drawstatus','id'=>$model->id),

	array('label'=>'Completed Matches', 'url'=>array('comp/drawplayed','id'=>$model->id),

	array('label'=>'Bulk Edit', 'url'=>array('draw/bulkedit','id'=>$model->id),

        array('label'=>'Publish All', 'url'=>array('draw/publishall', 'id'=>$model->id),

);



Produces HTML code like this…




<div class="portlet-content">

    <ul class="operations" id="yw6">

        <li><a href="/comp/drawstatus/24">Current/Next Matches</a></li>

        <li><a href="/comp/drawplayed/24">Completed Matches</a></li>

        <li><a href="/draw/bulkedit/24">Bulk Edit</a></li>

        <li><a href="/draw/publishall/24">Publish All</a></li>

    </ul>

</div>



There doesn’t appear to be a way to assign an id or a class to a menu item via PHP, so firstly I need to identify the menu item that I need to change, then as part of the event that fires the ajax request to change the mode of the page, I need to show hide the menu item accordingly.

So, first things first. I need to run some code when the page loads that locates the required menu item then give the list item a unique ID. I dont want to be doing this every time the mode changes, it only needs to be done once. Once it has an ID, I can reference it directly.

So, find this line…




        <li><a href="/draw/bulkedit/24">Bulk Edit</a></li>



And make it look like this…




        <li id="bulkedititem"><a href="/draw/bulkedit/24">Bulk Edit</a></li>



I run the following JQuery code when the document is ready




//loop through all the "a" elements within the div element

$(".portlet-content").find("a").each(function() {

    var hr = $(this).attr("href");

    var bedit = hr.indexOf("bulkedit");

    //when we find the menu item we want

    if(bedit > 0) {

        //get the parent (li) element of the link as this is what we need to show or hide

        var par = $(this).parent();

        //assign a unique id to the li element

        par.attr("id","bulkedititem");

    }

});



Now all I need to do when I click a button in the group is run either of the following 2 lines to show/hide.




$("#bulkedititem").hide();

$("#bulkedititem").show();



As the request is showing/hiding the li element, the menu options adjust accordingly (move up to fill the space when hidden, move down to make room for the item when shown).

here is the full code for the button




    $this->widget('booster.widgets.TbButtonGroup',

        array(

            'toggle' => 'radio',

            'buttons' => array(

                array(

                    'label' => 'IN-PLAY', 

                    'active'=>$model->capturemode == 1,

                    'htmlOptions'=>array('onChange'=>'$("#bulkedititem").hide();$.ajax({ type: "POST", url: "'.Yii::app()->createUrl('comp/capturemode', array('id'=>$model->id, 'val'=>1)).'" })'),

                ),

                array(

                    'label' => 'COMPLETE', 

                    'active'=>$model->capturemode == 0,

                    'htmlOptions'=>array('onChange'=>'$("#bulkedititem").show();$.ajax({ type: "POST", url: "'.Yii::app()->createUrl('comp/capturemode', array('id'=>$model->id, 'val'=>0)).'" })'),

                )),

            'htmlOptions' => array('name'=>'tgl-capture-mode')

        )

    );




Cheers

Greg J

Hi

You can set the ‘htmlOptions’ for a menu item by setting ‘itemOptions’.


$this->menu=array(

        array('label'=>'Current/Next Matches', 'url'=>array('comp/drawstatus','id'=>$model->id),

        array('label'=>'Completed Matches', 'url'=>array('comp/drawplayed','id'=>$model->id),

        array('label'=>'Bulk Edit', 'url'=>array('draw/bulkedit','id'=>$model->id),'itemOptions'=>array('id'=>'bulkedititem','class'=>'bulkedititem-class')),

        array('label'=>'Publish All', 'url'=>array('draw/publishall', 'id'=>$model->id),

);

ah excellent, thanks

i looked in the public properties for cmenu and didnt see that in the list. Now that I know what to look for I found the reference for it under items.

I knew there would be a way.

Greg J